Preference Editor
Verfasst: 23.12.2010 22:50
Vor einiger Zeit gab es hier mal einen Beitrag, wo jemand einen Preference Editor angeboten hat. Aber nur zum runterladen, von einer in meinen Augen etwas obskuren Hostingsite. War auch nicht schlecht, aber ohne Quellcode und damit für mich nicht interressant.
Aber als Inspiration genügte es und vor kurzem ans Werk. Da das Ganze einfach und simpel sein soll, habe ich ein Treegadget und ein Editorgadget genommen. Die Sortierroutinen sind teilweise etwas speziell, ich brauche dies so.
Genau wie der ColorRequester. Im Editorgadget auf eine dezimale Zahl Doppelclicken, welche für einen Farbwert steht, und Menupunkt ColorRequester wählen. Die dort gewählte Farbe wird dann übernommen.
In der Regel werden alle Änderungen sofort abgespeichert, außer man startet eine Menu Operation. Wie neue Datei etc.
Man kann auch Strg+S drücken oder eine andere Gruppe wählen.
Beim Ausprobieren, sollte man vielleicht erstmal eine Kopie anlegen mit Datei Speichern unter.
Hier die Include Datei
Testprogrammchen
Aber als Inspiration genügte es und vor kurzem ans Werk. Da das Ganze einfach und simpel sein soll, habe ich ein Treegadget und ein Editorgadget genommen. Die Sortierroutinen sind teilweise etwas speziell, ich brauche dies so.
Genau wie der ColorRequester. Im Editorgadget auf eine dezimale Zahl Doppelclicken, welche für einen Farbwert steht, und Menupunkt ColorRequester wählen. Die dort gewählte Farbe wird dann übernommen.
In der Regel werden alle Änderungen sofort abgespeichert, außer man startet eine Menu Operation. Wie neue Datei etc.
Man kann auch Strg+S drücken oder eine andere Gruppe wählen.
Beim Ausprobieren, sollte man vielleicht erstmal eine Kopie anlegen mit Datei Speichern unter.

