Notice: This forum has been recovered from an old backup, so some content, links, and dates may be outdated. The forum is currently read-only while we restore sign-in and registration functionality. Details

If you find this forum valuable and would like to help keep it online, donations to help cover hosting and domain costs are greatly appreciated, but never expected. You can support the forum through Buy Me a Coffee or Ko-fi. Thank you for helping preserve the EventGhost community.

Registry Plugin (war: Dialog Layout)

Allgemeines zum Thema EventGhost
Bartman
Plugin Developer
Posts: 881
Joined: Sun Feb 12, 2006 9:03 am

Post by Bartman »

Das mit der Bezeichnung habe ich an die anderen Actions angelehnt. Die sind ja in der Form "Mache irgendwas".

Das mit dem current Value habe ich auch schon ├╝berlegt, aber mir ist keine Form eingefallen, das brauchbar in die GUI zu integrieren.
User avatar
Bitmonster
Site Admin
Posts: 2239
Joined: Mon Feb 06, 2006 10:28 pm

Post by Bitmonster »

Ich habe das Plugin jetzt noch nicht in allen Details ausprobiert, aber mal so meine ersten Gedanken:

1. Das mit den Labels ist schon richtig so, denke ich. Man sollte nur vielleicht zu lange Labels abk├╝rzen. Also das man aus z.B. aus
HKEY_CURRENT_USER\SOFTWARE\NVIDIA Corporation\Global\nView\WindowManagement\rtvscan\Exceptions\#32770
etwas macht wie
HKCU\...\Exceptions\#32770
damit es ├╝bersichtlich bleibt. Ist nat├╝rlich auch nicht perfekt aber vielleicht doch etwas besser.

2. Dass ein neuer Dialog immer mit HKCU/Software aufgeht, dieses aber nicht im Baum selektiert ist, verwirrt etwas. Dein Code ist ja schon daf├╝r ausgelegt, den Key zu finden und anzuzeigen. Bei neuen Aktionen macht er es aber anscheinend nicht. Du kannst auch noch einen Trick verwenden:
Wenn du das Ergebnis der letzten Selektierung in die Plugin-Instanz schreibst, dann kann man das dazu verwenden beim Erstellen einer neuen Action gleich die letzte Selektierung als Vorgabe zu verwenden.

Man k├Ânnte die letzte Selektierung sogar in die EG-Konfiguration schreiben, dann funktioniert das sogar ├╝ber mehrere Sessions hinweg. Regedit macht das ja auch so.

3. Im Logger etwas aus der Konfiguration anzeigen zu lassen ist eigentlich nicht sch├Ân. Beim FindWindow habe ich das zwar auch gemacht, aber das soll auch noch rausfliegen. Zu oft verdeckt der Konfig-Dialog den Logger und dann kriegt der User das gar nicht mit.

4. Die Drop-Down-Box für den Hauptzweig würde ich vielleicht wieder rauswerfen. Tut sicher weh, wenn man sowas schon eingebaut hat, aber ich denke dass ist praktischer für den User, wenn er den Suchpfad direkt vollständig pasten kann. Oft kommen die Leute ja auf die Idee mal schnell sowas zu verwenden, wenn es irgendwo im Netz steht und da steht dann ja auch immer der volle Pfad in einem Stück.
Man m├╝sste dann nur soviel Intelligenz in den Code legen, dass er z.B. sowohl HKCU und HKEY_CURRENT_USER als das Gleiche erkennt.


Na ja, aber den Plugin Developer Titel kriegste schon mal. :)
Bartman
Plugin Developer
Posts: 881
Joined: Sun Feb 12, 2006 9:03 am

Post by Bartman »

1) Kann ich noch mal ändern. Nachdem Schema ist es ja auch noch recht einfach. Wie geht das denn mit dem Platzhalter in den Labeltexten, wie es sonst benutzt wird?

2) Bei mir ist HKCU\Software dann auch im Baum selektiert?!?!
Ins PlugIn schreiben d├╝rfte ich noch hinkriegen, aber wie das mit der Instanz geht ist auch noch so eine Sache.

Bei der Configsache kann ich auch gleich noch eine Sache ansprechen. Eigentlich mag ich es ja nicht, wenn Programme etwas in ihr eigenes Verzeichnis schreiben. Das geh├Ârt ja eigentlich eher ins Userverzeichnis. Bei eingeschr├ñnkten Benutzern muss man sowas erst m├╝hsam rausfinden und die Dateisystemrechte entsprechend ├ñndern.

3) Ich w├╝rde es ja gerne reichschreiben, aber mir ist auch nach einigem Nachdemken keine sinnvolle Positionierung/Darstellung eingefallen.

4) Kann ich mal schauen So schwer kann das ja auch nicht sein.
Gibt es irgendwo schon ein Beispiel einer Validierung vorm Bestätigen?
User avatar
Bitmonster
Site Admin
Posts: 2239
Joined: Mon Feb 06, 2006 10:28 pm

Post by Bitmonster »

1. Einfach ├╝ber eg.ParseString schicken in der __call__ Methode. Also sowas am Anfang machen:
pathname = eg.ParseString(pathname)

