示例#1
0
class Keychain():

    def __init__(self, repr: str = "", key: str = "", chord: str = "", boundFiles: [BindFile] = None):
        if (repr != ""):
            self.Parse(repr)
        else:
            self.parserBind = Bind(key=key, chord=chord)
            self.Key = self.parserBind.GetDefaultedKeyName()
            self.Chord = self.parserBind.GetDefaultedChordName()
            self.BoundFiles = boundFiles

    def Parse(self, repr: str):
        keychainDict = ast.literal_eval(repr)
        self.parserBind = Bind(key=keychainDict[KEY], chord=keychainDict[CHORD])
        self.Key = self.parserBind.GetDefaultedKeyName()
        self.Chord = self.parserBind.GetDefaultedChordName()
        boundFilesRepr = keychainDict[BOUND_FILES]
        if boundFilesRepr == NONE:
            boundFiles = None
        else:
            boundFiles = []
            for boundFileEntry in boundFilesRepr:
                boundFile = BindFile(repr=boundFileEntry[REPR])
                boundFile.FilePath = boundFileEntry[PATH]
                boundFiles.append(boundFile)
        self.BoundFiles = boundFiles
    
    def GetKeyWithChord(self):
        return self.parserBind.GetKeyWithChord(defaultNames=True)

    #Dictionary structure
    #KEY - Key for bind in root file
    #CHORD - Chord for bind in root file
    #BOUND_FILES- Array of dictionaries for bound files
        #PATH - Path from load command
        #REPR - repr string of loaded bind file

    def GetDictionary(self):
        keychainDict = {}
        keychainDict[KEY] = self.Key
        keychainDict[CHORD] = self.Chord
        if self.BoundFiles == None:
            keychainDict[BOUND_FILES] = NONE
        else:
            bound_files = []
            for boundFile in self.BoundFiles:
                bound_file_dict = {}
                bound_file_dict[PATH] = boundFile.FilePath
                bound_file_dict[REPR] = boundFile.__repr__()
                bound_files.append(bound_file_dict)
            keychainDict[BOUND_FILES] = bound_files
        return keychainDict


    def __repr__(self)->str:
        keychainDict = self.GetDictionary()
        return keychainDict.__repr__()

    def Clone(self):
        return Keychain(repr=self.__repr__())
示例#2
0
 def __init__(self, repr: str = "", key: str = "", chord: str = "", boundFiles: [BindFile] = None):
     if (repr != ""):
         self.Parse(repr)
     else:
         self.parserBind = Bind(key=key, chord=chord)
         self.Key = self.parserBind.GetDefaultedKeyName()
         self.Chord = self.parserBind.GetDefaultedChordName()
         self.BoundFiles = boundFiles
 def GetBindForKey(self, key, chord = ""):
     if (self.Binds == None):
         return []
     quickMatch = [b for b in self.Binds if ((b.Key == key) and ((chord == None) or (b.Chord == chord)))]
     if (len(quickMatch) > 0):
         return quickMatch
     dummyForConversion = Bind(key=key, chord=chord)
     defaultedName = dummyForConversion.GetKeyWithChord(defaultNames=True)
     return [b for b in self.Binds if (defaultedName == b.GetKeyWithChord(defaultNames=True))]
 def test_FromString(self):
     input = "A \"say This test passed\"\nB \"emote Yay!\""
     target = BindFile(repr=input)
     actual = len(target.Binds)
     self.assertEqual(actual, 2, "Did not find expected bind count")
     actual = str(target.Binds[0])
     expected = str(Bind(key="A", commands=[SlashCommand("say","This test passed")]))
     self.assertEqual(actual, expected, "Did not find expected 1st bind")
     actual = str(target.Binds[1])
     expected = str(Bind(key="B", commands=[SlashCommand("emote","Yay!")]))
     self.assertEqual(actual, expected, "Did not find expected 2nd bind")
示例#5
0
 def Load(self, bind: Bind):
     self.Loading = True
     try:
         if (self._lockKey):
             self.TextEntry.SetText(bind.GetCommands())
         else:
             self.TextEntry.SetText(bind.__repr__())
         self.SynchTextToUI()
     finally:
         self.Loading = False
     self.SetClean(self)
