From c59b8186775b2de7379d000143d174976a6014a2 Mon Sep 17 00:00:00 2001 From: blitzmann Date: Fri, 19 Dec 2014 00:13:06 -0500 Subject: [PATCH] Add wx.ProgressDialog to HTML export, along with some documentation and silent try-except in HTML export --- gui/mainFrame.py | 193 +++++++++++++++++++++------------------- gui/utils/exportHtml.py | 42 ++++++--- service/fit.py | 31 ++++--- service/port.py | 1 - 4 files changed, 150 insertions(+), 117 deletions(-) diff --git a/gui/mainFrame.py b/gui/mainFrame.py index 053fe08f7..61a5573b9 100644 --- a/gui/mainFrame.py +++ b/gui/mainFrame.py @@ -330,57 +330,16 @@ class MainFrame(wx.Frame): dlg.ShowModal() dlg.Destroy() - def showImportDialog(self, event): - fits = [] - sFit = service.Fit.getInstance() - dlg=wx.FileDialog( - self, - "Open One Or More Fitting Files", - wildcard = "EVE XML fitting files (*.xml)|*.xml|" \ - "EFT text fitting files (*.cfg)|*.cfg|" \ - "All Files (*)|*", - style = wx.FD_OPEN | wx.FD_FILE_MUST_EXIST | wx.FD_MULTIPLE) - if (dlg.ShowModal() == wx.ID_OK): - - self.progressDialog = wx.ProgressDialog("Importing fits", " "*100, parent=self, - style = wx.PD_APP_MODAL | wx.PD_ELAPSED_TIME) - self.progressDialog.message = None - sFit.importFitsThreaded(dlg.GetPaths(), self.importCallback) - self.progressDialog.ShowModal() - dlg.Destroy() - - def importCallback(self, info): - if info == -1: - self.progressDialog.Destroy() - elif info != self.progressDialog.message and info is not None: - self.progressDialog.message = info - self.progressDialog.Pulse(info) - else: - self.progressDialog.Pulse() - - # @todo: implement saveImportedFits where needed, modify _openAfterImport - #sFit = service.Fit.getInstance() - #IDs = sFit.saveImportedFits(fits) - #self._openAfterImport(len(fits), IDs) - - def _openAfterImport(self, importCount, fitIDs): - if importCount == 1: - wx.PostEvent(self, FitSelected(fitID=fitIDs[0])) - - self.shipBrowser.RefreshContent() - def showExportDialog(self, event): - dlg=wx.FileDialog( - self, - "Save Fitting As...", - wildcard = "EVE XML fitting files (*.xml)|*.xml", - style = wx.FD_SAVE) - if (dlg.ShowModal() == wx.ID_OK): + """ Export active fit """ + dlg = wx.FileDialog(self, "Save Fitting As...", + wildcard = "EVE XML fitting files (*.xml)|*.xml", + style = wx.FD_SAVE) + if dlg.ShowModal() == wx.ID_OK: sFit = service.Fit.getInstance() format = dlg.GetFilterIndex() - output = "" path = dlg.GetPath() - if (format == 0): + if format == 0: output = sFit.exportXml(self.getActiveFit()) if '.' not in os.path.basename(path): path += ".xml" @@ -420,7 +379,7 @@ class MainFrame(wx.Frame): # Target Resists editor self.Bind(wx.EVT_MENU, self.showTargetResistsEditor, id=menuBar.targetResistsEditorId) # Import dialog - self.Bind(wx.EVT_MENU, self.showImportDialog, id=wx.ID_OPEN) + self.Bind(wx.EVT_MENU, self.fileImportDialog, id=wx.ID_OPEN) # Export dialog self.Bind(wx.EVT_MENU, self.showExportDialog, id=wx.ID_SAVEAS) # Import from Clipboard @@ -565,12 +524,10 @@ class MainFrame(wx.Frame): sFit = service.Fit.getInstance() try: fits = sFit.importFitFromBuffer(fromClipboard(), self.getActiveFit()) - IDs = sFit.saveImportedFits(fits) - self._openAfterImport(len(fits), IDs) + #self._openAfterImport(len(fits), IDs) except: pass - def exportToClipboard(self, event): CopySelectDict = {CopySelectDialog.copyFormatEft: self.clipboardEft, CopySelectDialog.copyFormatEftImps: self.clipboardEftImps, @@ -585,59 +542,103 @@ class MainFrame(wx.Frame): pass dlg.Destroy() - def updateProgressDialog(self,count): - if count == -1: + def fileImportDialog(self, event): + """Handles importing single/multiple EVE XML / EFT cfg fit files""" + sFit = service.Fit.getInstance() + dlg = wx.FileDialog(self, "Open One Or More Fitting Files", + wildcard = "EVE XML fitting files (*.xml)|*.xml|" \ + "EFT text fitting files (*.cfg)|*.cfg|" \ + "All Files (*)|*", + style = wx.FD_OPEN | wx.FD_FILE_MUST_EXIST | wx.FD_MULTIPLE) + if (dlg.ShowModal() == wx.ID_OK): + self.progressDialog = wx.ProgressDialog( + "Importing fits", + " "*100, # set some arbitrary spacing to create wifth in window + parent=self, style = wx.PD_APP_MODAL | wx.PD_ELAPSED_TIME) + self.progressDialog.message = None + sFit.importFitsThreaded(dlg.GetPaths(), self.importCallback) + self.progressDialog.ShowModal() + dlg.Destroy() + + def importCallback(self, info): + """ + While importing fits from file, the logic calls back to this function to + update progress bar to show activity. If -1, closes dialog. If None, + simply Pulse()s progress. If there is a message to show new activity, + overwrites cached message and updates dialog + """ + if info == -1: self.progressDialog.Destroy() + elif info != self.progressDialog.message and info is not None: + self.progressDialog.message = info + self.progressDialog.Pulse(info) else: - self.progressDialog.Update(count) + self.progressDialog.Pulse() + + # @todo: modify _openAfterImport + #self._openAfterImport(len(fits), IDs) + + def _openAfterImport(self, importCount, fitIDs): + if importCount == 1: + wx.PostEvent(self, FitSelected(fitID=fitIDs[0])) + + self.shipBrowser.RefreshContent() def backupToXml(self, event): - sFit = service.Fit.getInstance() - + """ Back up all fits to EVE XML file """ defaultFile = "pyfa-fits-%s.xml"%strftime("%Y%m%d_%H%M%S", gmtime()) - saveDialog = wx.FileDialog( - self, - "Save Backup As...", - wildcard = "EVE XML fitting file (*.xml)|*.xml", - style = wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT, - defaultFile=defaultFile) + saveDialog = wx.FileDialog(self, "Save Backup As...", + wildcard = "EVE XML fitting file (*.xml)|*.xml", + style = wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT, + defaultFile=defaultFile) - if (saveDialog.ShowModal() == wx.ID_OK): + if saveDialog.ShowModal() == wx.ID_OK: filePath = saveDialog.GetPath() if '.' not in os.path.basename(filePath): filePath += ".xml" + sFit = service.Fit.getInstance() max = sFit.countAllFits() + self.progressDialog = wx.ProgressDialog("Backup fits", "Backing up %d fits to: %s"%(max, filePath), - maximum = max, parent=self, - style = wx.PD_APP_MODAL | wx.PD_ELAPSED_TIME) + maximum=max, parent=self, + style=wx.PD_APP_MODAL | wx.PD_ELAPSED_TIME) - sFit.backupFits(filePath, self.updateProgressDialog) + sFit.backupFits(filePath, self.backupCallback) self.progressDialog.ShowModal() + def backupCallback(self, info): + #print info + if info == -1: + self.progressDialog.Destroy() + else: + self.progressDialog.Update(info) + def exportSkillsNeeded(self, event): + """ Exports skills needed for active fit and active character """ sCharacter = service.Character.getInstance() - saveDialog = wx.FileDialog( - self, - "Export Skills Needed As...", - wildcard = "EVEMon skills training file (*.emp)|*.emp|" \ - "EVEMon skills training XML file (*.xml)|*.xml|" \ - "Text skills training file (*.txt)|*.txt", - style = wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT) - if (saveDialog.ShowModal() == wx.ID_OK): + saveDialog = wx.FileDialog(self, "Export Skills Needed As...", + wildcard = "EVEMon skills training file (*.emp)|*.emp|" \ + "EVEMon skills training XML file (*.xml)|*.xml|" \ + "Text skills training file (*.txt)|*.txt", + style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT) + + if saveDialog.ShowModal() == wx.ID_OK: saveFmtInt = saveDialog.GetFilterIndex() - saveFmt = "" + if saveFmtInt == 0: # Per ordering of wildcards above saveFmt = "emp" elif saveFmtInt == 1: saveFmt = "xml" else: saveFmt = "txt" + filePath = saveDialog.GetPath() if '.' not in os.path.basename(filePath): filePath += ".{0}".format(saveFmt) + self.waitDialog = animUtils.WaitDialog(self) sCharacter.backupSkills(filePath, saveFmt, self.getActiveFit(), self.closeWaitDialog) self.waitDialog.ShowModal() @@ -645,29 +646,39 @@ class MainFrame(wx.Frame): saveDialog.Destroy() def importCharacter(self, event): - sCharacter = service.Character.getInstance() - dlg=wx.FileDialog( - self, - "Open One Or More Character Files", - wildcard = "EVE CCP API XML character files (*.xml)|*.xml|" \ - "All Files (*)|*", - style = wx.FD_OPEN | wx.FD_FILE_MUST_EXIST | wx.FD_MULTIPLE) - if (dlg.ShowModal() == wx.ID_OK): - self.waitDialog = animUtils.WaitDialog(self, title = "Importing Character") + """ Imports character XML file from EVE API """ + dlg = wx.FileDialog(self, "Open One Or More Character Files", + wildcard="EVE API XML character files (*.xml)|*.xml|" \ + "All Files (*)|*", + style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST | wx.FD_MULTIPLE) + + if dlg.ShowModal() == wx.ID_OK: + self.waitDialog = animUtils.WaitDialog(self, title="Importing Character") + sCharacter = service.Character.getInstance() sCharacter.importCharacter(dlg.GetPaths(), self.importCharacterCallback) dlg.Destroy() self.waitDialog.ShowModal() - def exportHtml(self, event): - from gui.utils.exportHtml import exportHtml - self.waitDialog = animUtils.WaitDialog(self) - exportHtml.getInstance().refreshFittingHtml(True, self.closeWaitDialog) - self.waitDialog.ShowModal() - def importCharacterCallback(self): self.waitDialog.Destroy() wx.PostEvent(self, GE.CharListUpdated()) + def exportHtml(self, event): + from gui.utils.exportHtml import exportHtml + sFit = service.Fit.getInstance() + settings = service.settings.HTMLExportSettings.getInstance() + + max = sFit.countAllFits() + path = settings.getPath() + print max + self.progressDialog = wx.ProgressDialog("Backup fits", + "Generating HTML file at:\n%s"%path, + maximum=max, parent=self, + style=wx.PD_APP_MODAL | wx.PD_ELAPSED_TIME) + + exportHtml.getInstance().refreshFittingHtml(True, self.backupCallback) + self.progressDialog.ShowModal() + def closeWaitDialog(self): self.waitDialog.Destroy() @@ -679,7 +690,7 @@ class MainFrame(wx.Frame): else: self.graphFrame.SetFocus() - def openWXInspectTool(self,event): + def openWXInspectTool(self, event): from wx.lib.inspection import InspectionTool if not InspectionTool().initialized: InspectionTool().Init() diff --git a/gui/utils/exportHtml.py b/gui/utils/exportHtml.py index c61c2444a..281b5c32c 100644 --- a/gui/utils/exportHtml.py +++ b/gui/utils/exportHtml.py @@ -7,7 +7,7 @@ class exportHtml(): _instance = None @classmethod def getInstance(cls): - if cls._instance == None: + if cls._instance is None: cls._instance = exportHtml() return cls._instance @@ -15,17 +15,17 @@ class exportHtml(): def __init__(self): self.thread = exportHtmlThread() - def refreshFittingHtml(self, force = False, callback = False): + def refreshFittingHtml(self, force=False, callback=False): settings = service.settings.HTMLExportSettings.getInstance() - if (force or settings.getEnabled()): + if force or settings.getEnabled(): self.thread.stop() self.thread = exportHtmlThread(callback) self.thread.start() class exportHtmlThread(threading.Thread): - def __init__(self, callback = False): + def __init__(self, callback=False): threading.Thread.__init__(self) self.callback = callback self.stopRunning = False @@ -40,7 +40,7 @@ class exportHtmlThread(threading.Thread): return sMkt = service.Market.getInstance() - sFit = service.Fit.getInstance() + sFit = service.Fit.getInstance() settings = service.settings.HTMLExportSettings.getInstance() timestamp = time.localtime(time.time()) @@ -135,6 +135,9 @@ class exportHtmlThread(threading.Thread): HTML += ' \n' ' \n') + if groupFits > 0: # Market group header HTML += ( @@ -197,5 +215,5 @@ class exportHtmlThread(threading.Thread): pass if self.callback: - wx.CallAfter(self.callback) + wx.CallAfter(self.callback, -1) diff --git a/service/fit.py b/service/fit.py index 3c5faa9fc..25635b070 100644 --- a/service/fit.py +++ b/service/fit.py @@ -50,6 +50,8 @@ class FitBackupThread(threading.Thread): backupFile = open(path, "w", encoding="utf-8") backupFile.write(backedUpFits) backupFile.close() + + # Send done signal to GUI wx.CallAfter(self.callback, -1) @@ -63,6 +65,7 @@ class FitImportThread(threading.Thread): sFit = Fit.getInstance() sFit.importFitFromFiles(self.paths, self.callback) + # Send done signal to GUI wx.CallAfter(self.callback, -1) @@ -769,9 +772,16 @@ class Fit(object): thread.start() def importFitFromFiles(self, paths, callback=None): + """ + Imports fits from file(s). First processes all provided paths and stores + assembled fits into a list. This allows us to call back to the GUI as + fits are processed as well as when fits are being saved. + + returns + """ defcodepage = locale.getpreferredencoding() - fitImport = [] + fits = [] for path in paths: if callback: # Pulse wx.CallAfter(callback, "Processing file:\n%s"%path) @@ -786,18 +796,20 @@ class Fit(object): except UnicodeDecodeError: srcString = unicode(srcString, "cp1252") - _, fits = Port.importAuto(srcString, path, callback=callback) - fitImport += fits + _, fitsImport = Port.importAuto(srcString, path, callback=callback) + fits += fitsImport IDs = [] - for i, fit in enumerate(fitImport): + numFits = len(fits) + for i, fit in enumerate(fits): + # Set some more fit attributes and save fit.character = self.character fit.damagePattern = self.pattern fit.targetResists = self.targetResists eos.db.save(fit) IDs.append(fit.ID) if callback: # Pulse - wx.CallAfter(callback, "Saving fit\n%d/%d"%(i+1, len(fitImport))) + wx.CallAfter(callback, "Saving fit\n%d/%d"%(i+1, numFits)) return fits @@ -807,15 +819,8 @@ class Fit(object): fit.character = self.character fit.damagePattern = self.pattern fit.targetResists = self.targetResists - return fits - - def saveImportedFits(self, fits): - IDs = [] - for fit in fits: eos.db.save(fit) - IDs.append(fit.ID) - - return IDs + return fits def checkStates(self, fit, base): changed = False diff --git a/service/port.py b/service/port.py index 800447d19..600cb4bcc 100644 --- a/service/port.py +++ b/service/port.py @@ -365,7 +365,6 @@ class Port(object): fits = [] for i, fitting in enumerate(fittings): - print "fitting" f = Fit() f.name = fitting.getAttribute("name") # Maelstrom