2. Bei mir nicht. Kann es sein, dass die Suche case-sensitive ist und es bei dir tatsächlich "Software" heißt? Bei mir ist es nämlich "SOFTWARE". Schlüsselfpfade sind übrigens allgemein case-insensitive.

Was meinst du mit "aber wie das mit der Instanz geht ist auch noch so eine Sache"?

Das Configfile im Programmverzeichnis ist wirklich eine schlechte L├Âsung. Werde ich mal ├ñndern. Der urspr├╝ngliche Gedanke war, dass der User dann sp├ñtestens beim L├Âschen des Programmordners sicher sein kann, dass nichts mehr von EG ├╝ber ist.

4. Gute Frage. Muss ich mal schauen. Bisher waren es immer Controls die selber validieren und ich dann ggfs. den OK-Button disabled habe.
Bartman
Plugin Developer
Posts: 881
Joined: Sun Feb 12, 2006 9:03 am

Post by Bartman »

1) Das versteh ich jetzt nicht ganz. Ich meinte die Syntax wie es z.B. beim TriggerEvent.getLabel() vorkommt. Da heißt es

Code: Select all

return self.text.labelWithTime % (eventString, waitTime)
und in labelWithTime steht dann

Code: Select all

Trigger event "%s" after %.2f seconds
Diese Form hab ich zwar schon an einigen anderen Stellen gesehen, aber ich weiß echt nicht wie die funktioniert.

2) Jup bei mir heißt das "Software". Werde ich noch anpassen.

3) mit dem Kauderwelsch wollte ich nachfragen, wie man Werte so setzt, dass EG sie im Configfile abspeichert und beim Starten wiederherstellt.
User avatar
Bitmonster
Site Admin
Posts: 2239
Joined: Mon Feb 06, 2006 10:28 pm

Post by Bitmonster »

1. Achso, ich dachte du meinst die Variablen-Ersetzung mit dem Geschweifte-Klammern-Syntax, den EG an vielen Stellen hat.

Was du meinst steht hier: http://docs.python.org/lib/typesseq-strings.html

3. Schreibe ich bei Gelegenheit mal ein HowTo zu. Ich hatte die Funktion jetzt gerade aus den Plugins und Actions rausgenommen, weil sie praktisch nur von zwei Aktionen benutzt wird und ich lieber die Klassen ├╝bersichtlich halten wollte.
User avatar
Bitmonster
Site Admin
Posts: 2239
Joined: Mon Feb 06, 2006 10:28 pm

Post by Bitmonster »

3.)
Machen wir doch mal die Kurzform:

Zuerst brauchst du eine Klasse mit deinen Default-Werten, also z.B.

Code: Select all

class Defaults:
    lastKey = "HKCU\Software"
Dann rufst du in deiner Plugin __init__ die Funktion eg.GetConfig() auf:

Code: Select all

self.config = eg.GetConfig("plugins.Registry", Defaults)
In self.config.lastKey steht dann der Wert. Beim ersten Mal "HKCU\Software".

Ver├ñnderst du nun self.config, dann wird das automatisch beim Beenden von EG gesichert und beim n├ñchsten eg.GetConfig() wieder hervorgeholt. "plugins.Registry" ergibt sich aus dem Klassennamen deines Plugins. Das ist nat├╝rlich nicht absolut sicher, weil ein anderes Plugin auf die Idee kommen k├Ânnte genauso zu hei├ƒen. Zur Zeit geht das aber, weil wir ja noch die ├£bersicht haben.
Last edited by Bitmonster on Thu Aug 24, 2006 1:20 pm, edited 1 time in total.
Bartman
Plugin Developer
Posts: 881
Joined: Sun Feb 12, 2006 9:03 am

Post by Bartman »

Hier mal ein upgedater Code. Bislang noch ohne das Abspeichern der Einstellungen im globalen. Grade schon verr├╝ckt worden, weil ich kein event.skip() eingebaut hatte und deshalb immer nur ein Handler aufgerufen wurde. Und danach gabs Probleme, weil die Handler in der "falschen" Reihenfolge aufgerufen wurde und ich immer den alten Wert ausgelesen hab:oops:
Daf├╝r gibt es jetzt auch die K├╝rzung der Labels und wenn man f├╝r den Subkey einen Wert einf├╝gt, der den passenden Anfang hat wird die Auswahlbox gesetzt und der Text entsprechend verk├╝rzt. Das d├╝rfte f├╝r unbedarftes C&P reichen

Code: Select all

[Source Code entfernt, da neuere Version weiter unten verf├╝gbar]
User avatar
Bitmonster
Site Admin
Posts: 2239
Joined: Mon Feb 06, 2006 10:28 pm

Post by Bitmonster »

Was mir noch so aufgefallen ist:

Code: Select all

class RegistryChooser(wx.Window):
    text = Text
Das geht nicht. Die Text-Klasse wird nur f├╝r die Plugin-Klasse ├╝bersetzt und dann u.U. auf die Action-Klassen verteilt. Wenn du f├╝r das Fenster darauf zugreifen willst, dann musst du die self.text Referenz des Plugins ├╝bergeben. Z.B. als Parameter der RegistryChooser.__init__.