示例#6
0
    def __init__(self,
                 parent,
                 resultCallback,
                 bind: Bind = None,
                 lockKey=False,
                 title=None,
                 dirty=False):

        tk.Toplevel.__init__(self, parent)
        self.attributes("-topmost", 1)

        if (title == None):
            if (bind == None):
                title = 'New Bind'
                dirty = True
            else:
                title = bind.GetKeyWithChord()

        self.Title = title
        self.ResultCallback = resultCallback

        self.title(title)
        icon = GetResourcePath('.\\Resources\\keystone.ico')
        if (icon != None):
            self.iconbitmap(icon)
        self.protocol("WM_DELETE_WINDOW", self.OnCancel)
        self.columnconfigure(0, weight=1)
        self.rowconfigure(0, weight=1)

        frame = KeystoneEditFrame(self)
        frame.columnconfigure(0, weight=0)
        frame.columnconfigure(1, weight=1, minsize='205')
        frame.rowconfigure(0, weight=1)
        frame.rowconfigure(1, weight=0)

        if (bind == None):
            self.Editor = BindEditor(frame,
                                     Bind(repr=DEFAULT_BIND),
                                     lockKey=lockKey,
                                     dirty=dirty)
        else:
            self.Editor = BindEditor(frame, bind, lockKey=lockKey, dirty=dirty)
        self.Editor.grid(column=1, row=0, rowspan=2, sticky='nsew')
        self.Cancel = KeystoneButton(frame, text="OK", command=self.OnOk)
        self.Cancel.configure(text="Cancel", command=self.OnCancel)
        self.Cancel.Color('red', 'black')
        self.Cancel.grid(column=0, row=1, sticky='nsew')
        self.OK = KeystoneButton(frame, text="OK", command=self.OnOk)
        self.OK.Color('green', 'black')
        self.OK.grid(column=0, row=0, sticky='nsew')
        frame.grid(column=0, row=0, sticky='nsew')
示例#7
0
 def Parse(self, repr: str):
     keychainDict = ast.literal_eval(repr)
     self.parserBind = Bind(key=keychainDict[KEY], chord=keychainDict[CHORD])
     self.Key = self.parserBind.GetDefaultedKeyName()
     self.Chord = self.parserBind.GetDefaultedChordName()
     boundFilesRepr = keychainDict[BOUND_FILES]
     if boundFilesRepr == NONE:
         boundFiles = None
     else:
         boundFiles = []
         for boundFileEntry in boundFilesRepr:
             boundFile = BindFile(repr=boundFileEntry[REPR])
             boundFile.FilePath = boundFileEntry[PATH]
             boundFiles.append(boundFile)
     self.BoundFiles = boundFiles
示例#8
0
    def __init__(self, parent, bind: Bind, dirty=False):
        KeystoneEditFrame.__init__(self, parent)

        self.BindFileEditor = parent
        while (self.BindFileEditor.__class__.__name__ != "EditBindFile"):
            self.BindFileEditor = self.BindFileEditor.master
            if (self.BindFileEditor == None):
                break
        self.Editor = None

        self.columnconfigure(0, weight=0)
        self.columnconfigure(1, weight=1)
        self.rowconfigure(0, weight=0)
        self.rowconfigure(1, weight=0)
        self._showingEdit = True
        self.Button = KeystoneButton(self,
                                     text="...",
                                     width=6,
                                     command=self.OnEdit)
        self.Button.grid(row=0, column=0, sticky="nsew")
        self.Repr = tk.StringVar()
        self.Label = KeystoneLabel(self, textvariable=self.Repr)
        self.Repr.set(bind.__repr__())
        self.Label.grid(row=0, column=1, sticky="nsew")

        self.OnSetDirty.append(self.SetEdited)
        self.OnSetClean.append(self.SetEdited)
        self.BindFileEditor.OnSetClean.append(self.SetClean)
        if (dirty):
            self.SetDirty()
示例#9
0
    def AddUploadBind(self, *args):
        if (self.FilePath == None):
            return
        path = os.path.abspath(self.FilePath)
        bind = None
        dirty = False
        #find current biind
        loadBinds = [
            bind for bind in [item.Item.Get() for item in self.view.Items]
            if bind.IsLoadFileBind()
        ]
        for loadBind in loadBinds:
            loadCommands = loadBind.GetLoadFileCommands()
            for command in loadCommands:
                boundPath = command.GetTargetFile()
                if (boundPath == path):
                    bind = loadBind
                    break
            if (bind != None):
                break

        if (bind == None):
            bind = Bind(repr=DEFAULT_LOAD_BIND % path)
            dirty = True

        if (self.Editor == None):
            self.Editor = EditBindWindow(self,
                                         self.NewBindCallback,
                                         bind=bind,
                                         dirty=dirty)
