PB5.61; Find/Replace dialog;

Got an idea for enhancing PureBasic? New command(s) you'd like to see?
HanPBF
Enthusiast
Enthusiast
Posts: 563
Joined: Fri Feb 19, 2010 3:42 am

PB5.61; Find/Replace dialog;

Post by HanPBF »

Wish: keep Checkbox value of "Search inside Selection only" to last value.

The Checkbox "Search inside Selection only" in the Find/Replace dialog is reset when selection in code resets.

That seems at first time correct; but when You want to replace the same entries in more than one selection and in between change to no selection then the checkbox is cleared.

The problem is that it is easy to forget from one selection to the other to enable that checkbox.
Then, when all is replaced in code You can only close the file without storing hopefully having saved after the last replace...
Ctrl-z does not work for whole replacement but only for each one replaced string.

So, this behaviour is correct: checkbox "Seach inside Selection only" switches to disabled when no selection in code.

This would be good: when You reselect some code, the checkbox goes back to old state.

Alternatively the checkbox can switch to "on" when code has a selection.
User avatar
TI-994A
Addict
Addict
Posts: 2512
Joined: Sat Feb 19, 2011 3:47 am
Location: Singapore
Contact:

Re: PB5.61; Find/Replace dialog;

Post by TI-994A »

HanPBF wrote:...Then, when all is replaced in code You can only close the file without storing hopefully having saved after the last replace...
If we're lucky enough to have noticed the erroneous changes before our ingrained Ctrl-S move. :lol:

Been there many times, especially on late nights when faculties are shot to hell. Some of these replacements could run in the thousands, and not so easy to undo or reverse.

Might be a good feature, although not a godsend solution for the absent-minded.
Texas Instruments TI-99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too! Please visit my YouTube Channel :D
User avatar
Michael Vogel
Addict
Addict
Posts: 2666
Joined: Thu Feb 09, 2006 11:27 pm
Contact:

Re: PB5.61; Find/Replace dialog;

Post by Michael Vogel »

I know, this is not the optimal workaround - but maybe it will help you a little bit (if you are using windows)...
...when started, you can use ctrl+shift+L to toggle the checkmark for the 'search in selection' option.

The #ModeIntelligent activates the checkmark automatically, you can do a more comfortable version saving the last state and set it according to your wishes - BTW you could add some tooltips and stop the program automatically when purebasic will be closed.

Code: Select all

; Shortcuts for the Find/Replace dialog 
; (c) Michael Vogel

; Define

	#ID="·PB·"
	#FindDialog=1

	Global ActionMode
	Global ActionName.s
	Global Active

	Enumeration
		#ModeCheckbox
		#ModeClick
		#ModeIntelligent
	EndEnumeration

	#ColActive=		$0D68E0; $12CB6B;
	#ColInactive=	$707070
	#ColSum=		#ColActive+#ColInactive


	CompilerIf #PB_Compiler_Unicode
		#Icon=Chr($2716);	fett
	CompilerElse
		#Icon="×"
	CompilerEndIf
	
	CompilerIf #FindDialog
		#WinTitle="Find/Repla"
		#WinPosX=-70
		#WinPosY=-4
	CompilerElse
		#WinTitle="PureBasic "
		#WinPosX=-140
		#WinPosY=1
	CompilerEndIf

; EndDefine