Code: Select all

    changeActions = ("create or change", "change if exists only", "delete")
    changeActionLabel = ('Change "%s" to %s', 'Change "%s" to %s if exists only', 'Delete "%s"')
   
    queryActions = ("check if exists", "return as result", "compare to")
    queryActionLabel = ('Check if "%s" exists', 'Return "%s" as result', 'Compare "%s" with %s')
Die hast du unter dem Plugin angeordnet. Wäre aber doch ratsamer es unter die Actions anzuordnen, damit die in GetLabel() einfach nur auf self.text zugreifen müssen, statt auf self.plugin.text.

regKeys und regTypes brauchen schätzungsweise nicht in der Text-Klasse stehen, weil die wohl nicht übersetzt werden müssen. Zudem hat ein Übersetzer keinen Zugriff auf _winreg in seinem Language-File und somit würde das so sowieso nicht klappen.

Code: Select all

from wxPython.wx import * 
Den import mag ich gar nicht. Versuch mal den wegzulassen und alle wx-Sachen immer ├╝ber den wx.XXX Weg anzusprechen, statt ├╝ber wxXXX.
Bartman
Plugin Developer
Posts: 881
Joined: Sun Feb 12, 2006 9:03 am

Post by Bartman »

neuer Versuch.
Ich suche für etwas anderes noch eine Eingabekomponente für Freitext, wo man aber per Dropdownliste auch Vorgaben auswählen kann. Gibt es doch bestimmt schon fertig, ich weiß nur nicht wie das heißt.

Code: Select all

import eg
import wx
import _winreg
import binascii

from eg.cFunctions import RegEnumKeysAndValues


class Text:
    noKeyError = "No key given"
    noSubkeyError = "No subkey given"
    noTypeError = "No type given"
    noNewValueError = "No new value given"
    noValueNameError = "No value name given"
    keyOpenError = "Error opening registry key"
    valueChangeError = "Error while modifying value"
   
    defaultText = "(Default)"
    chooseText = "Choose Registry Key:"
    keyText = "Key:"
    valueText = "Value:"
    valueName = "Value name:"
    actionText = "Action:"
    newValue = "New value:"
    oldValue = "Current value:"
    oldType = "Current Type:"
    typeText = "Type:"
    
    keyText2 = "Key"
    noValueText = "value not found"
   

    class RegistryChange:
        name = "Change Registry Value"
        description = "Changes a value in the windows registry"
        actions = ("create or change", "change if exists only", "delete")
        labels = (
            'Change "%s" to %s',
            'Change "%s" to %s if exists only',
            'Delete "%s"'
        )


    class RegistryQuery:
        name = "Query Registry"
        description = "Queries the windows registry and return or compares the value"
        actions = ("check if exists", "return as result", "compare to")
        labels = (
            'Check if "%s" exists',
            'Return "%s" as result',
            'Compare "%s" with %s'
        )


regKeys = (
    (_winreg.HKEY_CLASSES_ROOT, "HKEY_CLASSES_ROOT", "HKCR"),
    (_winreg.HKEY_CURRENT_USER, "HKEY_CURRENT_USER", "HKCU"),
    (_winreg.HKEY_LOCAL_MACHINE, "HKEY_LOCAL_MACHINE", "HKLM"),
    (_winreg.HKEY_USERS, "HKEY_USERS", "HKU"),
    (_winreg.HKEY_CURRENT_CONFIG, "HKEY_CURRENT_CONFIG", "HKCC")
)

regTypes = (
    (None, "Auto"),
    (_winreg.REG_BINARY, "REG_BINARY"),
    (_winreg.REG_DWORD, "REG_DWORD"),
    (_winreg.REG_EXPAND_SZ, "REG_EXPAND_SZ"),
    (_winreg.REG_MULTI_SZ, "REG_MULTI_SZ"),
    (_winreg.REG_NONE, "REG_NONE"),
    (_winreg.REG_SZ, "REG_SZ")
)