示例#10
0
def GetDefaultBindForKey(key, chord = "") -> Bind:
    bindFile = NewBindFile(defaults=True)
    binds = bindFile.GetBindForKey(key, chord)
    if (len(binds) > 0):
        return binds[0]
    else:
        return Bind(key, chord, [SlashCommand(repr=DEFAULT_COMMAND)])
示例#11
0
 def Newlink(self, filePath) -> Keylink:
     filePath = os.path.abspath(filePath)
     #create load command
     loadCommand = SlashCommand(name=LOAD_FILE_COMMANDS[0],
                                text="\"%s\"" % filePath)
     loadBind = Bind(self.Key, self.Chord, [loadCommand])
     #create new bind file
     bindFile = BindFile(binds=[loadBind], filePath=filePath)
     return Keylink(bindFile, self.Key, self.Chord)
 def test_Clone(self):
     target = Bind(repr = "SHIFT+A \"say This test failed $$ emote No!\"")
     actual = target.Clone()
     actual.Key = "B"
     actual.Chord = "ALT"
     actual.Commands[0].Name = "em"
     actual.Commands[0].Text = "This test passed"
     actual.Commands[1].Name = "say"
     actual.Commands[1].Text = "Yay!"
     self.assertNotEqual(actual.Key, target.Key, 'Key not different')
     self.assertNotEqual(actual.Chord, target.Chord, 'Chord not different')
     self.assertNotEqual(actual.Commands[0].Name, target.Commands[0].Name, 'Commands[0].Name not different')
     self.assertNotEqual(actual.Commands[0].Text, target.Commands[0].Text, 'Commands[0].Text not different')
     self.assertNotEqual(actual.Commands[1].Name, target.Commands[1].Name, 'Commands[1].Name not different')
     self.assertNotEqual(actual.Commands[1].Text, target.Commands[1].Text, 'Commands[1].Text not different')
     self.assertEqual(actual.Key, "B", 'Key not changed')
     self.assertEqual(actual.Chord, "ALT", 'Chord not changed')
     self.assertEqual(actual.Commands[0].Name, "em", 'Commands[0].Name not changed')
     self.assertEqual(actual.Commands[0].Text, "This test passed", 'Commands[0].Text not changed')
     self.assertEqual(actual.Commands[1].Name, "say", 'Commands[1].Name not changed')
     self.assertEqual(actual.Commands[1].Text, "Yay!", 'Commands[1].Text not changed')
示例#13
0
 def __init__(self,
              bindFileCollection: BindFileCollection,
              key: str,
              chord: str = ""):
     self.Collection = bindFileCollection
     self.Anchor = Keylink(bindFileCollection.File, key, chord)
     self.RootPath = os.path.dirname(self.Anchor.FilePath)
     self.Links = []
     self.Key = key
     self.Chord = chord
     keyChord = Bind(key, chord).GetKeyWithChord()
     for bindFile in bindFileCollection.KeyChains[keyChord]:
         self.Links.append(Keylink(bindFile, key, chord))
示例#14
0
 def GetBindFromUI(self) -> Bind:
     bind = Bind()
     if (self.ShowCommands.get()):
         bind.Commands = [item.Item.Get() for item in self.Commands.Items]
     else:
         bind.Commands = None
     bind.Key = self.Key.get()
     bind.Chord = self.Chord.get()
     return bind
    def test__repr__(self):
        #test a single command
        key = "A"
        commands = [SlashCommand(name="say", text="This test passed")]
        expected = "A \"say This test passed\""
        target = Bind(key=key, commands=commands)
        actual = str(target)
        self.assertEqual(actual, expected, "Single command")

        #test concatenated commands
        commands = [SlashCommand(name="say", text="This test passed"), SlashCommand(name="emote", text="Yay!")]
        expected = "A \"say This test passed$$emote Yay!\""
        target = Bind(key=key, commands=commands)
        actual = str(target)
        self.assertEqual(actual, expected, "Multiple commands")

        #test chord
        key = "A"
        chord = "CTRL"
        commands = [SlashCommand(name="say", text="This test passed")]
        expected = "CTRL+A \"say This test passed\""
        target = Bind(key=key, chord=chord, commands=commands)
        actual = str(target)
        self.assertEqual(actual, expected, "Chord in key")