Hier die Include Datei
Code: Alles auswählen
; Preference Editor Include Datei
Structure pref_edit
window.i
winbrmin.i
winhhmin.i
statusbar.i
treegadget.i
editgadget.i
txtgadget1.i
txtgadget2.i
prefdat.s
grpname.s
pattern.s
EndStructure
EnableExplicit
Define pref_edit.pref_edit
Enumeration
#prefedit_datnew
#prefedit_datopen
#prefedit_datsave
#prefedit_prgende
#prefedit_prginfo
#prefedit_grpnew
#prefedit_grpsave
#prefedit_grpkill
#prefedit_grpname
#prefedit_grpcopy
#prefedit_grpread
#prefedit_grpsort
#prefedit_keyread
#prefedit_keycolor
#prefedit_keysort1
#prefedit_keysort2
#prefedit_keysort3
EndEnumeration
Procedure.i PrefEdit_Group(flag)
Shared pref_edit.pref_edit
With pref_edit
Protected j, p
Protected editanz, treeindex, treeanzahl
Protected newname.s, oldname.s, keyzeile.s, keyname.s, keyvalue.s
Select flag
Case #prefedit_grpread
ClearGadgetItems(\treegadget)
If OpenPreferences(\prefdat)
If ExaminePreferenceGroups()
While NextPreferenceGroup()
AddGadgetItem(\treegadget, -1, PreferenceGroupName(), 0, 0)
Wend
Else
SetGadgetText(\txtgadget2, "keine groups")
ProcedureReturn
EndIf
ClosePreferences()
SetGadgetText(\txtgadget1, \prefdat)
Else
If \prefdat: SetGadgetText(\txtgadget1, \prefdat + " fehlt"): EndIf
EndIf
StatusBarText(\statusbar, 0, "Wählen Sie eine Gruppe")
PrefEdit_Group(#prefedit_grpsort)
Case #prefedit_grpsort
treeanzahl = CountGadgetItems(\treegadget)
If treeanzahl
Protected Dim treenamen.s(treeanzahl)
For j = 1 To treeanzahl: treenamen(j) = GetGadgetItemText(\treegadget, j - 1): Next
SortArray(treenamen(), #PB_Sort_Ascending, 1, treeanzahl)
For j = 1 To treeanzahl: SetGadgetItemText(\treegadget, j - 1, treenamen(j)): Next
For j = 1 To treeanzahl
If GetGadgetItemText(\treegadget, j - 1) = \grpname
SetGadgetState(\treegadget, j-1)
SetActiveGadget(\treegadget)
Break
EndIf
Next
EndIf
Case #prefedit_grpsave
editanz = CountGadgetItems(\editgadget)
If editanz = 0: ProcedureReturn: EndIf
If OpenPreferences(\prefdat)
RemovePreferenceGroup(\grpname) ;wegen den Kommentaren und alten Keys
PreferenceGroup(\grpname)
For j = 1 To editanz
keyzeile = GetGadgetItemText(\editgadget, j - 1)
If Left(keyzeile, 1) = ";"
PreferenceComment(Trim(Mid(keyzeile, 2)))
Else
p = FindString(keyzeile, "=", 1)
If p
keyname = Trim(Mid(keyzeile, 1, p - 1))
keyvalue = Trim(Mid(keyzeile, p + 1))
WritePreferenceString(keyname, keyvalue)
EndIf
EndIf
Next
ClosePreferences()
EndIf
Case #prefedit_grpname
;da es kein RenamePreferenceGroup gibt, wird erst eine Kopie angelegt und dann die alte Group gelöscht
oldname = \grpname
treeindex = GetGadgetState(\treegadget)
If treeindex < 0: ProcedureReturn: EndIf
newname = InputRequester("Gruppenname", "neuer Name", \grpname)
If Trim(newname): \grpname = newname: Else: ProcedureReturn: EndIf
;Gruppe unter neuem Namen speichern
SetGadgetText(\txtgadget2, \grpname)
SetGadgetItemText(\treegadget, treeindex, \grpname)
PrefEdit_Group(#prefedit_grpsave)
;Gruppe mit altem Namen löschen
If OpenPreferences(\prefdat)
If PreferenceGroup(oldname)
RemovePreferenceGroup(oldname)
ClosePreferences()
EndIf
EndIf
PrefEdit_Group(#prefedit_grpsort)
Case #prefedit_grpkill
treeindex = GetGadgetState(\treegadget)
If treeindex < 0: ProcedureReturn: EndIf
RemoveGadgetItem(\treegadget, treeindex)
SetGadgetText(\txtgadget2, "")
If OpenPreferences(\prefdat)
If PreferenceGroup(\grpname)
RemovePreferenceGroup(\grpname)
EndIf
ClosePreferences()
EndIf
Case #prefedit_grpcopy
If GetGadgetState(\treegadget) < 0: ProcedureReturn: EndIf
newname = Trim(InputRequester("Gruppenname", "Name der Kopie", \grpname))
If \grpname = newname: ProcedureReturn: EndIf
If newname: \grpname = newname: Else: ProcedureReturn: EndIf
AddGadgetItem(\treegadget, -1, \grpname, 0, 0)
PrefEdit_Group(#prefedit_grpsave)
PrefEdit_Group(#prefedit_grpsort)
Case #prefedit_grpnew
newname = Trim(InputRequester("neue Gruppe", "Name", \grpname))
If \grpname = newname: ProcedureReturn: EndIf
If newname: \grpname = newname: Else: ProcedureReturn: EndIf
SetGadgetText(\txtgadget2, \grpname)
AddGadgetItem(\treegadget, 0, \grpname, 0, 0)
PrefEdit_Group(#prefedit_grpsort)
StatusBarText(\statusbar, 0, "Hinweis: Leere Gruppen werden nicht gespeichert !")
EndSelect
EndWith
EndProcedure
Procedure.i PrefEdit_DateiThread(adr)
;dient nur dazu das Wort Öffnen im OpenFileRequester() gegen Löschen auszutauschen
;die Zeichenkette titel ist der Fenstertitel beim Aufruf vom OpenFileRequester()
Protected titel.s = PeekS(adr)
Repeat
Protected hWnd = FindWindow_(#Null, titel)
If hWnd
hWnd = FindWindowEx_(hWnd, #Null, #Null, "Ö&ffnen")
If hWnd
SetWindowText_(hWnd, "Löschen")
EndIf
EndIf
Delay(100)
Until hWnd
EndProcedure
Procedure.i PrefEdit_Datei(flag)
Shared pref_edit.pref_edit
With pref_edit
Protected ok, titel.s, file.s = \prefdat
If Not \pattern
\pattern = "Ini-Text (*.ini)|*.ini;|Format (*.fmt)|*.fmt;|PopUp (*.pop)|*.pop;|Text (*.txt)|*.txt;|Alle Dateien (*.*)|*.*"
EndIf
If flag = 'open'
file = OpenFileRequester("", file, \pattern, 0)
If Not file: ProcedureReturn: EndIf
\prefdat = file
PrefEdit_Group(#prefedit_grpread)
ElseIf flag = 'save'
file = SaveFileRequester("", file, \pattern, 0)
If Not file: ProcedureReturn: EndIf
If Not CopyFile(\prefdat, file)
MessageRequester("Error", "Datei konnte nicht kopiert werden")
ProcedureReturn
EndIf
\prefdat = file
PrefEdit_Group(#prefedit_grpread)
ElseIf flag = 'new'
titel = "Neue Datei"
file = SaveFileRequester(titel, "Neu", \pattern, 0)
If Not file: ProcedureReturn: EndIf
If Not GetExtensionPart(file)
Protected endung$ = StringField(\pattern, SelectedFilePattern() + 1, ";")
endung$ = GetExtensionPart(endung$)
If endung$: file + "." + endung$: EndIf
EndIf
Protected dnr = ReadFile(#PB_Any, file)
If dnr
CloseFile(dnr)
ok = MessageRequester("Hinweis", file + " existiert schon", #MB_OKCANCEL)
If ok = 2: ProcedureReturn: EndIf
EndIf
dnr = OpenFile(#PB_Any, file)
If dnr
WriteStringN(dnr, "[Neu]")
WriteStringN(dnr, "1 = neuer Eintrag")
CloseFile(dnr)
\prefdat = file
PrefEdit_Group(#prefedit_grpread)
SetGadgetState(\treegadget, 0)
SetActiveGadget(\treegadget)
EndIf
EndIf
EndWith
EndProcedure
Procedure.i PrefEdit_Key(flag)
Shared pref_edit.pref_edit
With pref_edit
Protected j, p, max, dnr
Protected editanz = CountGadgetItems(\editgadget)
Protected zeile.s, keywort.s, keywert.s
Protected Dim zeilen.s(editanz)
Protected Dim keyworte.s(editanz), Dim keywerte.s(editanz)
Select flag
Case #prefedit_keyread
\grpname = GetGadgetItemText(\treegadget, GetGadgetState(\treegadget))
SetGadgetText(\txtgadget2, \grpname)
ClearGadgetItems(\editgadget)
;Read Comment, da es kein PB Befehl dafür gibt
dnr = ReadFile(#PB_Any, \prefdat)
If dnr
While Eof(dnr) = 0
zeile = ReadString(dnr)
If zeile = "[" + \grpname + "]"
While Eof(dnr) = 0
zeile = ReadString(dnr)
If Left(zeile, 1) = ";"
AddGadgetItem(\editgadget, -1, zeile)
Else
Break
EndIf
Wend
Break
EndIf
Wend
CloseFile(dnr)
EndIf
;Read Keys
If OpenPreferences(\prefdat)
If PreferenceGroup(\grpname)
If ExaminePreferenceKeys()
While NextPreferenceKey()
AddGadgetItem (\editgadget, -1, PreferenceKeyName() + " = " + PreferenceKeyValue())
Wend
EndIf
EndIf
ClosePreferences()
EndIf
Case #prefedit_keysort1
;die Zeilen im Editgadget werden aufsteigend sortiert
If editanz > 1
For j = 1 To editanz: zeilen(j) = GetGadgetItemText(\editgadget, j - 1): Next
SortArray(zeilen(), #PB_Sort_Ascending, 1, editanz)
For j = 1 To editanz: SetGadgetItemText(\editgadget, j - 1, zeilen(j)): Next
PrefEdit_Group(#prefedit_grpsave)
EndIf
Case #prefedit_keysort2
;am Anfang einer Zeile steht eine unformatierte Zahl
;es werden Leerzeichen davor gesetzt um eine korrekte Sortierung zu erhalten
;anschließend werden die Zeilen aufsteigend sortiert
If editanz > 1
For j = 1 To editanz
zeile = GetGadgetItemText(\editgadget, j - 1)
p = FindString(zeile, "=", 1)
If p > max: max = p: EndIf
Next
For j = 1 To editanz
zeile = GetGadgetItemText(\editgadget, j - 1)
p = FindString(zeile, "=", 1)
If p
keywort = RSet(Trim(Left(zeile, p - 1)), max)
keywert = Trim(Mid(zeile, p + 1))
zeilen(j) = keywort + " = " + keywert
EndIf
Next
SortArray(zeilen(), #PB_Sort_Ascending, 1, editanz)
For j = 1 To editanz: : SetGadgetItemText(\editgadget, j - 1, Trim(zeilen(j))): Next
PrefEdit_Group(#prefedit_grpsave)
EndIf
Case #prefedit_keysort3
;es werden nur die Werte hinter dem "=" aufsteigend sortiert
If editanz > 1
For j = 1 To editanz
zeile = GetGadgetItemText(\editgadget, j - 1)
p = FindString(zeile, "=", 1)
If p
keyworte(j) = Trim(Left(zeile, p - 1))
keywerte(j) = Trim(Mid(zeile, p + 1))
EndIf
Next
SortArray(keywerte(), #PB_Sort_Ascending, 1, editanz)
For j = 1 To editanz: zeile = keyworte(j) + " = " + keywerte(j): SetGadgetItemText(\editgadget, j - 1, zeile): Next
PrefEdit_Group(#prefedit_grpsave)
EndIf
Case #prefedit_keycolor
;die markierte Zahl im EditGadget wird dem ColorRequester übergeben
;und die gewählte Farbe ersetzt dann die markierte Zahl.
Protected range.charrange, laenge, color, buffer.s, old.s
SendMessage_(GadgetID(\editgadget), #EM_EXGETSEL, 0, range)
laenge = range\cpMax - range\cpMin
If laenge
buffer = Space(laenge + 2)
SendMessage_(GadgetID(\editgadget), #EM_GETSELTEXT, 0, buffer)
color = Val(buffer): old = buffer
EndIf
color = ColorRequester(color)
If color > -1 And laenge
buffer = Str(color)
SendMessage_(GadgetID(\editgadget), #EM_REPLACESEL, 0, buffer)
SetClipboardText(old)
EndIf
EndSelect
EndWith
EndProcedure
Procedure.i PrefEdit_Resize()
Shared pref_edit.pref_edit
With pref_edit
Protected winbr = WindowWidth(\window), winhh = WindowHeight(\window)
If winbr < \winbrmin: winbr = \winbrmin: EndIf ;\winbrmin siehe PrefEdit_Window
If winhh < \winhhmin: winhh = \winhhmin: EndIf
Protected rand = 10, abstand = 8, texthh = 20, treebr = 150, menuhh = MenuHeight(), sbhh = StatusBarHeight(\statusbar)
Protected sp1 = rand
Protected sp2 = sp1 + treebr + abstand
Protected sp, ze, br, hh
ResizeWindow(\window, #PB_Ignore, #PB_Ignore, winbr, winhh)
ze = rand
ResizeGadget(\txtgadget1, sp1, ze, winbr - rand - rand, texthh)
ze + texthh + abstand
hh = winhh - abstand - texthh - (2 * rand) - menuhh - sbhh
ResizeGadget(\treegadget, sp1, ze, treebr, hh)
br = winbr - sp2 - rand
ResizeGadget(\txtgadget2, sp2, ze, br, texthh)
ze + texthh + abstand
hh - texthh - abstand
ResizeGadget(\editgadget, sp2, ze, br, hh)
EndWith
EndProcedure
Procedure.i PrefEdit(parent = 0, dat$ = "", patt$ = "")
Shared pref_edit.pref_edit
With pref_edit
;mehrfach aufrufen verhindern
If \window: ProcedureReturn: EndIf ;\window wird bei CloseWindow gelöscht
Protected parentid = 0
If IsWindow(parent): parentid = WindowID(parent): EndIf
Protected flags = #PB_Window_SizeGadget | #PB_Window_ScreenCentered | #PB_Window_SystemMenu
CompilerIf #PB_Compiler_Version >= 440: flags | #PB_Window_Tool: CompilerEndIf
\prefdat = dat$
\pattern = patt$ ;für Dateiauswahl, Format siehe PB Hilfe OpenFileRequester()
\winbrmin = 400
\winhhmin = 300
\window = OpenWindow(#PB_Any, 0, 0, \winbrmin, \winhhmin, "PrefEdit", flags, parentid)
\statusbar = CreateStatusBar(#PB_Any, WindowID(\window)): AddStatusBarField(#PB_Ignore)
\txtgadget1 = TextGadget(#PB_Any, 0, 0, 0, 0, "") ;, #PB_Text_Border)
\treegadget = TreeGadget(#PB_Any, 0, 0, 0, 0)
\txtgadget2 = TextGadget(#PB_Any, 0, 0, 0, 0, "Gruppe ?")
\editgadget = EditorGadget(#PB_Any, 0, 0, 0, 0)
Protected menu = CreateMenu(#PB_Any, WindowID(\window))
MenuTitle("Datei")
MenuItem(#prefedit_datnew, "Datei &neu")
MenuItem(#prefedit_datopen, "Datei ö&ffnen" + #TAB$ + "Strg+O")
MenuItem(#prefedit_datsave, "Datei s&peichern unter")
MenuBar()
MenuItem(#prefedit_prgende, "&Ende")
MenuTitle("Gruppe")
MenuItem(#prefedit_grpnew, "Gruppe &neu")
MenuItem(#prefedit_grpsave, "Gruppe &speichern" + #TAB$ + "Strg+S")
MenuItem(#prefedit_grpkill, "Gruppe &löschen")
MenuItem(#prefedit_grpcopy, "Gruppe &kopieren")
MenuItem(#prefedit_grpname, "&Name ändern")
MenuTitle("Key")
MenuItem(#prefedit_keysort1,"&Sortiere Zeilen")
MenuItem(#prefedit_keysort2,"Sortiere &Zeilen mit Zahlen am Anfang")
MenuBar()
MenuItem(#prefedit_keysort3,"Sortiere nur &KeyWert")
MenuBar()
MenuItem(#prefedit_keycolor,"&ColorRequester")
MenuTitle("Info")
MenuItem(#prefedit_prginfo,"HJBremer 24.12.2010")
DisableMenuItem(menu, #prefedit_prginfo, 1)
AddKeyboardShortcut(\window, #PB_Shortcut_Control | #PB_Shortcut_O, #prefedit_datopen)
AddKeyboardShortcut(\window, #PB_Shortcut_Control | #PB_Shortcut_S, #prefedit_grpsave)
PrefEdit_Group(#prefedit_grpread)
PrefEdit_Resize()
EndWith
EndProcedure
Procedure.i PrefEdit_Events(event)
Shared pref_edit.pref_edit
With pref_edit
Protected window = EventWindow(), eventtype = EventType()
If window <> \window: ProcedureReturn event: EndIf ;richtiges Window ? wenn nicht, dann Return
Select event
Case #PB_Event_Gadget
Select EventGadget()
Case \editgadget ;:Debug eventtype
Select eventtype
Case 256 ;Focus undokumentiert
StatusBarText(\statusbar, 0, "Strg + Z = Undo, Strg + Y = ReUndo")
Case 512 ;LostFocus undokumentiert
StatusBarText(\statusbar, 0, "")
PrefEdit_Group(#prefedit_grpsave)
EndSelect
Case \treegadget ;:Debug eventtype
Select eventtype
Case #PB_EventType_Change ;nur #PB_EventType_LeftClick reicht nicht
PrefEdit_Key(#prefedit_keyread)
EndSelect
EndSelect
Case #PB_Event_Menu
Select EventMenu()
Case #prefedit_datnew: PrefEdit_Datei('new')
Case #prefedit_datopen: PrefEdit_Datei('open')
Case #prefedit_datsave: PrefEdit_Datei('save')
Case #prefedit_prgende: CloseWindow(\window): \window = 0
Case #prefedit_grpnew: PrefEdit_Group(#prefedit_grpnew)
Case #prefedit_grpsave: PrefEdit_Group(#prefedit_grpsave)
Case #prefedit_grpkill: PrefEdit_Group(#prefedit_grpkill)
Case #prefedit_grpcopy: PrefEdit_Group(#prefedit_grpcopy)
Case #prefedit_grpname: PrefEdit_Group(#prefedit_grpname)
Case #prefedit_keycolor: PrefEdit_Key(#prefedit_keycolor)
Case #prefedit_keysort1: PrefEdit_Key(#prefedit_keysort1)
Case #prefedit_keysort2: PrefEdit_Key(#prefedit_keysort2)
Case #prefedit_keysort3: PrefEdit_Key(#prefedit_keysort3)
EndSelect
Case #WM_EXITSIZEMOVE: PrefEdit_Resize()
Case #PB_Event_CloseWindow: CloseWindow(\window): \window = 0
EndSelect
EndWith
ProcedureReturn -1
EndProcedure
Code: Alles auswählen
; -PrefEdit-Test-
XIncludeFile "PrefEdit.pbi"
#win = 1
OpenWindow(#win, 0, 0, 600, 500, "", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
CreateMenu(#PB_Any, WindowID(#win))
MenuTitle("Test")
MenuItem(1, "Prefedit")
MenuItem(2, "irgendwas")
MenuBar()
MenuItem(4, "Ende")
;ein Beispiel für den Aufruf
;PrefEdit(#win, "\Bremer\BeispieleXX\MiniAdr\fbuchpop.pop")
;PrefEdit(#win, "\Bremer\BeispieleXX\MiniAdr\fbuchpop.pop", "Ini-Text (*.ini)|*.ini;|Alle Dateien (*.*)|*.*")
Define event
Repeat
event = WaitWindowEvent()
event = PrefEdit_Events(event)
Select event
Case #PB_Event_Menu
Select EventMenu()
Case 1: PrefEdit(#win)
Case 2: Debug "Mainwindow Menupunkt 2"
Case 4: event = #PB_Event_CloseWindow
EndSelect
EndSelect
Until event = #PB_Event_CloseWindow