class RegistryLazyTree(wx.TreeCtrl):
   
    def __init__(
        self,
        parent,
        id=-1,
        key = _winreg.HKEY_CURRENT_USER,
        subkey = "Software",
        valueName = None,
        pos = wx.DefaultPosition,
        size = wx.DefaultSize,
        style = wx.TR_HAS_BUTTONS,
        validator = wx.DefaultValidator,
        name="RegistryLazyTree",
        text = None
    ):
        self.text = text
        wx.TreeCtrl.__init__(self, parent, id, pos, size, style, validator, name)

        self.SetImageList(eg.imageList)
        self.SetMinSize((-1,200))
        self.treeRoot = self.AddRoot(
            "Registry",
            image = eg.SetupIcons("root"),
            data = wx.TreeItemData((True, None, None, None))
        )
        self.folderIcon = eg.SetupIcons("folder")
        self.valueIcon = eg.SetupIcons("action")
        #Adding keys
        for item in regKeys:
            #a tupel of 4 values is assigned to every item
            #1) stores if the key has yet to be queried for subkey, when selected
            #2) _winreg.hkey constant
            #3) name of the key
            #4) value name, None if just a key, empty string for default value
            tmp = self.AppendItem(
                self.treeRoot,
                item[1],
                image = self.folderIcon,
                data =wx.TreeItemData((False, item[0], "", None))
            )
            self.SetItemHasChildren(tmp, True)
            if item[0] == key:
                self.SelectItem(tmp)

        #select old value in tree
        self.onTreeChange(wx.CommandEvent(), key, subkey, valueName)
        self.EnsureVisible(self.GetSelection())
       
        self.Bind(wx.EVT_TREE_SEL_CHANGED, self.onTreeChange)
        self.Bind(wx.EVT_TREE_ITEM_EXPANDING, self.OnExpandNode)

    def GetValue(self):
        data = self.GetItemData(self.GetSelection()).GetData()
        return data[1], data[2], data[3]

    def OnExpandNode(self, event):
        self.onTreeChange(event, node = event.GetItem())

    def onTreeChange(
        self,
        event,
        key2Select = None,
        subkey2Select = None,
        valueName2Select = None,
        node = None
    ):
        #print "onTreeChange", key2Select, subkey2Select, valueName2Select
        if not node:
           node = self.GetSelection()
        
        keyHasBeenQueried, fatherKey,\
           fatherSubkey, fatherValueName = self.GetItemData(node).GetData()
        subkey2Find = None
        newItemSelected = False
        
        if not keyHasBeenQueried:#check for subkeys
            self.SetItemData(node,
                wx.TreeItemData((True, fatherKey, fatherSubkey, fatherValueName)))
           
            #buildung tree
            try:
                regHandle = _winreg.OpenKey(fatherKey, fatherSubkey)
            except EnvironmentError, e:
                eg.PrintError(self.text.keyOpenError + ": " + str(e))
                return 0
            
            #query subkeys
            if len(fatherSubkey) == 0:
                parentSubkey = ""
            else:
                parentSubkey = fatherSubkey + "\\"
            
            #preparing strings to find the subkey2Select key
            if valueName2Select:
                valueName2Select = valueName2Select.lower()
            if subkey2Select:
                subkey2Select = subkey2Select.lower()
            if key2Select and subkey2Select and key2Select == fatherKey:
                length = len(fatherSubkey)
                if subkey2Select[0:length] == fatherSubkey.lower():
                    subkey2Find = subkey2Select[length:]
                    if subkey2Find.startswith("\\"):
                        subkey2Find = subkey2Find[1:]
                    subkeys = subkey2Find.split("\\", 1)
                    subkey2Find = subkeys[0]

            #building Tree
            keyNames, valueList = RegEnumKeysAndValues(regHandle)

            #sorting
            keyNames.sort(lambda a,b: cmp(a[0].lower(), b[0].lower()) )
            valueList.sort(lambda a,b: cmp(a[0].lower(), b[0].lower()) )
           
            #subkeys
            for keyName, numSubKeys, numSubValues in keyNames:
                hasChildren = bool(numSubKeys + numSubValues > 0)
                data = (
                    not hasChildren,
                    fatherKey,
                    parentSubkey + keyName,
                    None
                )
                tmp = self.AppendItem(
                    node,
                    keyName,
                    image=self.folderIcon,
                    data=wx.TreeItemData(data)
                )
                if subkey2Find == keyName.lower():
                    newItemSelected = True
                    self.SelectItem(tmp)                 
                self.SetItemHasChildren(tmp, hasChildren)

            #values
            for valueName, valueType in valueList:
               
                if len(valueName) == 0:
                    enumValueName = self.text.defaultText
                else:
                    enumValueName = valueName
                data = (True, fatherKey, fatherSubkey, valueName)
                tmp = self.AppendItem(
                    node,
                    enumValueName,
                    image = self.valueIcon,
                    data = wx.TreeItemData(data)
                )
                if (
                    valueName2Select != None
                    and valueName.lower() == valueName2Select
                    and subkey2Select == fatherSubkey.lower()
                ):
                    newItemSelected = True
                    self.SelectItem(tmp)

        if newItemSelected:
            self.onTreeChange(
                wx.CommandEvent(),
                key2Select,
                subkey2Select,
                valueName2Select
            )
        event.Skip()