示例#16
0
    def Load(self, bindFile):
        self.LoadedFile = bindFile.Clone()
        self.Loading = True
        try:
            if (self.LoadedFile.Binds != None):

                binds = []
                if (self.List.get()):
                    binds = self.LoadedFile.Binds
                else:
                    #load in expeded order
                    chords = ['']
                    for chord, altname, desc in CHORD_KEYS:
                        dummy = altname
                        dummy = desc
                        chords.append(chord)
                    for key, altname, desc in KEY_NAMES:
                        dummy = altname
                        dummy = desc
                        for chord in chords:
                            keyBinds = self.LoadedFile.GetBindForKey(
                                key, chord)
                            if (len(keyBinds) > 0):
                                binds.append(keyBinds[0])
                    #load anything in the file we didn't match at the end
                    for bind in self.LoadedFile.Binds:
                        loaded = [
                            b for b in binds if (bind.GetKeyWithChord(
                                defaultNames=True) == b.GetKeyWithChord(
                                    defaultNames=True))
                        ]
                        if (len(loaded) == 0):
                            binds.append(bind)

                self.view.Load(BindListItem, binds, Bind(repr=DEFAULT_BIND))

        finally:
            self.Loading = False
        self.FilePath = self.LoadedFile.FilePath
        if (self.FilePath == None):
            self.PathLabel.configure(text="")
        else:
            self.PathLabel.configure(text=self.FilePath)
            if (os.path.exists(self.FilePath)):
                self.SetClean(self)
            else:
                self.SetDirty(self)
        self.OnLinkedFilesFound()
示例#17
0
 def SynchTextToUI(self):
     key = self.Key.get()
     chord = self.Chord.get()
     text = self.TextEntry.GetText()
     if (self._lockKey):
         text = "%s %s" % (FormatKeyWithChord(key, chord), text)
     bind = Bind(repr=text)
     if (key != bind.Key):
         self.Key.set(bind.Key)
     if (chord != bind.Chord):
         self.Chord.set(bind.Chord)
     if (bind.Commands != None):
         self.Commands.Load(SlashCommandEditor, bind.Commands,
                            SlashCommand(repr=DEFAULT_COMMAND))
         self.ShowCommands.set(True)
     else:
         self.ShowCommands.set(False)
     self.ShowTextEditor.set(False)
def getBoundFiles(path, bind: Bind, foundFiles, boundFiles):
    for command in bind.GetLoadFileCommands():
        boundPath = command.GetTargetFile()
        if (ComparableFilePath (boundPath) == ComparableFilePath (path)):
            #self load
            continue
        if (boundFiles == None):
            if (os.path.exists(boundPath)):
                action = 'read_from_disk'
            else:
                action = 'create_a_blank'
        else:
            match = [b for b in boundFiles if ComparableFilePath (b.FilePath) == ComparableFilePath (boundPath)]
            if (len(match) > 0):
                action = 'loaded_match'
                boundFile = match[0]
            elif (os.path.exists(boundPath)):
                action = 'read_from_disk'
            else:
                action = 'create_a_blank'

        if (action == 'create_a_blank'):
            boundFile = NewBindFile()
            boundFile.FilePath = boundPath
        elif (action == 'read_from_disk'):
            boundFile = ReadBindsFromFile(boundPath)

        #check if already included
        match = [b for b in foundFiles if ComparableFilePath (b.FilePath) == ComparableFilePath (boundFile.FilePath)]
        if (len(match) > 0):
            continue

        foundFiles.append(boundFile.Clone())
        for chainBind in boundFile.GetLoadFileBinds():
                for foundFile in getBoundFiles(path, chainBind, foundFiles, boundFiles):
                    match = [b for b in foundFiles if ComparableFilePath (b.FilePath) == ComparableFilePath (boundFile.FilePath)]
                    if (len(match) > 0):
                        continue
                    foundFiles.append(foundFile)
        
    return foundFiles