Procedure Action(hwnd,param)

	Protected s.s
	Protected c.s

	s=Space(128)
	GetWindowText_(hwnd,s,128)

	If s=ActionName; bei 'EnumChildWindows_(w,@Action(),@t)' funktioniert auch 'If s=PeekS(param)'...

		If IsWindowEnabled_(hwnd)
			Select ActionMode
			Case #ModeClick
				SendMessage_(hwnd,#BM_CLICK,1,0)
			Case #ModeCheckbox
				SendMessage_(hwnd,#BM_SETCHECK,Bool(SendMessage_(hwnd,#BM_GETCHECK,#Null,#Null)=0),#Null)
			Case #ModeIntelligent
				Delay(50)
				If IsWindowEnabled_(hwnd)
					SendMessage_(hwnd,#BM_SETCHECK,#True,#Null)
				EndIf
			EndSelect
		EndIf

	EndIf

	ProcedureReturn #True

EndProcedure
Procedure.s ProcessNameFromHwnd(hwnd)

	Protected ProcessID
	Protected hProcess
	Protected hModule
	Protected ProcessName.s=Space(#MAX_PATH)
	Protected EnumProcessModules
	Protected GetModuleFileNameEx

	If  OpenLibrary(0,"psapi.dll")
		EnumProcessModules=GetFunction(0,"EnumProcessModules")
		GetModuleFileNameEx=GetFunction(0,"GetModuleFileNameExA")

		GetWindowThreadProcessId_(hwnd,@ProcessID)
		hProcess=OpenProcess_(#PROCESS_QUERY_INFORMATION|#PROCESS_VM_READ,0,ProcessID)

		CallFunctionFast(EnumProcessModules,hProcess,@hModule,1,0)
		CallFunctionFast(GetModuleFileNameEx,hProcess,hModule,@ProcessName,#MAX_PATH)

		CloseHandle_(hProcess)
		CloseLibrary(0)
	EndIf

	ProcedureReturn ProcessName

EndProcedure
Procedure Click(s.s,t.s,mode)

	Protected w

	If Active=#ColActive
		w=FindWindow_(#Null,s)
		If w
			ActionName=t
			ActionMode=mode
			EnumChildWindows_(w,@Action(),0);  oder ...,@t)
		EndIf
	EndIf

EndProcedure
Procedure InfoWindow()

	Static x,y,z=1
	Protected h
	Protected s.s,t.s
	Protected r.rect

	h=GetForegroundWindow_()
	If h
		CompilerIf #PB_Compiler_Unicode
			t=ProcessNameFromHwnd(h)
			s=PeekS(@t,-1,#PB_Ascii)
		CompilerElse
			s=ProcessNameFromHwnd(h)
		CompilerEndIf

		If FindString(s,"Purebasic.")
			s=Space(255)
			GetWindowText_(h,@s,255)
			If Left(s,10)=#WinTitle
				GetWindowRect_(h,@r)
				If r\right-x Or r\top-y
					x=r\right
					y=r\top
					ResizeWindow(0,x+#WinPosX,y+#WinPosY,#PB_Ignore,#PB_Ignore)
				EndIf
				h=0
			EndIf
		EndIf

	Else
		h=1

	EndIf

	h=Bool(h)
	If z<>h
		z=h
		HideWindow(0,h,#PB_Window_NoActivate)
		If h=#Null
			Click("Find/Replace","Search inside Selection only",#ModeIntelligent)
		EndIf
	EndIf

EndProcedure

Procedure Main()

	Protected WinID
	Protected w

	WinID=FindWindow_(0,#ID)
	If WinID
		PostMessage_(WinID,#PB_Event_CloseWindow,0,0)
		End
	EndIf

	Active=#ColActive

	WinID=OpenWindow(0,0,0,32,20,#ID,#PB_Window_BorderLess|#PB_Window_Invisible)
	TextGadget(0,0,0,32,20,#Icon,#SS_CENTERIMAGE|#PB_Text_Center|#SS_NOTIFY)
	SetGadgetColor(0,#PB_Gadget_BackColor,Active)
	SetGadgetColor(0,#PB_Gadget_FrontColor,$FFFFFF)

	StickyWindow(0,1)
	AddWindowTimer(0,0,10)

	GadgetToolTip(0,"Find & Replace ("+Chr($2318)+Chr($21D1)+"Key)")

	#MonkeyKey=#MOD_CONTROL|#MOD_SHIFT

	RegisterHotKey_(WinID,6001,#MonkeyKey,#VK_W)
	RegisterHotKey_(WinID,6002,#MonkeyKey,#VK_C)
	RegisterHotKey_(WinID,6003,#MonkeyKey,#VK_M)
	RegisterHotKey_(WinID,6004,#MonkeyKey,#VK_S)
	RegisterHotKey_(WinID,6005,#MonkeyKey,#VK_N)
	RegisterHotKey_(WinID,6006,#MonkeyKey,#VK_R)
	RegisterHotKey_(WinID,6007,#MonkeyKey,#VK_A)
	RegisterHotKey_(WinID,6008,#MonkeyKey,#VK_X)
	RegisterHotKey_(WinID,6009,#MonkeyKey,#VK_L)

	Repeat

		Select WaitWindowEvent()
		Case #PB_Event_CloseWindow
			For w=6001 To 6008
				UnregisterHotKey_(WinID,w)
			Next w
			End

		Case #WM_RBUTTONDOWN
			PostEvent(#PB_Event_CloseWindow)

		Case #PB_Event_Gadget
			Active=#ColSum-Active
			SetGadgetColor(0,#PB_Gadget_BackColor,Active)

		Case #WM_HOTKEY
			Select EventwParam()
			Case 6001
				Click("Find/Replace","Whole Words only",#ModeCheckbox)
			Case 6002
				Click("Find/Replace","Case Sensitive",#ModeCheckbox)
			Case 6003
				Click("Find/Replace","Don't search in Comments",#ModeCheckbox)
			Case 6004
				Click("Find/Replace","Don't search in Strings",#ModeCheckbox)
			Case 6005
				Click("Find/Replace","Find Next",1)
			Case 6006
				Click("Find/Replace","Replace",1)
			Case 6007
				Click("Find/Replace","Replace All",1)
			Case 6008
				PostEvent(#PB_Event_Gadget)
			Case 6009
				Click("Find/Replace","Search inside Selection only",#ModeCheckbox)
			EndSelect

		Case #PB_Event_Timer
			InfoWindow()


		EndSelect

	ForEver

EndProcedure

Main()
HanPBF
Enthusiast
Enthusiast
Posts: 563
Joined: Fri Feb 19, 2010 3:42 am

Re: PB5.61; Find/Replace dialog;

Post by HanPBF »

Thanks a lot for the suggestion!


The problem is understood and identified as a problem -> that's good!
User avatar
Michael Vogel
Addict
Addict
Posts: 2666
Joined: Thu Feb 09, 2006 11:27 pm
Contact:

Re: PB5.61; Find/Replace dialog;

Post by Michael Vogel »

Hi,
I made a small tool for windows now for everyone who want to get a better Find & Replace experience :)

It's based on the above source code but additionally will start purebasic and stops running as soon purebasic will be closed. All you have to do is to rename your purebasic.exe file to purebasic.xex and put the tool in the same directory.

Some remarks:
• rename original purebasic.exe to purebasic.xex
• purebasic will be started with the parameter /portable
• when showing the find/replace dialog you will see a changed window title
• pressing ctrl+shift+x will show/hide all shortcut characters in the dialog
• all shortcuts have to be used together with ctrl and shift

Have fun :wink:
Post Reply