class RegistryChooser(wx.Window):
   
    def __init__(
        self,
        parent,
        id = -1,
        text = None,
        key = _winreg.HKEY_CURRENT_USER,
        subkey = "Software",
        valueName = None,
        pos = wx.DefaultPosition,
        size = wx.DefaultSize,
        style = wx.EXPAND
    ):
        self.text = text
        wx.Window.__init__(self, parent, id, pos, size, style)
        sizer = wx.GridBagSizer(5, 5)
        sizer.AddGrowableRow(1)
        sizer.AddGrowableCol(3,2)
        sizer.AddGrowableCol(5,1)
       
       
        sizer.SetEmptyCellSize((0,0))
        sizer.Add(
            wx.StaticText(self, -1, self.text.chooseText),
            (0, 0),
            (1, 6),
            flag = wx.ALIGN_CENTER_VERTICAL
        )
       
        sizer.Add(
            wx.StaticText(self, -1, self.text.keyText),
            (2, 0),
            flag = wx.ALIGN_CENTER_VERTICAL
        )

        #key
        keyChoice = wx.Choice(self, -1)
        for i in  range(0,len(regKeys)):
            keyChoice.Append(regKeys[i][1])
            if regKeys[i][0] == key:
                keyChoice.SetSelection(i)
        sizer.Add(keyChoice, (2, 1))

        sizer.Add(
            wx.StaticText(self, -1, "\\"),
            (2, 2),
            flag = wx.ALIGN_CENTER_VERTICAL
        )

        #subkey
        subkeyCtrl = wx.TextCtrl(self, -1, subkey, size=(200,-1))
        sizer.Add(subkeyCtrl, (2, 3), flag = wx.EXPAND)

        sizer.Add(
            wx.StaticText(self, -1, self.text.valueName),
            (2, 4),
            flag = wx.ALIGN_CENTER_VERTICAL
        )
       
        #old Value
        sizer.Add(
            wx.StaticText(self, -1, self.text.oldValue),
            (3, 0),
            flag = wx.ALIGN_CENTER_VERTICAL
        )
        self.oldValueCtrl = wx.TextCtrl(self, -1)
        self.oldValueCtrl.Enable(False)
        sizer.Add(
            self.oldValueCtrl,
            (3, 1),
            (1, 3),
            flag = wx.EXPAND
        )
        sizer.Add(
            wx.StaticText(self, -1, self.text.oldType),
            (3, 4),
            flag = wx.ALIGN_CENTER_VERTICAL
        )
        self.oldTypeCtrl = wx.TextCtrl(self, -1)
        self.oldTypeCtrl.Enable(False)
        sizer.Add(
            self.oldTypeCtrl,
            (3, 5),
            flag = wx.EXPAND
        )
        self.fillOldValue(key, subkey, valueName)

        #Create TreeCtrl
        tree = RegistryLazyTree(self, -1, key, subkey, valueName, text=text)
        sizer.Add(tree, (1, 0), (1, 6), flag = wx.EXPAND)

        if valueName == None:
            valueName = ""
        elif len(valueName) == 0:
            valueName = self.text.defaultText
        valueNameCtrl = wx.TextCtrl(self, -1, valueName, size=(100,-1))
        sizer.Add(valueNameCtrl, (2, 5), flag = wx.EXPAND)

        self.SetSizer(sizer)
        self.SetAutoLayout(True)
        sizer.Fit(self)
        self.Layout()
        self.SetMinSize(self.GetSize())
       
        self.keyChoice = keyChoice
        self.subkeyCtrl = subkeyCtrl
        self.valueNameCtrl = valueNameCtrl
        self.tree = tree
        self.tree.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnTreeSelect)
        self.subkeyCtrl.Bind(wx.EVT_TEXT, self.OnSubkeyEnter)
        self.Bind(wx.EVT_SIZE, self.OnSize)

    def OnSubkeyEnter(self, event):
        value = self.subkeyCtrl.GetValue()
        if value.startswith("HK") and value.count("\\") > 0:
            #probably a whole key pasted
            tmp = value.split("\\", 1)
            key = tmp[0].upper() #get first part
            value = tmp[1]
            for i in  range(0,len(regKeys)):
                if regKeys[i][1] == key or regKeys[i][2] == key:
                    self.keyChoice.SetSelection(i)
                    self.subkeyCtrl.SetValue(value)
                    break
        event.Skip()

    def OnTreeSelect(self, event):
        key, subkey, valueName = self.tree.GetValue()
        if key != None:#change only if not root node
            if valueName == None:
                self.valueNameCtrl.SetValue("")
            elif len(valueName) == 0:
                self.valueNameCtrl.SetValue(self.text.defaultText)
            else:
                self.valueNameCtrl.SetValue(valueName)
            self.subkeyCtrl.SetValue(subkey)
            for i in  range(0,len(regKeys)):
               if regKeys[i][0] == key:
                   self.keyChoice.SetSelection(i)
                   break
        self.fillOldValue(key, subkey, valueName)
        event.Skip()

    def fillOldValue(self, key, subkey, valueName):
        curType = None
        curValue = None
        if valueName != None:
            try:
                regHandle = _winreg.OpenKey(key, subkey)
                regValue = _winreg.QueryValueEx(regHandle, valueName)
                _winreg.CloseKey(regHandle)
                for i in  range(1,len(regTypes)):
                    if regTypes[i][0] == regValue[1]:
                        curType = regTypes[i][1]
                        break
            except EnvironmentError, e:
                curType = ""
                curValue = self.text.noValueText
            if len(curType) > 0:
                try:
                    curValue = unicode(regValue[0])
                except:
                    #convert to hex
                    curValue = "0x" + binascii.hexlify(regValue[0]).upper()
        else:
            curType = self.text.keyText2
            curValue = ""
            
        self.oldValueCtrl.SetValue(str(curValue))
        self.oldTypeCtrl.SetValue(curType)
    

    def OnSize(self, event):
        if self.GetAutoLayout():
            self.Layout()

    def GetValue(self):
        #key
        key = regKeys[self.keyChoice.GetSelection()][0]

        #subkey
        subkey = self.subkeyCtrl.GetValue()

        #valueName
        valueName = self.valueNameCtrl.GetValue()
        if len(valueName) == 0:
            valueName = None
        elif valueName == self.text.defaultText:
            valueName = ""
       
        return key, subkey, valueName