示例#19
0
 def AssignCommand(self, *args):
     model = Bind(key=self.Key.get(),
                  chord=self.Chord.get(),
                  commands=[SlashCommand(repr=DEFAULT_COMMAND)])
     self.Load(model)
     self.SetDirty()
 def test__repr__(self):
     expected = "A \"say This test passed\"\nB \"emote Yay!\""
     binds = [Bind(key="A", commands=[SlashCommand("say", "This test passed")]), Bind(key="B", commands=[SlashCommand("emote", "Yay!")])]
     target = BindFile(binds)
     actual = str(target)
     self.assertEqual(actual, expected)
    def test_GetKeyWithChord(self):

        target = Bind(repr = "PERIOD \"say This test passed\"")
        expected = "PERIOD"
        actual = target.GetKeyWithChord()
        self.assertEqual(actual, expected, 'Did not get expected non-chorded key')
        expected = "."
        actual = target.GetKeyWithChord(defaultNames=True)
        self.assertEqual(actual, expected, 'Did not get expected defaulted non-chorded key')
       
        target = Bind(repr = "shift+PERIOD \"say This test passed\"")
        expected = "shift+PERIOD"
        actual = target.GetKeyWithChord()
        self.assertEqual(actual, expected, 'Did not get expected chorded key')
        expected = "SHIFT+."
        actual = target.GetKeyWithChord(defaultNames=True)
        self.assertEqual(actual, expected, 'Did not get expected defaulted chorded key')
       
        target = Bind(repr = "whoknows+whatthisis \"say This test passed\"")
        expected = "whoknows+whatthisis"
        actual = target.GetKeyWithChord()
        self.assertEqual(actual, expected, 'Did not get expected chorded nonsense')
        actual = target.GetKeyWithChord(defaultNames=True)
        self.assertEqual(actual, expected, 'Did not get expected defaulted chorded nonsense')
    def test_FromString(self):
        #test single command bound to key (with leading spaces)
        target = Bind(repr = "   A \"say This test passed\"")
        self.assertEqual(target.Key, "A", "Did not find expected KeyName on a single command")
        actual = len(target.Commands)
        self.assertEqual(actual, 1, "Did not find expected command count on a single command")
        actual = target.Commands[0].Name
        self.assertEqual(actual, "say", "Did not find expected command name on a single command")
        actual = target.Commands[0].Text
        self.assertEqual(actual, "This test passed", "Did not find expected command text on a single command")

        #test concatenated commands bound to a key
        target = Bind(repr = "A \"say This test passed $$ emote Yay!\"")
        self.assertEqual(target.Key, "A", "Did not find expected KeyName on concatenated commands")
        actual = len(target.Commands)
        self.assertEqual(actual, 2, "Did not find expected command count on concatenated commands")
        actual = target.Commands[0].Name
        self.assertEqual(actual, "say", "Did not find expected 1st command name on concatenated commands")
        actual = target.Commands[0].Text
        self.assertEqual(actual, "This test passed ", "Did not find expected 1st command text on concatenated commands")
        actual = target.Commands[1].Name
        self.assertEqual(actual, "emote", "Did not find expected 2nd command name on concatenated commands")
        actual = target.Commands[1].Text
        self.assertEqual(actual, "Yay!", "Did not find expected 2nd command text on concatenated commands")

        #test string with quote bound space
        expected ="COMMA \"show chat$$beginchat /tell $target, \""
        target = Bind(repr = "COMMA \"show chat$$beginchat /tell $target, \"")
        actual = str(target)
        self.assertEqual(actual, expected, "Did not get expected round trip on a Bind with a space bound by quotes")

        #test key with a chord
        target = Bind(repr = "SHIFT+A \"say This test passed\"")
        self.assertEqual(target.Key, "A", "Did not find expected KeyName on a chord")
        self.assertEqual(target.Chord, "SHIFT", "Did not find expected Chord on a chord")
        actual = len(target.Commands)
        self.assertEqual(actual, 1, "Did not find expected command count on a chord")
        actual = target.Commands[0].Name
        self.assertEqual(actual, "say", "Did not find expected command name on a chord")
        actual = target.Commands[0].Text
        self.assertEqual(actual, "This test passed", "Did not find expected command text on a chord")

        #test load file bind
        self.assertEqual(target.IsLoadFileBind(), False, "Unexpectedly set IsLoadFileBind")
        target = Bind(repr = "MouseChord \"powexec_name Hover$$bind_load_file \".\\TestReferences\\Jock Tamson\\MouseChord2.txt\"\"")
        self.assertEqual(target.IsLoadFileBind(), True, "Unexpectedly did not set IsLoadFileBind")
示例#23
0
 def Parse(self, repr: str):
     parts = repr.split(self.LINE_SEPARATOR)
     self.Binds = [Bind(repr=p) for p in parts if (p != "")]
示例#24
0
 def Get(self):
     return Bind(repr=self.Repr.get())