From f0473f1eab2fde0c99a1a296384159bb35306a6c Mon Sep 17 00:00:00 2001 From: blitzmann Date: Wed, 3 Sep 2014 12:52:05 -0400 Subject: [PATCH] Added support to show errors for resist imports, as well as many improvements to GUI logic. --- eos/saveddata/targetResists.py | 21 ++++--- gui/resistsEditor.py | 107 ++++++++++++++++++++++++--------- service/targetResists.py | 42 ++++++------- 3 files changed, 110 insertions(+), 60 deletions(-) diff --git a/eos/saveddata/targetResists.py b/eos/saveddata/targetResists.py index 7512e1dfc..00133be3f 100644 --- a/eos/saveddata/targetResists.py +++ b/eos/saveddata/targetResists.py @@ -34,17 +34,22 @@ class TargetResists(object): def importPatterns(cls, text): lines = re.split('[\n\r]+', text) patterns = [] - + numPatterns = 0 for line in lines: - if line.strip()[0] == "#": # comments + try: + if line.strip()[0] == "#": # comments + continue + line = line.split('#',1)[0] # allows for comments + type, data = line.rsplit('=',1) + type, data = type.strip(), data.split(',') + except: + # Data isn't in correct format, continue to next line continue - line = line.split('#',1)[0] # allows for comments - type, data = line.rsplit('=',1) - type, data = type.strip(), data.split(',') - #if type != "TargetResists": - #continue + if type != "TargetResists": + continue + numPatterns += 1 name, data = data[0], data[1:5] #print name, data fields = {} @@ -63,7 +68,7 @@ class TargetResists(object): pattern.name = name.strip() patterns.append(pattern) - return patterns + return patterns, numPatterns EXPORT_FORMAT = "TargetResists = %s,%.1f,%.1f,%.1f,%.1f\n" @classmethod diff --git a/gui/resistsEditor.py b/gui/resistsEditor.py index ad53e952b..fee5928c1 100644 --- a/gui/resistsEditor.py +++ b/gui/resistsEditor.py @@ -21,6 +21,7 @@ import wx import bitmapLoader import service from gui.utils.clipboard import toClipboard, fromClipboard +from service.targetResists import ImportError class ResistsEditorDlg (wx.Dialog): @@ -168,10 +169,14 @@ class ResistsEditorDlg (wx.Dialog): self.Destroy() def ValuesUpdated(self, event=None): + ''' + Event that is fired when resists values change. Iterates through all + resist edit fields. If blank, sets it to 0.0. If it is not a proper + decimal value, sets text color to red and refuses to save changes until + issue is resolved + ''' if self.block: return - if event is not None: - print event.GetString() try: p = self.getActivePattern() @@ -181,7 +186,7 @@ class ResistsEditorDlg (wx.Dialog): if editObj.GetValue() == "": # if we are blank, overwrite with 0 - editObj.ChangeValue("0") + editObj.ChangeValue("0.0") editObj.SetInsertionPointEnd() value = float(editObj.GetValue()) @@ -208,8 +213,8 @@ class ResistsEditorDlg (wx.Dialog): except AssertionError: event.EventObject.SetForegroundColour(wx.RED) self.stNotice.SetLabel("Incorrect Range (must be 0-100)") - finally: - self.Refresh() # Refresh for color changes to take effect immediately + finally: # Refresh for color changes to take effect immediately + self.Refresh() def restrict(self): for type in self.DAMAGE_TYPES: @@ -232,11 +237,16 @@ class ResistsEditorDlg (wx.Dialog): return self.choices[self.ccResists.GetSelection()] def patternChanged(self, event=None): + "Event fired when user selects pattern. Can also be called from script" p = self.getActivePattern() if p is None: + # This happens when there are no patterns in the DB. As such, force + # user to create one first or exit dlg. + self.newPattern(None) return self.block = True + # Set new values for field in self.DAMAGE_TYPES: edit = getattr(self, "%sEdit" % field) amount = getattr(p, "%sAmount" % field)*100 @@ -245,32 +255,35 @@ class ResistsEditorDlg (wx.Dialog): self.block = False self.ValuesUpdated() - def newPattern(self,event): - sTR = service.TargetResists.getInstance() - p = sTR.newPattern() - self.choices.append(p) - id = self.ccResists.Append(p.name) - self.ccResists.SetSelection(id) + def newPattern(self, event): + ''' + Simply does new-pattern specifics: replaces label on button, restricts, + and resets values to default. Hands off to the rename function for + further handling. + ''' self.btnSave.SetLabel("Create") - + self.restrict() # reset values for type in self.DAMAGE_TYPES: editObj = getattr(self, "%sEdit"%type) - editObj.ChangeValue("0") + editObj.ChangeValue("0.0") editObj.SetForegroundColour(wx.NullColor) self.Refresh() self.renamePattern() - def renamePattern(self,event=None): - if event is not None: - self.btnSave.SetLabel("Rename") + def renamePattern(self, event=None): + "Changes layout to facilitate naming a pattern" self.ccResists.Hide() self.namePicker.Show() self.headerSizer.Replace(self.ccResists, self.namePicker) self.namePicker.SetFocus() - self.namePicker.SetValue(self.getActivePattern().name) + if event is not None: # Rename mode + self.btnSave.SetLabel("Rename") + self.namePicker.SetValue(self.getActivePattern().name) + else: # Create mode + self.namePicker.SetValue("") for btn in (self.new, self.rename, self.delete, self.copy): btn.Hide() @@ -283,22 +296,37 @@ class ResistsEditorDlg (wx.Dialog): event.Skip() def processRename(self, event): + ''' + Processes rename event (which can be new or old patterns). If new + pattern, creates it; if old, selects it. if checks are valid, rename + saves pattern to DB. + + Also resets to default layout and unrestricts. + ''' newName = self.namePicker.GetLineText(0) self.stNotice.SetLabel("") - p = self.getActivePattern() - for pattern in self.choices: - if pattern.name == newName and p != pattern: - self.stNotice.SetLabel("Name already used, please pick another") - return - if newName == "": self.stNotice.SetLabel("Invalid name") return sTR = service.TargetResists.getInstance() + if event.EventObject.Label == "Create": + p = sTR.newPattern() + else: + # we are renaming, so get the current selection + p = self.getActivePattern() + + # test for patterns of the same name + for pattern in self.choices: + if pattern.name == newName and p != pattern: + self.stNotice.SetLabel("Name already used, please pick another") + return + + # rename regardless of new or rename sTR.renamePattern(p, newName) + self.updateChoices() self.headerSizer.Replace(self.namePicker, self.ccResists) self.ccResists.Show() self.namePicker.Hide() @@ -309,9 +337,6 @@ class ResistsEditorDlg (wx.Dialog): btn.Show() sel = self.ccResists.GetSelection() - self.ccResists.Delete(sel) - self.ccResists.Insert(newName, sel) - self.ccResists.SetSelection(sel) self.ValuesUpdated() self.unrestrict() @@ -337,17 +362,41 @@ class ResistsEditorDlg (wx.Dialog): def __del__( self ): pass + def updateChoices(self): + "Gathers list of patterns and updates choice selections" + sTR = service.TargetResists.getInstance() + self.choices = sTR.getTargetResistsList() + + # Sort the remaining list and continue on + self.choices.sort(key=lambda p: p.name) + self.ccResists.Clear() + + for choice in map(lambda p: p.name, self.choices): + self.ccResists.Append(choice) + self.ccResists.SetSelection(0) + self.patternChanged() + def importPatterns(self, event): + "Event fired when import from clipboard button is clicked" + text = fromClipboard() if text: sTR = service.TargetResists.getInstance() - # @todo: fix return value and use that to determine label - sTR.importPatterns(text) - self.stNotice.SetLabel("Patterns imported from clipboard") + try: + sTR.importPatterns(text) + self.stNotice.SetLabel("Patterns successfully imported from clipboard") + except service.targetResists.ImportError, e: + self.stNotice.SetLabel(str(e)) + except Exception, e: + self.stNotice.SetLabel("Could not import from clipboard: unknown errors") + finally: + self.updateChoices() else: self.stNotice.SetLabel("Could not import from clipboard") def exportPatterns(self, event): + "Event fired when export to clipboard button is clicked" + sTR = service.TargetResists.getInstance() toClipboard( sTR.exportPatterns() ) self.stNotice.SetLabel("Patterns exported to clipboard") diff --git a/service/targetResists.py b/service/targetResists.py index bdca643ce..49deb154b 100644 --- a/service/targetResists.py +++ b/service/targetResists.py @@ -21,6 +21,9 @@ import eos.db import eos.types import copy +class ImportError(Exception): + pass + class TargetResists(): instance = None @classmethod @@ -30,13 +33,6 @@ class TargetResists(): return cls.instance - def __init__(self): - uniform = eos.db.getTargetResists("None") - if uniform is None: - uniform = eos.types.TargetResists(0,0,0,0) - uniform.name = "None" - eos.db.save(uniform) - def getTargetResistsList(self): return eos.db.getTargetResistsList() @@ -45,7 +41,7 @@ class TargetResists(): return eos.db.getTargetResists(name) def newPattern(self): - p = eos.types.TargetResists(0, 0, 0, 0) + p = eos.types.TargetResists(0.0, 0.0, 0.0, 0.0) p.name = "" return p @@ -69,24 +65,24 @@ class TargetResists(): current = self.getTargetResistsList() for pattern in current: lookup[pattern.name] = pattern - try: - imports = eos.types.TargetResists.importPatterns(text) - for pattern in imports: - if pattern.name in lookup: - match = lookup[pattern.name] - match.__dict__.update(pattern.__dict__) - else: - eos.db.save(pattern) - eos.db.commit() - except: - pass + + imports, num = eos.types.TargetResists.importPatterns(text) + for pattern in imports: + if pattern.name in lookup: + match = lookup[pattern.name] + match.__dict__.update(pattern.__dict__) + else: + eos.db.save(pattern) + eos.db.commit() + + lenImports = len(imports) + if lenImports == 0: + raise ImportError("No patterns found for import") + if lenImports != num: + raise ImportError("%d patterns imported from clipboard; %d had errors"%(num, num-lenImports)) def exportPatterns(self): patterns = self.getTargetResistsList() - for i in xrange(len(patterns) - 1, -1, -1): - if patterns[i].name in ("None"): - del patterns[i] - patterns.sort(key=lambda p: p.name) return eos.types.TargetResists.exportPatterns(*patterns)