class Registry(eg.PluginClass):
    text = Text
   
    def __init__(self):
        self.AddAction(RegistryChange)
        self.AddAction(RegistryQuery)
        self.lastKeySelected = _winreg.HKEY_CURRENT_USER
        self.lastSubkeySelected = "Software"
        self.lastValueNameSelected = None


    def UpdateLastSelectedKeys(self, key, subkey, valueName):
        self.lastKeySelected = key
        self.lastSubkeySelected = subkey
        self.lastValueNameSelected = valueName
   

    def FullKeyName(self, key, subkey, valueName, maxSubkeyLength = 15):
        label = "root"
        if not key:
            return label
           
        for i in  range(0,len(regKeys)):
           if regKeys[i][0] == key:
               label = regKeys[i][2]
               break

        if not subkey:
            return label
       
        if (
            maxSubkeyLength
            and len(subkey) > maxSubkeyLength
            and subkey.count("\\") != 0
        ):
            label += "\\...\\" + subkey.rsplit("\\", 1)[1]
        else:
            label += "\\" + subkey

        if valueName == None:
            return label
        elif len(valueName) == 0:
            return label + "\\" + self.text.defaultText
        else:
            return label + "\\" + valueName



class RegistryQuery(eg.ActionClass):
   
    def __call__(self, key, subkey, valueName, action, compareValue):
        if not key:#nothing selected
           return None

        success = False
        try:
            regHandle = _winreg.OpenKey(key, subkey)
            success = True
        except EnvironmentError, e:
            pass

        #key does not exist or is not readable
        if not success:
            if action == 0:
                return False
            elif action == 1:
                return None
            elif action == 2:
                return False

        #key found and no value specfied
        if valueName == None:
            if action == 0:
                return True
            eg.PrintError(self.text.noValueNameError)
            if action == 1:
                return None
            elif action == 2:
                return False

        #reading value
        try:
            regValue = _winreg.QueryValueEx(regHandle, valueName)
            value = regValue[0]
            if action == 0:
                return True
            elif action == 1:
                return value
            elif action == 2:
                return str(value) == compareValue

        except EnvironmentError, e:
            if action == 0:
                return False
            elif action == 1:
                return None
            elif action == 2:
                return False


    def GetLabel(self, key, subkey, valueName, action, compareValue):
        hkey = self.plugin.FullKeyName(key, subkey, valueName)
        if action == 2:
            return self.text.labels[action] % (hkey, compareValue)
        return self.text.labels[action] % hkey


    def Configure(
        self,
        key = None,
        subkey = None,
        valueName = None,
        action = 0,
        compareValue = ""
    ):
        text = self.text
        plugin = self.plugin

        if key == None:
            key = plugin.lastKeySelected
            subkey = plugin.lastSubkeySelected
            valueName = plugin.lastValueNameSelected
        else:
            plugin.lastKeySelected = key
            plugin.lastSubkeySelected = subkey
            plugin.lastValueNameSelected = valueName

        dialog = eg.ConfigurationDialog(self, resizeable=True)
       
        #keyChooser
        regChooserCtrl = RegistryChooser(
            dialog,
            -1,
            plugin.text,
            key,
            subkey,
            valueName
        )

        def updateLastSelectedKeys(event):
            #print "updateLastSelectedKeys", self.plugin.lastKeySelected, self.plugin.lastSubkeySelected, self.plugin.lastValueNameSelected, "Ctrl", regChooserCtrl.GetValue()
            a, b, c = regChooserCtrl.tree.GetValue()
            plugin.lastKeySelected = a
            plugin.lastSubkeySelected = b
            plugin.lastValueNameSelected = c
            event.Skip()

        regChooserCtrl.tree.Bind(wx.EVT_TREE_SEL_CHANGED, updateLastSelectedKeys)


        dialog.sizer.Add(regChooserCtrl, 1,  flag = wx.EXPAND)
        dialog.sizer.Add(wx.Size(5,5))

        choices = len(text.actions)
        rb = range(0,choices)
        sizer2 = wx.FlexGridSizer(1, choices + 2, 5, 5)
        sizer2.AddGrowableCol(4)

        sizer2.Add(
            wx.StaticText(dialog, -1, plugin.text.actionText),
            flag = wx.ALIGN_CENTER_VERTICAL
        )

        def onRadioButton(event):
            flag = rb[2].GetValue()
            compareValueCtrl.Enable(flag)
            event.Skip()

        rb[0] = wx.RadioButton(
            dialog,
            -1,
            text.actions[0],
            style = wx.RB_GROUP
        )
        rb[0].SetValue(action == 0)
        sizer2.Add(rb[0], flag = wx.ALIGN_CENTER_VERTICAL)
       
        rb[1] = wx.RadioButton(dialog, -1, text.actions[1])
        rb[1].SetValue(action == 1)
        sizer2.Add(rb[1], flag = wx.ALIGN_CENTER_VERTICAL)

        rb[2] = wx.RadioButton(dialog, -1, text.actions[2])
        rb[2].SetValue(action == 2)
        sizer2.Add(rb[2], flag = wx.ALIGN_CENTER_VERTICAL)

        compareValueCtrl = wx.TextCtrl(dialog, -1, compareValue, size=(200,-1)) #, size=(200,-1)
        sizer2.Add(compareValueCtrl, flag = wx.EXPAND)

        onRadioButton(wx.CommandEvent())
        rb[0].Bind(wx.EVT_RADIOBUTTON, onRadioButton)
        rb[1].Bind(wx.EVT_RADIOBUTTON, onRadioButton)
        rb[2].Bind(wx.EVT_RADIOBUTTON, onRadioButton)
       

        dialog.sizer.Add(sizer2, flag = wx.EXPAND)


        if dialog.AffirmedShowModal():
            key, subkey, valueName = regChooserCtrl.GetValue()
            compareValue = compareValueCtrl.GetValue()
            for i in range(0,3):
                if rb[i].GetValue():
                    action = i
                    break

            return (key, subkey, valueName, action, compareValue)
           
       
           
