diff --git a/ConnectDialog.py b/ConnectDialog.py index dd03bbfd..8b7f4046 100644 --- a/ConnectDialog.py +++ b/ConnectDialog.py @@ -44,8 +44,8 @@ def __init__(self, parent, id, title, sn="Source", snL=[None,None], tn="Target", L1.append("%s"%_('All')) L2.append("%s"%_('All')) - self._label_source = wx.StaticText(self, wx.NewIdRef(), '%s:'%self.sn) - self._label_target = wx.StaticText(self, wx.NewIdRef(), '%s:'%self.tn) + self._label_source = wx.StaticText(self, wx.NewIdRef(), '%s'%self.sn) + self._label_target = wx.StaticText(self, wx.NewIdRef(), '%s'%self.tn) self._combo_box_sn = wx.ComboBox(self, wx.NewIdRef(), choices = L1, style = wx.CB_DROPDOWN|wx.CB_READONLY|wx.CB_SORT) self._combo_box_tn = wx.ComboBox(self, wx.NewIdRef(), choices = L2, style = wx.CB_DROPDOWN|wx.CB_READONLY|wx.CB_SORT) self._button_disconnect = wx.Button(self, wx.NewIdRef(), _("Disconnect")) diff --git a/Container.py b/Container.py index 416de6b4..0b695500 100644 --- a/Container.py +++ b/Container.py @@ -79,8 +79,6 @@ import pluginmanager import ZipManager import DropTarget - -if builtins.__dict__['GUI_FLAG']: import PlotGUI import SimulationGUI import PriorityGUI @@ -718,9 +716,11 @@ def OnAddConstants(self, event): nb2 = win.GetDiagramNotebook() title = nb2.GetPageText(nb2.GetSelection()) - dlg = DiagramConstantsDialog.DiagramConstantsDialog(win, wx.NewIdRef(), title, self) - dlg.ShowModal() - dlg.Destroy() + dlg = DiagramConstantsDialog.DiagramConstantsDialog(win, wx.NewIdRef(), title) + dlg.Populate(self.constants_dico) + if dlg.ShowModal() == wx.ID_OK: + self.constants_dico = dlg.GetData() + dlg.Destroy() @BuzyCursorNotification def checkDEVSInstance(self, diagram=None, D={}): diff --git a/DSV.py b/DSV.py index e3c1fd1d..ec948970 100644 --- a/DSV.py +++ b/DSV.py @@ -412,8 +412,8 @@ def organizeIntoLines(input, textQualifier = '"', limit = None): break # filter out empty lines - # data = filter(lambda i: "".join(i), data) - data = list(filter(string.join, data)) + data = list(filter(lambda i: "".join(i), data)) + #data = list(filter(string.join, data)) return data # ------------------------------------------------------------------------------ @@ -526,8 +526,8 @@ def importDSV(input, delimiter = ',', textQualifier = '"', columns = 0, else: record.append(accu) else: - #record = map(lambda x: x.strip(), line.split(delimiter)) - record = list(map(string.strip, line.split(delimiter))) + record = list(map(lambda x: x.strip(), line.split(delimiter))) + #record = list(map(string.strip, line.split(delimiter))) newdata.append(record) # (end of replacement code) @@ -638,7 +638,7 @@ def __init__(self, parent, id, file, data, isValidCallback = None, style = wx.TAB_TRAVERSAL, name = "ImportWizardPanel"): wx.Panel.__init__(self, parent, id, pos, size, style, name) self.SetAutoLayout(True) - mainSizer = wx.FlexGridSizer(3, 1) + mainSizer = wx.FlexGridSizer(4, 1, gap=wx.Size(0,0)) self.SetSizer(mainSizer) mainSizer.AddGrowableCol(0) @@ -669,7 +669,7 @@ def __init__(self, parent, id, file, data, isValidCallback = None, delimiterBox = wx.BoxSizer(wx.HORIZONTAL) delimStaticBox = wx.StaticBox(self, -1, _("Delimiters")) delimStaticSizer = wx.StaticBoxSizer(delimStaticBox, wx.VERTICAL) - delimGridSizer = wx.FlexGridSizer(2, 3) + delimGridSizer = wx.FlexGridSizer(2, 3, gap=wx.Size(0,0)) delims = { _('Tab'): '\t', @@ -802,7 +802,7 @@ def __init__(self, parent, id, file, data, isValidCallback = None, (message1, 0, wx.ALL, 5), (delimiterBox, 0, wx.ALL, 5), (previewSettingsBox, 0, wx.ALL, 5), - (previewStaticSizer, 0, wx.ALL | wx.EXPAND, 5), + (previewStaticSizer, 0, wx.ALL | wx.EXPAND, 5) ]) self.Layout() diff --git a/DiagramConstantsDialog.py b/DiagramConstantsDialog.py index 589beb6f..98cdb058 100644 --- a/DiagramConstantsDialog.py +++ b/DiagramConstantsDialog.py @@ -7,19 +7,31 @@ import csv import DSV -_ = wx.GetTranslation +ID_IMPORT = wx.NewIdRef() +ID_EXPORT = wx.NewIdRef() +ID_ADD = wx.NewIdRef() +ID_REMOVE = wx.NewIdRef() +ID_HELP = wx.NewIdRef() -class DiagramConstantsDialog(wx.Dialog): +import gettext +_ = gettext.gettext - def __init__(self, parent, id, title, model): - """ Constructor - """ +class DiagramConstantsDialog(wx.Dialog): - wx.Dialog.__init__(self, parent, id, title, wx.DefaultPosition, (400, 380), style=wx.DEFAULT_FRAME_STYLE|wx.NO_FULL_REPAINT_ON_RESIZE) + def __init__(self, *args, **kw): + super(DiagramConstantsDialog, self).__init__(*args, **kw) ### local copy - self.model = model - self.label = title + self.label = args[2] + + ### all of the constants + self.data = {} + + self.InitUI() + + def InitUI(self): + """ Init the user interface + """ self.SetTitle(_("%s - Constants Manager")%(self.label)) @@ -27,88 +39,93 @@ def __init__(self, parent, id, title, model): icon.CopyFromBitmap(wx.Bitmap(os.path.join(ICON_PATH_16_16, "properties.png"), wx.BITMAP_TYPE_ANY)) self.SetIcon(icon) - self._panel = wx.Panel(self, wx.NewIdRef()) + panel = wx.Panel(self) + vbox = wx.BoxSizer(wx.VERTICAL) + + ### Add a toolbar in order to add, delete, import, export and have help on the user of constant. + tb = wx.ToolBar(panel) + vbox.Add(tb, 0, wx.EXPAND) + + tb.SetToolBitmapSize((16,16)) + + tb.AddTool(ID_ADD, "", wx.Bitmap(os.path.join(ICON_PATH,'comment_add.png')), shortHelp=_('New constant')) + tb.AddTool(ID_REMOVE, "", wx.Bitmap(os.path.join(ICON_PATH,'comment_remove.png')), shortHelp=_('Delete constant')) + tb.AddTool(ID_EXPORT, "", wx.Bitmap(os.path.join(ICON_PATH,'export.png')), shortHelp=_('Export constants into file')) + tb.AddTool(ID_IMPORT, "", wx.Bitmap(os.path.join(ICON_PATH,'import.png')), wx.NullBitmap, shortHelp=_('Import constants from file')) + tb.AddTool(ID_HELP, "", wx.Bitmap(os.path.join(ICON_PATH,'info.png')), wx.NullBitmap, shortHelp=_('Help')) - grid_sizer_1 = wx.GridSizer(1, 2, 0, 0) + tb.Realize() - self._grid = wx.grid.Grid(self._panel, wx.NewIdRef(), size=(200, 100)) + self._grid = wx.grid.Grid(panel) self._grid.AutoSizeColumns(True) self._grid.CreateGrid(1, 2) self._grid.SetColLabelValue(0, _("Name")) - self._grid.SetColSize(0, 100) + self._grid.SetColSize(0, 200) self._grid.SetColLabelValue(1, _("Value")) - self._grid.SetColSize(1, 100) - ### The label windows will still exist, but they will not be visible. - - # constants loading - D = self.model.constants_dico if self.model else {} - - row = 0 - self._grid.DeleteRows(0) - for key in D: - self._grid.AppendRows() - self._grid.SetCellValue(row, 0, key) - self._grid.SetCellValue(row, 1, str(D[key])) - row += 1 - - grid_sizer_1.Add(self._grid, 1, wx.EXPAND|wx.ALL, 0) - - self._panel.SetSizer(grid_sizer_1) - - self._button_add = wx.Button(self._panel, wx.ID_ADD, "") - self._button_remove = wx.Button(self._panel, wx.ID_REMOVE, "") - self._button_help = wx.Button(self._panel, wx.ID_HELP, "") - - grid_sizer_3 = wx.GridSizer(3, 1, 0, 0) - grid_sizer_3.Add(self._button_add, 0, wx.EXPAND|wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL, 0) - grid_sizer_3.Add(self._button_remove, 0, wx.EXPAND|wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL, 0) - grid_sizer_3.Add((-1,50), 0, wx.EXPAND|wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL, 0) - - self._button_import = wx.Button(self._panel, wx.NewIdRef(), _("Import")) - self._button_export = wx.Button(self._panel, wx.NewIdRef(), _("Export")) - self._button_import.SetDefault() - - sizer_2 = wx.BoxSizer(wx.VERTICAL) - sizer_2.Add(self._button_import, 0, wx.EXPAND|wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL|wx.ADJUST_MINSIZE, 0) - sizer_2.Add(self._button_export, 0, wx.EXPAND|wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL|wx.ADJUST_MINSIZE, 0) - sizer_2.Add(self._button_help, 0, wx.EXPAND|wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL|wx.ADJUST_MINSIZE, 0) - - sizer_1 = wx.BoxSizer(wx.VERTICAL) - sizer_1.Add(grid_sizer_3, 1, wx.EXPAND, 0) - sizer_1.Add(sizer_2, 1, wx.EXPAND, 0) - - grid_sizer_1.Add(sizer_1, 1, wx.EXPAND, 0) - - self._button_cancel = wx.Button(self._panel, wx.ID_CANCEL, "") - self._button_ok = wx.Button(self._panel, wx.ID_OK, "") - - grid_sizer_2 = wx.GridSizer(1, 2, 0, 0) - grid_sizer_2.Add(self._button_cancel, 0, wx.ALIGN_BOTTOM|wx.ALIGN_CENTER_HORIZONTAL|wx.ADJUST_MINSIZE, 0) - grid_sizer_2.Add(self._button_ok, 0, wx.ALIGN_BOTTOM|wx.ALIGN_CENTER_HORIZONTAL|wx.ADJUST_MINSIZE, 0) - - sizer_1.Add(grid_sizer_2, 1, wx.EXPAND, 0) - - self._panel.SetSizer(grid_sizer_1) + self._grid.SetColSize(1, 200) + + ### label column is not visible + self._grid.SetRowLabelSize(0) + + vbox.Add(self._grid, 1, wx.EXPAND|wx.ALL,0) + + vbox.Add((-1, 15)) + + self._button_ok = wx.Button(panel, wx.ID_OK, size=(70, 30)) + self._button_cancel = wx.Button(panel, wx.ID_CANCEL, size=(70, 30)) + + hbox = wx.BoxSizer(wx.HORIZONTAL) + hbox.Add(self._button_cancel) + hbox.Add(self._button_ok, flag=wx.LEFT|wx.BOTTOM, border=5) + + vbox.Add(hbox, 0, flag=wx.ALIGN_BOTTOM|wx.ALIGN_CENTER_HORIZONTAL|wx.ADJUST_MINSIZE, border=10) + +# From http://docs.wxwidgets.org/trunk/overview_windowsizing.html, wxWidgets provides two main methods for sizing: +# +# Fit() sets the size of a window to fit around its children. +# The size of each children is added and then this parent window changes its size to fit them all. +# Layout() the opposite. The children will change their size, according to sizer rules, so they can fit into available space of their parent. +# [...] is what is called by the default EVT_SIZE handler for container windows + +# Because a grid can have thousands of rows/cols its size can be huge. +# Don't try to tell the parent to fit around it. +# You better set max and min sizes for the grid (or its sizer) and then use Fit() or Layout() each time you change number of rows/cols or their sizes. + + panel.SetSizerAndFit(vbox) + #self.SetAutoLayout(True) + #self.Fit() self.__set_events() ### just for windows - e = wx.SizeEvent(self.GetSize()) - self.ProcessEvent(e) +# e = wx.SizeEvent(self.GetSize()) +# self.ProcessEvent(e) self.Center() def __set_events(self): """ Binding """ - self.Bind(wx.EVT_BUTTON, self.OnAdd, self._button_add) - self.Bind(wx.EVT_BUTTON, self.OnRemove, self._button_remove) - self.Bind(wx.EVT_BUTTON, self.OnExport, self._button_export) - self.Bind(wx.EVT_BUTTON, self.OnImport, self._button_import) - self.Bind(wx.EVT_BUTTON, self.OnHelp, self._button_help) + self.Bind(wx.EVT_TOOL, self.OnAdd, id=ID_ADD) + self.Bind(wx.EVT_TOOL, self.OnRemove, id=ID_REMOVE) + self.Bind(wx.EVT_TOOL, self.OnExport, id=ID_EXPORT) + self.Bind(wx.EVT_TOOL, self.OnImport, id=ID_IMPORT) + self.Bind(wx.EVT_TOOL, self.OnHelp, id=ID_HELP) self.Bind(wx.EVT_BUTTON, self.OnOk, self._button_ok) self.Bind(wx.EVT_BUTTON, self.OnCancel, self._button_cancel) + def Populate(self, data): + """ Populate the grid from a dictionary data + """ + + ### populate the grid + if data != {}: + self._grid.DeleteRows(0) + for i,key in enumerate(data): + self._grid.AppendRows() + self._grid.SetCellValue(i, 0, key) + self._grid.SetCellValue(i, 1, str(data[key])) + def OnAdd(self,evt): """ Add line """ @@ -118,8 +135,22 @@ def OnRemove(self, evt): """ Delete selected lines """ - for row in self._grid.GetSelectedRows(): - self._grid.DeleteRows(row) + ### only if the grid has rows + if self._grid.GetNumberRows(): + try: + ### only possible solution to have correct selected rows! + i = self._grid.GetSelectionBlockTopLeft()[0][0] + j = self._grid.GetSelectionBlockBottomRight()[0][0] + + if i == j: + self._grid.DeleteRows(i) + else: + self._grid.DeleteRows(i,j) + + ### no cells have been selected. We delete the current row according to the current position of the cursor. + except: + row = self._grid.GetGridCursorRow() + self._grid.DeleteRows(row) def OnImport(self, event): """ csv file importing @@ -144,14 +175,20 @@ def logErrors(oldrow, newrow, expectedColumns, maxColumns, file = errorLog): errorLog.close() if results != None: - # delete first row - self._grid.DeleteRows(0) + + dial = wx.MessageDialog(self, _('Do you want to clear the current values before importing?'), _('Import Manager'), wx.YES_NO | wx.NO_DEFAULT | wx.ICON_QUESTION) + if dial.ShowModal() == wx.ID_YES: + # delete rows + self._grid.DeleteRows(0,self._grid.GetNumberRows()) + dial.Destroy() + + nbRows=self._grid.GetNumberRows() # import data to the grid for (row,data) in zip(list(range(len(results[1]))),results[1]): self._grid.AppendRows() - self._grid.SetCellValue(row,0,data[0]) - self._grid.SetCellValue(row,1,str(data[1])) - dial = wx.MessageDialog(self, _('Import completed'), _('Import Manager'), wx.OK|wx.ICON_INFORMATION) + self._grid.SetCellValue(row+nbRows,0,data[0]) + self._grid.SetCellValue(row+nbRows,1,str(data[1])) + dial = wx.MessageDialog(self, _('Import completed!'), _('Import Manager'), wx.OK|wx.ICON_INFORMATION) dial.ShowModal() else: dlg.Destroy() @@ -184,26 +221,29 @@ def OnExport(self,evt): def OnOk(self,evt): """ Defintion of constantes in builtin and close dialog """ - D={} + for row in range(self._grid.GetNumberRows()): const=self._grid.GetCellValue(row,0) val= self._grid.GetCellValue(row,1) if val != '': if type(val) in [float, int]: - D[const]=float(val) + self.data[const]=float(val) elif type(val) in [str, str]: - D[const]=val + self.data[const]=val else: pass - if D != {}: - builtins.__dict__[os.path.splitext(self.label)[0]]=D + if self.data != {}: + builtins.__dict__[os.path.splitext(self.label)[0]] = self.data elif os.path.splitext(self.label)[0] in builtins.__dict__: del builtins.__dict__[os.path.splitext(self.label)[0]] - self.model.constants_dico = D + evt.Skip() - self.Destroy() + def GetData(self): + """ Return the constants stored in the grid as a dictionnary + """ + return self.data def OnCancel(self,evt): """ Close dialog @@ -221,19 +261,18 @@ class TestApp(wx.App): def OnInit(self): - import gettext - builtins.__dict__['ICON_PATH_16_16']=os.path.join('icons','16x16') + builtins.__dict__['ICON_PATH']=os.path.join('icons') builtins.__dict__['_'] = gettext.gettext - self.frame = DiagramConstantsDialog(None, -1, title="Model", model=None) - self.frame.Show() + frame = DiagramConstantsDialog(None, -1, "Model") + frame.Populate({'a':1, 'b':2, 'c':3}) + frame.Show() return True def OnQuit(self, event): self.Close() if __name__ == '__main__': - app = TestApp(0) app.MainLoop() \ No newline at end of file diff --git a/Reporter.py b/Reporter.py index 8f4dc726..573d5091 100644 --- a/Reporter.py +++ b/Reporter.py @@ -162,6 +162,7 @@ def GetLastError(self): """ if len(self._sessionerr): return self._sessionerr[-1] + class ErrorDialog(BaseDialog): """ Dialog for showing errors and and notifying gui2exe-users should the @@ -173,6 +174,7 @@ class ErrorDialog(BaseDialog): """ ABORT = False REPORTER_ACTIVE = False + def __init__(self, message): """ Initialize the dialog @@ -200,7 +202,7 @@ def __init__(self, message): str(ErrorReporter().GetErrorStack()), \ "---- End Traceback Info ----") - self.textCtrl = wx.TextCtrl(self, value=self.err_msg, style=wx.TE_MULTILINE | wx.TE_READONLY) + self.textCtrl = wx.TextCtrl(self, value=self.err_msg, size=(-1,200),style=wx.TE_MULTILINE | wx.TE_READONLY) self.abortButton = wx.Button(self, wx.ID_CANCEL, size=(-1, 26)) self.sendButton = wx.Button(self, ID_SEND, _("Report Error"), size=(-1, 26)) self.sendButton.SetDefault() @@ -217,7 +219,6 @@ def __init__(self, message): self.CenterOnParent() self.ShowModal() - def DoLayout(self): """ Layout the dialog and prepare it to be shown @@ -230,10 +231,10 @@ def DoLayout(self): # Objects mainmsg = wx.StaticText(self, - label=_("Error: Help improve DEVSimPy by clicking on " + label=_("Help improve DEVSimPy by clicking on " "Report Error\nto send the Error " "Traceback shown below.")) - t_lbl = wx.StaticText(self, label=_(" Error Traceback:")) + t_lbl = wx.StaticText(self, label=_("Error Traceback:")) t_lbl.SetFont(wx.Font(8, wx.SWISS, wx.NORMAL, wx.BOLD, False)) # Layout @@ -246,7 +247,7 @@ def DoLayout(self): mainSizer.Add(topSizer, 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 20) mainSizer.Add(t_lbl, 0, wx.LEFT|wx.TOP|wx.RIGHT, 5) mainSizer.Add((0, 2)) - mainSizer.Add(self.textCtrl, 1, wx.EXPAND|wx.LEFT|wx.BOTTOM|wx.RIGHT, 5) + mainSizer.Add(self.textCtrl, 1, wx.EXPAND|wx.ALL, 5) bottomSizer.Add(self.abortButton, 0, wx.ALL, 5) bottomSizer.Add((0, 0), 1, wx.EXPAND) bottomSizer.Add(self.sendButton, 0, wx.TOP|wx.BOTTOM, 5) @@ -254,12 +255,10 @@ def DoLayout(self): bottomSizer.Add(self.closeButton, 0, wx.TOP|wx.BOTTOM|wx.RIGHT, 5) mainSizer.Add(bottomSizer, 0, wx.EXPAND) - self.SetSizer(mainSizer) - mainSizer.Layout() - + self.SetSizerAndFit(mainSizer) + self.SetAutoLayout(True) self.Fit() - def OnButton(self, evt): """Handles button events @@ -276,6 +275,7 @@ def OnButton(self, evt): e_id = evt.GetId() if e_id == wx.ID_CLOSE: self.Close() + elif e_id == ID_SEND: frame = SendMailWx(None) msg = self.err_msg @@ -286,6 +286,7 @@ def OnButton(self, evt): frame.subjectTxt.SetValue(msg) frame.Show() self.Close() + elif e_id == wx.ID_ABORT: ErrorDialog.ABORT = True # Try a nice shutdown first time through @@ -293,6 +294,7 @@ def OnButton(self, evt): wx.MenuEvent(wx.wxEVT_MENU_OPEN, wx.ID_EXIT), True) self.Close() + else: evt.Skip() diff --git a/devsimpy.py b/devsimpy.py index 96443ccb..08bc7c03 100644 --- a/devsimpy.py +++ b/devsimpy.py @@ -781,12 +781,35 @@ def OnDeleteRecentFiles(self, event): """ Delete the recent files list """ - # update openFileList variable - self.openFileList = ['']*NB_OPENED_FILE + dial = wx.MessageDialog(self, _('Do you want to clear the list of recent opened files?'), 'Clean Recent Opened Files List', wx.YES_NO | wx.NO_DEFAULT | wx.ICON_QUESTION) + + ### if local editor + if dial.ShowModal() == wx.ID_YES: + # update openFileList variable + self.openFileList = ['']*NB_OPENED_FILE - # update config file - self.cfg.Write("openFileList", str(eval("self.openFileList"))) - self.cfg.Flush() + # update config file + self.cfg.Write("openFileList", str(eval("self.openFileList"))) + self.cfg.Flush() + + notify = wx.adv.NotificationMessage( + title="Information", + message="Recent opened files list has been deleted!", + parent=self, flags=wx.ICON_INFORMATION) + + # Various options can be set after the message is created if desired. + # notify.SetFlags(# wx.ICON_INFORMATION + # wx.ICON_WARNING + # # wx.ICON_ERROR + # ) + # notify.SetTitle("Wooot") + # notify.SetMessage("It's a message!") + # notify.SetParent(self) + + notify.Show(timeout=5) # 1 for short timeout, 100 for long timeout + # notify.Close() # Hides the notification. + + dial.Destroy() def OnCreatePerspective(self, event): """ diff --git a/pluginmanager.py b/pluginmanager.py index f491e8fb..c91a66b4 100644 --- a/pluginmanager.py +++ b/pluginmanager.py @@ -10,6 +10,9 @@ import os import importlib +import gettext +_ = gettext.gettext + # list of registred plug-ins plugins = defaultdict(list) # list of enable/disable event plug-in