class RegistryChange(eg.ActionClass):
   

    def __call__(self, key, subkey, valueName, action, keyType, newValue):
        if not key:
            eg.PrintError(self.plugin.text.noKeyError)
            return 0
        if not subkey:
            eg.PrintError(self.plugin.text.noSubkeyError)
            return 0
        if not valueName:
            eg.PrintError(self.plugin.text.noValueNameError)
            return 0
       
        #try to get handle
        try:
            if action == 0:
                regHandle = _winreg.CreateKey(key, subkey)
            else:
                regHandle = _winreg.OpenKey(
                    key,
                    subkey,
                    0,
                    _winreg.KEY_WRITE | _winreg.KEY_READ
                )
        except EnvironmentError, e:
            if action != 1:
                eg.PrintError(self.plugin.text.keyOpenError + ": " + str(e))
            return 0
       
        #getting old value
        oldType = None
        try:
            regValue = _winreg.QueryValueEx(regHandle, valueName)
            oldType = regValue[1]
        except EnvironmentError, e:
            #exit because value does not exist
            if (action == 1):
                _winreg.CloseKey(regHandle)
                return 1
            if (action == 2):
                _winreg.CloseKey(regHandle)
                return 0

        #try to determine type if none is given
        if ((action == 0) or (action == 1)) and keyType == None:
            if oldType == None:
                try:
                    int(newValue)
                    #is int
                    keyType = _winreg.REG_DWORD
                except ValueError, e:
                    if newValue.count("%") > 1:
                        keyType = _winreg.REG_EXPAND_SZ
                    else:
                        keyType = _winreg.REG_SZ
            #if key already exists use the old type
            else:
                keyType = oldType
       
        #set or delete key
        try:
            if (action == 0) or (action == 1):
                if keyType == _winreg.REG_DWORD:
                	newValue = int(newValue)
                #change key
                _winreg.SetValueEx(regHandle, valueName, 0, keyType, newValue)
            elif (action == 2):
                #delete value
                _winreg.DeleteValue(regHandle, valueName)
            return 1
        except (EnvironmentError, ValueError), e:
            eg.PrintError(self.plugin.text.valueChangeError + ": " + str(e))
            return 0


    def GetLabel(self, key, subkey, valueName, action, keyType, newValue):
        hkey = self.plugin.FullKeyName(key, subkey, valueName)
        if action == 2:
            return self.text.labels[action] % hkey
        return self.text.labels[action] % (hkey, newValue)


    def Configure(
        self,
        key = None,
        subkey = None,
        valueName = None,
        action = 0,
        keyType = None,
        newValue = ""
    ):
        text = self.text
        plugin = self.plugin
       
        if key == None:
            key = plugin.lastKeySelected
            subkey = plugin.lastSubkeySelected
            valueName = plugin.lastValueNameSelected
        else:
            plugin.lastKeySelected = key
            plugin.lastSubkeySelected = subkey
            plugin.lastValueNameSelected = valueName

        dialog = eg.ConfigurationDialog(self)
       
        #keyChooser
        regChooserCtrl = RegistryChooser(
            dialog,
            -1,
            plugin.text,
            key,
            subkey,
            valueName
        )

        def updateLastSelectedKeys(event):
            a, b, c = regChooserCtrl.tree.GetValue()
            plugin.lastKeySelected = a
            plugin.lastSubkeySelected = b
            plugin.lastValueNameSelected = c
            event.Skip()

        regChooserCtrl.Bind(wx.EVT_TREE_SEL_CHANGED, updateLastSelectedKeys)

        dialog.sizer.Add(regChooserCtrl, 1,  flag = wx.EXPAND)
        dialog.sizer.Add(wx.Size(5,5))

        #Action
        actionSizer = wx.BoxSizer(wx.HORIZONTAL)
       

        choices = len(text.actions)
        rb = range(0, choices)

        actionSizer.Add(
            wx.StaticText(dialog, -1, plugin.text.actionText),
            flag = wx.ALIGN_CENTER_VERTICAL
        )

        def onRadioButton(event):#disables elements depending on action selection
            flag = not rb[2].GetValue()
            newValueCtrl.Enable(flag)
            typeChoice.Enable(flag)
            event.Skip()

        rb[0] = wx.RadioButton(dialog, -1, text.actions[0], style = wx.RB_GROUP)
        rb[0].SetValue(action == 0)
        actionSizer.Add(rb[0], flag = wx.ALIGN_CENTER_VERTICAL)
       
        rb[1] = wx.RadioButton(dialog, -1, text.actions[1])
        rb[1].SetValue(action == 1)
        actionSizer.Add(rb[1], flag = wx.ALIGN_CENTER_VERTICAL)

        rb[2] = wx.RadioButton(dialog, -1, text.actions[2])
        rb[2].SetValue(action == 2)
        actionSizer.Add(rb[2], flag = wx.ALIGN_CENTER_VERTICAL)

        dialog.sizer.Add(actionSizer)
        dialog.sizer.Add(wx.Size(5,5))


        #new Value Input
        newValueSizer = wx.FlexGridSizer(1, 4, 5, 5)
        newValueSizer.AddGrowableCol(1)
       
        newValueSizer.Add(
            wx.StaticText(dialog, -1, plugin.text.newValue),
            flag = wx.ALIGN_CENTER_VERTICAL
        )

        newValueCtrl = wx.TextCtrl(dialog, -1, newValue, size=(200,-1))
        newValueSizer.Add(newValueCtrl, flag = wx.EXPAND)

        newValueSizer.Add(
            wx.StaticText(dialog, -1, plugin.text.typeText),
            flag = wx.ALIGN_CENTER_VERTICAL
        )

        typeChoice = wx.Choice(dialog, -1)
        for i, value in  enumerate(regTypes):
            typeChoice.Append(value[1])
            if value[0] == keyType:
                typeChoice.SetSelection(i)

        newValueSizer.Add(typeChoice)

        onRadioButton(wx.CommandEvent())
        rb[0].Bind(wx.EVT_RADIOBUTTON, onRadioButton)
        rb[1].Bind(wx.EVT_RADIOBUTTON, onRadioButton)
        rb[2].Bind(wx.EVT_RADIOBUTTON, onRadioButton)
       

        dialog.sizer.Add(newValueSizer, flag = wx.EXPAND)

        if dialog.AffirmedShowModal():
            key, subkey, valueName = regChooserCtrl.GetValue()

            for i, item in enumerate(rb):
                if item.GetValue():
                    action = i
                    break

            keyType = regTypes[typeChoice.GetSelection()][0]

            newValue = newValueCtrl.GetValue()

            return (key, subkey, valueName, action, keyType, newValue)
Last edited by Bartman on Mon Sep 11, 2006 6:24 pm, edited 3 times in total.
User avatar
Bitmonster
Site Admin
Posts: 2239
Joined: Mon Feb 06, 2006 10:28 pm

Post by Bitmonster »

Ich habe deinen Source da oben mal direkt geändert.

1. Die Actions als Toplevel-Klassen gemacht, damit man gleich eine Einr├╝ckung spart.
2. Lange Zeilen umgebrochen.
3. RegistryLazyTree hatte noch direkt einen Zugriff auf die Text-Klasse. Habe ich über Parameter geändert.
4. Manche Zugriffe auf self.text und self.plugin durch lokale Variablen verk├╝rzt.

Das Control was du suchst, nennt sich wx.ComboBox.
User avatar
Bitmonster
Site Admin
Posts: 2239
Joined: Mon Feb 06, 2006 10:28 pm

Post by Bitmonster »

Noch ne Kleinigkeit:
Du machst oft sowas wie:
if fatherData[3] != None:

Mir ist dann immer nicht klar, was fatherData[3] ist. Besser wäre es (wenn da sonst nichts dagegen spricht) erst am Anfang fatherData zu entpacken in Variablen, die etwas aussagekräftiger sind. Also sowas wie:

key, value, keyParent, wasWeissIch = fatherData

Das ist dann im Endeffekt auch schneller, da Python mit lokalen Variablen schneller arbeitet als mit einem List-Index.

Jetzt sind es schon 800 Zeilen. :)
Bartman
Plugin Developer
Posts: 881
Joined: Sun Feb 12, 2006 9:03 am

Post by Bartman »

habe das im Posting oben mal geändert und noch ein paar Zeilen dazu geschrieben
User avatar
Bitmonster
Site Admin
Posts: 2239
Joined: Mon Feb 06, 2006 10:28 pm

Post by Bitmonster »

Dann fehlt erstmal nur noch eine __info__.py, dann kann ich das Plugin mal mit aufnehmen.

Mit der Value_anzeige sollte man aber wirklich noch etwas machen. Also da w├╝rde ich dann schon eher eine weitere Zeile opfern damit man dort ein "Current Value" Control hat. Am besten sieht wohl ein TextCtrl aus, dass man disabled hat.
Bartman
Plugin Developer
Posts: 881
Joined: Sun Feb 12, 2006 9:03 am

Post by Bartman »

Code: Select all

name = "Registry"
author = "Bartman"
version = "1.0.0"
description = "Queries or changes values in the windows registry"
Post Reply