def Init(self, name=None, appname=""): """Method called after the panel has been initialized.""" # Hide the close button on Mac if guiutil.IsMac(): XRCCTRL(self, 'wxID_OK').Hide() # Set window icon else: self.SetIcon(guiutil.get_icon()) # Set the dialog title if name: self.SetTitle(name) # Initialize controls self.notebook = XRCCTRL(self, 'notebook') # Modify the control and font size on Mac for child in self.GetChildren(): guiutil.adjust_control(child) # Bind ui events to the proper methods self.Bind(wx.EVT_CLOSE, self.OnClose) self.Bind(wx.EVT_WINDOW_DESTROY, self.OnClose) wx.EVT_BUTTON(self, XRCID('wxID_OK'), self.OnClose) # Initialize variables self.preftemplate = [] self.values = {} self.appname = appname
def Init(self, name = None, appname = ""): """Method called after the panel has been initialized.""" # Hide the close button on Mac if guiutil.IsMac(): XRCCTRL(self, 'wxID_OK').Hide() # Set window icon else: self.SetIcon(guiutil.get_icon()) # Set the dialog title if name: self.SetTitle(name) # Initialize controls self.notebook = XRCCTRL(self, 'notebook') # Modify the control and font size on Mac for child in self.GetChildren(): guiutil.adjust_control(child) # Bind ui events to the proper methods self.Bind(wx.EVT_CLOSE, self.OnClose) self.Bind(wx.EVT_WINDOW_DESTROY, self.OnClose) wx.EVT_BUTTON(self, XRCID('wxID_OK'), self.OnClose) # Initialize variables self.preftemplate = [] self.values = {} self.appname = appname
def Init(self, plugins, pluginsDisabled): """Method called after the panel has been initialized.""" # Set window icon if not guiutil.IsMac(): self.SetIcon(guiutil.get_icon()) # Initialize controls self.tcPlugins = XRCCTRL(self, 'tcPlugins') self.panelTreeView = XRCCTRL(self, 'panelTreeView') self.panelProperties = XRCCTRL(self, 'panelProperties') self.lblName = XRCCTRL(self, 'lblName') self.lblAuthor = XRCCTRL(self, 'lblAuthor') self.lblPluginType = XRCCTRL(self, 'lblPluginType') self.lblVersion = XRCCTRL(self, 'lblVersion') self.lblVersionNumber = XRCCTRL(self, 'lblVersionNumber') self.lblDescription = XRCCTRL(self, 'lblDescription') self.checkEnabled = XRCCTRL(self, 'checkEnabled') self.lblMessage = XRCCTRL(self, 'lblMessage') self.btnGetMorePlugins = XRCCTRL(self, 'btnGetMorePlugins') self.btnDeletePlugin = XRCCTRL(self, 'btnDeletePlugin') self.plugins = plugins self.pluginsDisabled = set(pluginsDisabled) # Bind interface events to the proper methods # wx.EVT_BUTTON(self, XRCID('btnDeletePlugin'), self.DeletePlugin) # wx.EVT_CHECKBOX(self, XRCID('checkEnabled'), self.OnEnablePlugin) self.Bind(wx.EVT_CHECKBOX, self.OnEnablePlugin, id=XRCID('checkEnabled')) # wx.EVT_TREE_ITEM_ACTIVATED(self, XRCID('tcPlugins'), self.OnEnablePlugin) self.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.OnEnablePlugin, id=XRCID('tcPlugins')) # wx.EVT_TREE_SEL_CHANGED(self, XRCID('tcPlugins'), self.OnSelectTreeItem) self.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnSelectTreeItem, id=XRCID('tcPlugins')) # wx.EVT_TREE_SEL_CHANGING(self, XRCID('tcPlugins'), self.OnSelectRootItem) self.Bind(wx.EVT_TREE_SEL_CHANGING, self.OnSelectRootItem, id=XRCID('tcPlugins')) # Modify the control and font size as needed font = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT) if guiutil.IsMac(): children = list(self.Children) + \ list(self.panelTreeView.Children) + \ list(self.panelProperties.Children) for control in children: control.SetFont(font) control.SetWindowVariant(wx.WINDOW_VARIANT_SMALL) XRCCTRL(self, 'wxID_OK').SetWindowVariant(wx.WINDOW_VARIANT_NORMAL) font.SetWeight(wx.FONTWEIGHT_BOLD) if guiutil.IsMSWindows(): self.tcPlugins.SetPosition((0, 3)) self.panelTreeView.SetWindowStyle(wx.STATIC_BORDER) if (guiutil.IsMac() or guiutil.IsGtk()): self.tcPlugins.SetPosition((-30, 0)) self.panelTreeView.SetWindowStyle(wx.SUNKEN_BORDER) self.lblName.SetFont(font) self.lblMessage.SetFont(font) self.Layout() self.InitPluginList() self.LoadPlugins()
def Init(self, plugins, pluginsDisabled): """Method called after the panel has been initialized.""" # Set window icon if not guiutil.IsMac(): self.SetIcon(guiutil.get_icon()) # Initialize controls self.tcPlugins = XRCCTRL(self, 'tcPlugins') self.panelTreeView = XRCCTRL(self, 'panelTreeView') self.panelProperties = XRCCTRL(self, 'panelProperties') self.lblName = XRCCTRL(self, 'lblName') self.lblAuthor = XRCCTRL(self, 'lblAuthor') self.lblPluginType = XRCCTRL(self, 'lblPluginType') self.lblVersion = XRCCTRL(self, 'lblVersion') self.lblVersionNumber = XRCCTRL(self, 'lblVersionNumber') self.lblDescription = XRCCTRL(self, 'lblDescription') self.checkEnabled = XRCCTRL(self, 'checkEnabled') self.lblMessage = XRCCTRL(self, 'lblMessage') self.btnGetMorePlugins = XRCCTRL(self, 'btnGetMorePlugins') self.btnDeletePlugin = XRCCTRL(self, 'btnDeletePlugin') self.plugins = plugins self.pluginsDisabled = set(pluginsDisabled) # Bind interface events to the proper methods # wx.EVT_BUTTON(self, XRCID('btnDeletePlugin'), self.DeletePlugin) wx.EVT_CHECKBOX(self, XRCID('checkEnabled'), self.OnEnablePlugin) wx.EVT_TREE_ITEM_ACTIVATED(self, XRCID('tcPlugins'), self.OnEnablePlugin) wx.EVT_TREE_SEL_CHANGED(self, XRCID('tcPlugins'), self.OnSelectTreeItem) wx.EVT_TREE_SEL_CHANGING(self, XRCID('tcPlugins'), self.OnSelectRootItem) # Modify the control and font size as needed font = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT) if guiutil.IsMac(): children = list(self.Children) + \ list(self.panelTreeView.Children) + \ list(self.panelProperties.Children) for control in children: control.SetFont(font) control.SetWindowVariant(wx.WINDOW_VARIANT_SMALL) XRCCTRL(self, 'wxID_OK').SetWindowVariant(wx.WINDOW_VARIANT_NORMAL) font.SetWeight(wx.FONTWEIGHT_BOLD) if guiutil.IsMSWindows(): self.tcPlugins.SetPosition((0, 3)) self.panelTreeView.SetWindowStyle(wx.STATIC_BORDER) if (guiutil.IsMac() or guiutil.IsGtk()): self.tcPlugins.SetPosition((-30, 0)) self.panelTreeView.SetWindowStyle(wx.SUNKEN_BORDER) self.lblName.SetFont(font) self.lblMessage.SetFont(font) self.Layout() self.InitPluginList() self.LoadPlugins()
def Init(self): """Method called after the dialog has been initialized.""" # Set window icon if not guiutil.IsMac(): self.SetIcon(guiutil.get_icon()) # Initialize controls self.txtDICOMFolder = XRCCTRL(self, 'txtDICOMFolder') self.checkPatientName = XRCCTRL(self, 'checkPatientName') self.txtFirstName = XRCCTRL(self, 'txtFirstName') self.txtLastName = XRCCTRL(self, 'txtLastName') self.checkPatientID = XRCCTRL(self, 'checkPatientID') self.txtPatientID = XRCCTRL(self, 'txtPatientID') self.checkPrivateTags = XRCCTRL(self, 'checkPrivateTags') self.bmpError = XRCCTRL(self, 'bmpError') self.lblDescription = XRCCTRL(self, 'lblDescription') # Bind interface events to the proper methods wx.EVT_BUTTON(self, XRCID('btnFolderBrowse'), self.OnFolderBrowse) wx.EVT_CHECKBOX(self, XRCID('checkPatientName'), self.OnCheckPatientName) wx.EVT_CHECKBOX(self, XRCID('checkPatientID'), self.OnCheckPatientID) wx.EVT_BUTTON(self, wx.ID_OK, self.OnOK) # Set and bold the font of the description label if guiutil.IsMac(): font = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT) font.SetWeight(wx.FONTWEIGHT_BOLD) self.lblDescription.SetFont(font) # Initialize the import location via pubsub pub.subscribe(self.OnImportPrefsChange, 'general.dicom.import_location') pub.sendMessage('preferences.requested.value', 'general.dicom.import_location') # Pre-select the text on the text controls due to a Mac OS X bug self.txtFirstName.SetSelection(-1, -1) self.txtLastName.SetSelection(-1, -1) self.txtPatientID.SetSelection(-1, -1) # Load the error bitmap self.bmpError.SetBitmap(wx.Bitmap(util.GetResourcePath('error.png'))) # Initialize variables self.name = self.txtLastName.GetValue( ) + '^' + self.txtFirstName.GetValue() self.patientid = self.txtPatientID.GetValue() self.privatetags = True
def Init(self): """Method called after the dialog has been initialized.""" # Set window icon if not guiutil.IsMac(): self.SetIcon(guiutil.get_icon()) # Initialize controls self.txtDICOMFolder = XRCCTRL(self, 'txtDICOMFolder') self.checkPatientName = XRCCTRL(self, 'checkPatientName') self.txtFirstName = XRCCTRL(self, 'txtFirstName') self.txtLastName = XRCCTRL(self, 'txtLastName') self.checkPatientID = XRCCTRL(self, 'checkPatientID') self.txtPatientID = XRCCTRL(self, 'txtPatientID') self.checkPrivateTags = XRCCTRL(self, 'checkPrivateTags') self.bmpError = XRCCTRL(self, 'bmpError') self.lblDescription = XRCCTRL(self, 'lblDescription') # Bind interface events to the proper methods wx.EVT_BUTTON(self, XRCID('btnFolderBrowse'), self.OnFolderBrowse) wx.EVT_CHECKBOX(self, XRCID('checkPatientName'), self.OnCheckPatientName) wx.EVT_CHECKBOX(self, XRCID('checkPatientID'), self.OnCheckPatientID) wx.EVT_BUTTON(self, wx.ID_OK, self.OnOK) # Set and bold the font of the description label if guiutil.IsMac(): font = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT) font.SetWeight(wx.FONTWEIGHT_BOLD) self.lblDescription.SetFont(font) # Initialize the import location via pubsub pub.subscribe(self.OnImportPrefsChange, 'general.dicom.import_location') pub.sendMessage('preferences.requested.value', 'general.dicom.import_location') # Pre-select the text on the text controls due to a Mac OS X bug self.txtFirstName.SetSelection(-1, -1) self.txtLastName.SetSelection(-1, -1) self.txtPatientID.SetSelection(-1, -1) # Load the error bitmap self.bmpError.SetBitmap(wx.Bitmap(util.GetResourcePath('error.png'))) # Initialize variables self.name = self.txtLastName.GetValue() + '^' + self.txtFirstName.GetValue() self.patientid = self.txtPatientID.GetValue() self.privatetags = True
def Init(self, plugins): """Method called after the panel has been initialized.""" # Set window icon if not guiutil.IsMac(): self.SetIcon(guiutil.get_icon()) # Initialize controls self.lcPlugins = XRCCTRL(self, 'lcPlugins') self.btnGetMorePlugins = XRCCTRL(self, 'btnGetMorePlugins') self.btnDeletePlugin = XRCCTRL(self, 'btnDeletePlugin') self.plugins = plugins # Bind interface events to the proper methods # wx.EVT_BUTTON(self, XRCID('btnDeletePlugin'), self.DeletePlugin) self.InitPluginList() self.LoadPlugins()
def Init(self, rxdose): """Method called after the dialog has been initialized.""" # Set window icon if not guiutil.IsMac(): self.SetIcon(guiutil.get_icon()) # Initialize controls self.txtOriginalRxDose = XRCCTRL(self, 'txtOriginalRxDose') self.txtNewRxDose = XRCCTRL(self, 'txtNewRxDose') # Bind interface events to the proper methods wx.EVT_BUTTON(self, wx.ID_OK, self.OnOK) # Pre-select the text on the text controls due to a Mac OS X bug self.txtOriginalRxDose.SetSelection(-1, -1) self.txtNewRxDose.SetSelection(-1, -1) # Initialize variables self.txtOriginalRxDose.SetValue(str(int(rxdose))) self.txtNewRxDose.SetValue(str(int(rxdose) / 2))
def Init(self, rxdose): """Method called after the dialog has been initialized.""" # Set window icon if not guiutil.IsMac(): self.SetIcon(guiutil.get_icon()) # Initialize controls self.txtOriginalRxDose = XRCCTRL(self, 'txtOriginalRxDose') self.txtNewRxDose = XRCCTRL(self, 'txtNewRxDose') # Bind interface events to the proper methods wx.EVT_BUTTON(self, wx.ID_OK, self.OnOK) # Pre-select the text on the text controls due to a Mac OS X bug self.txtOriginalRxDose.SetSelection(-1, -1) self.txtNewRxDose.SetSelection(-1, -1) # Initialize variables self.txtOriginalRxDose.SetValue(str(int(rxdose))) self.txtNewRxDose.SetValue(str(int(rxdose)/2))
def __init__(self, parent, id, title, res): # Initialize logging logger = logging.getLogger('dicompyler') # Configure the exception hook to process threads as well self.InstallThreadExcepthook() # Remap the exception hook so that we can log and display exceptions def LogExcepthook(*exc_info): # Log the exception text = "".join(traceback.format_exception(*exc_info)) logger.error("Unhandled exception: %s", text) pub.sendMessage('logging.exception', msg=text) sys.excepthook = LogExcepthook # Modify the logging system from pydicom to capture important messages pydicom_logger = logging.getLogger('pydicom') for l in pydicom_logger.handlers: pydicom_logger.removeHandler(l) # Add file logger logpath = os.path.join(guiutil.get_data_dir(), 'logs') if not os.path.exists(logpath): os.makedirs(logpath) self.fh = logging.handlers.RotatingFileHandler(os.path.join( logpath, 'dicompyler.log'), maxBytes=524288, backupCount=7) self.fh.setFormatter( logging.Formatter( '%(asctime)s - %(name)s - %(levelname)s - %(message)s')) self.fh.setLevel(logging.WARNING) logger.addHandler(self.fh) pydicom_logger.addHandler(self.fh) # Add console logger if not frozen if not util.main_is_frozen(): self.ch = logging.StreamHandler() self.ch.setFormatter( logging.Formatter('%(levelname)s: %(message)s')) self.ch.setLevel(logging.WARNING) logger.addHandler(self.ch) pydicom_logger.addHandler(self.ch) # Otherwise if frozen, send stdout/stderror to /dev/null since # logging the messages seems to cause instability due to recursion else: devnull = open(os.devnull, 'w') sys.stdout = devnull sys.stderr = devnull # Set the window size if guiutil.IsMac(): size = (900, 700) else: size = (850, 625) wx.Frame.__init__(self, parent, id, title, pos=wx.DefaultPosition, size=size, style=wx.DEFAULT_FRAME_STYLE) # Set up the status bar self.sb = self.CreateStatusBar(3) # set up resource file and config file self.res = res # Set window icon if not guiutil.IsMac(): self.SetIcon(guiutil.get_icon()) # Load the main panel for the program self.panelGeneral = self.res.LoadPanel(self, 'panelGeneral') # Initialize the General panel controls self.notebook = XRCCTRL(self, 'notebook') self.notebookTools = XRCCTRL(self, 'notebookTools') self.lblPlanName = XRCCTRL(self, 'lblPlanName') self.lblRxDose = XRCCTRL(self, 'lblRxDose') self.lblPatientName = XRCCTRL(self, 'lblPatientName') self.lblPatientID = XRCCTRL(self, 'lblPatientID') self.lblPatientGender = XRCCTRL(self, 'lblPatientGender') self.lblPatientDOB = XRCCTRL(self, 'lblPatientDOB') self.choiceStructure = XRCCTRL(self, 'choiceStructure') self.lblStructureVolume = XRCCTRL(self, 'lblStructureVolume') self.lblStructureMinDose = XRCCTRL(self, 'lblStructureMinDose') self.lblStructureMaxDose = XRCCTRL(self, 'lblStructureMaxDose') self.lblStructureMeanDose = XRCCTRL(self, 'lblStructureMeanDose') self.cclbStructures = guiutil.ColorCheckListBox( self.notebookTools, 'structure') self.cclbIsodoses = guiutil.ColorCheckListBox(self.notebookTools, 'isodose') # Modify the control size on Mac controls = [self.notebookTools, self.choiceStructure] if guiutil.IsMac(): for control in controls: control.SetWindowVariant(wx.WINDOW_VARIANT_SMALL) # Setup the layout for the frame mainGrid = wx.BoxSizer(wx.VERTICAL) hGrid = wx.BoxSizer(wx.HORIZONTAL) if guiutil.IsMac(): hGrid.Add(self.panelGeneral, 1, flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTRE, border=4) else: hGrid.Add(self.panelGeneral, 1, flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTRE) mainGrid.Add(hGrid, 1, flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTRE) # Load the menu for the frame menuMain = self.res.LoadMenuBar('menuMain') # If we are running on Mac OS X, alter the menu location if guiutil.IsMac(): wx.PyApp.SetMacAboutMenuItemId(XRCID('menuAbout')) wx.PyApp.SetMacPreferencesMenuItemId(XRCID('menuPreferences')) wx.PyApp.SetMacExitMenuItemId(XRCID('menuExit')) # Set the menu as the default menu for this frame self.SetMenuBar(menuMain) # Setup Tools menu self.menuShowLogs = menuMain.FindItemById( XRCID('menuShowLogs')).GetMenu() self.menuPlugins = menuMain.FindItemById( XRCID('menuPluginManager')).GetMenu() # Setup Import menu self.menuImport = menuMain.FindItemById( XRCID('menuImportPlaceholder')).GetMenu() self.menuImport.Delete( menuMain.FindItemById(XRCID('menuImportPlaceholder')).GetId()) self.menuImportItem = menuMain.FindItemById(XRCID('menuImport')) self.menuImportItem.Enable(False) # Setup Export menu self.menuExport = menuMain.FindItemById( XRCID('menuExportPlaceholder')).GetMenu() self.menuExport.Delete( menuMain.FindItemById(XRCID('menuExportPlaceholder')).GetId()) self.menuExportItem = menuMain.FindItemById(XRCID('menuExport')) self.menuExportItem.Enable(False) # Bind menu events to the proper methods self.Bind(wx.EVT_MENU, self.OnOpenPatient, id=XRCID('menuOpen')) self.Bind(wx.EVT_MENU, self.OnClose, id=wx.ID_EXIT) self.Bind(wx.EVT_MENU, self.OnPreferences, id=wx.ID_PREFERENCES) self.Bind(wx.EVT_MENU, self.OnShowLogs, id=XRCID('menuShowLogs')) self.Bind(wx.EVT_MENU, self.OnPluginManager, id=XRCID('menuPluginManager')) self.Bind(wx.EVT_MENU, self.OnAbout, id=wx.ID_ABOUT) self.Bind(wx.EVT_MENU, self.OnHomepage, id=XRCID('menuHomepage')) self.Bind(wx.EVT_MENU, self.OnLicense, id=XRCID('menuLicense')) # Load the toolbar for the frame toolbarMain = self.res.LoadToolBar(self, 'toolbarMain') self.SetToolBar(toolbarMain) self.toolbar = self.GetToolBar() # Setup main toolbar controls folderbmp = wx.Bitmap(util.GetResourcePath('folder_user.png')) self.maintools = [{ 'label': "Open Patient", 'bmp': folderbmp, 'shortHelp': "Open Patient...", 'eventhandler': self.OnOpenPatient }] for m, tool in enumerate(self.maintools): self.toolbar.AddTool(m + 1, tool['label'], tool['bmp'], shortHelp=tool['shortHelp']) self.Bind(wx.EVT_TOOL, tool['eventhandler'], id=m + 1) self.toolbar.Realize() # Bind interface events to the proper methods self.Bind(wx.EVT_CHOICE, self.OnStructureSelect, id=XRCID('choiceStructure')) self.Bind(wx.EVT_ACTIVATE, self.OnActivate) self.Bind(wx.EVT_CLOSE, self.OnClose) self.notebook.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, self.OnPageChanged) # Events to work around a focus bug in Windows self.notebook.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self.notebook.Bind(wx.EVT_MOUSEWHEEL, self.OnMouseWheel) self.notebookTools.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self.notebookTools.Bind(wx.EVT_MOUSEWHEEL, self.OnMouseWheel) self.SetSizer(mainGrid) self.Layout() #Set the Minumum size self.SetMinSize(size) self.Centre(wx.BOTH) # Initialize the welcome notebook tab panelWelcome = self.res.LoadPanel(self.notebook, 'panelWelcome') self.notebook.AddPage(panelWelcome, 'Welcome') # Set the version on the welcome notebook tab XRCCTRL(self, 'lblVersion').SetLabel('Version ' + __version__) # Initialize the tools notebook self.notebookTools.AddPage(self.cclbStructures, 'Structures') self.notebookTools.AddPage(self.cclbIsodoses, 'Isodoses') # Create the data folder datapath = guiutil.get_data_dir() if not os.path.exists(datapath): os.mkdir(datapath) # Initialize the preferences if guiutil.IsMac(): self.prefmgr = preferences.PreferencesManager(parent=self, appname='dicompyler') else: self.prefmgr = preferences.PreferencesManager(parent=self, appname='dicompyler', name='Options') sp = wx.StandardPaths.Get() self.generalpreftemplate = [{ 'DICOM Import Settings': [{ 'name': 'Import Location', 'type': 'choice', 'values': ['Remember Last Used', 'Always Use Default'], 'default': 'Remember Last Used', 'callback': 'general.dicom.import_location_setting' }, { 'name': 'Default Location', 'type': 'directory', 'default': sp.GetDocumentsDir(), 'callback': 'general.dicom.import_location' }] }, { 'Plugin Settings': [{ 'name': 'User Plugins Location', 'type': 'directory', 'default': os.path.join(datapath, 'plugins'), 'callback': 'general.plugins.user_plugins_location', 'restart': True }] }, { 'Calculation Settings': [{ 'name': 'DVH Calculation', 'type': 'choice', 'values': ['Use RT Dose DVH if Present', 'Always Recalculate DVH'], 'default': 'Use RT Dose DVH if Present', 'callback': 'general.calculation.dvh_recalc' }] }, { 'Advanced Settings': [{ 'name': 'Enable Detailed Logging', 'type': 'checkbox', 'default': False, 'callback': 'general.advanced.detailed_logging' }] }] self.preftemplate = [{'General': self.generalpreftemplate}] pub.sendMessage('preferences.updated.template', msg=self.preftemplate) # Initialize variables self.ptdata = {} # Set up pubsub pub.subscribe(self.OnLoadPatientData, 'patient.updated.raw_data') pub.subscribe(self.OnStructureCheck, 'colorcheckbox.checked.structure') pub.subscribe(self.OnStructureUncheck, 'colorcheckbox.unchecked.structure') pub.subscribe(self.OnIsodoseCheck, 'colorcheckbox.checked.isodose') pub.subscribe(self.OnIsodoseUncheck, 'colorcheckbox.unchecked.isodose') pub.subscribe(self.OnUpdatePlugins, 'general.plugins.user_plugins_location') pub.subscribe(self.OnUpdatePreferences, 'general') pub.subscribe(self.OnUpdateStatusBar, 'main.update_statusbar') pub.subscribe(self.OnOpenPatient, 'dicomgui.show') # Send a message to the logging system to turn on/off detailed logging pub.sendMessage('preferences.requested.value', msg='general.advanced.detailed_logging') # Create the default user plugin path self.userpluginpath = os.path.join(datapath, 'plugins') if not os.path.exists(self.userpluginpath): os.mkdir(self.userpluginpath) # Load and initialize plugins self.plugins = [] self.pluginsDisabled = [] pub.sendMessage('preferences.requested.value', msg='general.plugins.user_plugins_location') pub.sendMessage('preferences.requested.value', msg='general.calculation.dvh_recalc') pub.sendMessage('preferences.requested.value', msg='general.plugins.disabled_list') pub.sendMessage('preferences.requested.values', msg='general.window')
def Init(self, res): """Method called after the panel has been initialized.""" # Set window icon if not guiutil.IsMac(): self.SetIcon(guiutil.get_icon()) # Initialize controls self.txtDicomImport = XRCCTRL(self, 'txtDicomImport') self.btnDicomImport = XRCCTRL(self, 'btnDicomImport') self.checkSearchSubfolders = XRCCTRL(self, 'checkSearchSubfolders') self.lblDirections = XRCCTRL(self, 'lblDirections') self.lblDirections2 = XRCCTRL(self, 'lblDirections2') self.lblProgressLabel = XRCCTRL(self, 'lblProgressLabel') self.lblProgress = XRCCTRL(self, 'lblProgress') self.gaugeProgress = XRCCTRL(self, 'gaugeProgress') self.lblProgressPercent = XRCCTRL(self, 'lblProgressPercent') self.lblProgressPercentSym = XRCCTRL(self, 'lblProgressPercentSym') self.tcPatients = XRCCTRL(self, 'tcPatients') self.bmpRxDose = XRCCTRL(self, 'bmpRxDose') self.lblRxDose = XRCCTRL(self, 'lblRxDose') self.txtRxDose = XRCCTRL(self, 'txtRxDose') self.lblRxDoseUnits = XRCCTRL(self, 'lblRxDoseUnits') self.btnSelect = XRCCTRL(self, 'wxID_OK') # Bind interface events to the proper methods wx.EVT_BUTTON(self, XRCID('btnDicomImport'), self.OnBrowseDicomImport) wx.EVT_CHECKBOX(self, XRCID('checkSearchSubfolders'), self.OnCheckSearchSubfolders) wx.EVT_TREE_SEL_CHANGED(self, XRCID('tcPatients'), self.OnSelectTreeItem) wx.EVT_TREE_ITEM_ACTIVATED(self, XRCID('tcPatients'), self.OnOK) wx.EVT_BUTTON(self, wx.ID_OK, self.OnOK) wx.EVT_BUTTON(self, wx.ID_CANCEL, self.OnCancel) # Set the dialog font and bold the font of the directions label font = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT) if guiutil.IsMac(): self.txtDicomImport.SetFont(font) self.btnDicomImport.SetFont(font) self.checkSearchSubfolders.SetFont(font) self.lblDirections.SetFont(font) self.lblDirections2.SetFont(font) self.lblProgressLabel.SetFont(font) self.lblProgress.SetFont(font) self.lblProgressPercent.SetFont(font) self.lblProgressPercentSym.SetFont(font) self.tcPatients.SetFont(font) self.txtRxDose.SetFont(font) self.lblRxDoseUnits.SetFont(font) font.SetWeight(wx.FONTWEIGHT_BOLD) self.lblDirections2.SetFont(font) self.lblRxDose.SetFont(font) # Initialize the patients tree control self.root = self.InitTree() # Initialize the patients dictionary self.patients = {} # Initialize the import location via pubsub pub.subscribe(self.OnImportPrefsChange, 'general.dicom') pub.sendMessage('preferences.requested.values', 'general.dicom') # Search subfolders by default self.import_search_subfolders = True # Set the threading termination status to false intially self.terminate = False # Hide the progress bar until it needs to be shown self.gaugeProgress.Show(False) self.lblProgressPercent.Show(False) self.lblProgressPercentSym.Show(False) # Start the directory search as soon as the panel loads self.OnDirectorySearch()
def __init__(self, parent, id, title, res): # Initialize logging logger = logging.getLogger('dicompyler') # Configure the exception hook to process threads as well self.InstallThreadExcepthook() # Remap the exception hook so that we can log and display exceptions def LogExcepthook(*exc_info): # Log the exception text = "".join(traceback.format_exception(*exc_info)) logger.error("Unhandled exception: %s", text) pub.sendMessage('logging.exception', msg=text) sys.excepthook = LogExcepthook # Modify the logging system from pydicom to capture important messages pydicom_logger = logging.getLogger('pydicom') for l in pydicom_logger.handlers: pydicom_logger.removeHandler(l) # Add file logger logpath = os.path.join(guiutil.get_data_dir(), 'logs') if not os.path.exists(logpath): os.makedirs(logpath) self.fh = logging.handlers.RotatingFileHandler( os.path.join(logpath, 'dicompyler.log'), maxBytes=524288, backupCount=7) self.fh.setFormatter(logging.Formatter( '%(asctime)s - %(name)s - %(levelname)s - %(message)s')) self.fh.setLevel(logging.WARNING) logger.addHandler(self.fh) pydicom_logger.addHandler(self.fh) # Add console logger if not frozen if not util.main_is_frozen(): self.ch = logging.StreamHandler() self.ch.setFormatter(logging.Formatter( '%(levelname)s: %(message)s')) self.ch.setLevel(logging.WARNING) logger.addHandler(self.ch) pydicom_logger.addHandler(self.ch) # Otherwise if frozen, send stdout/stderror to /dev/null since # logging the messages seems to cause instability due to recursion else: devnull = open(os.devnull, 'w') sys.stdout = devnull sys.stderr = devnull # Set the window size if guiutil.IsMac(): size=(900, 700) else: size=(850, 625) wx.Frame.__init__(self, parent, id, title, pos=wx.DefaultPosition, size=size, style=wx.DEFAULT_FRAME_STYLE) # Set up the status bar self.sb = self.CreateStatusBar(3) # set up resource file and config file self.res = res # Set window icon if not guiutil.IsMac(): self.SetIcon(guiutil.get_icon()) # Load the main panel for the program self.panelGeneral = self.res.LoadPanel(self, 'panelGeneral') # Initialize the General panel controls self.notebook = XRCCTRL(self, 'notebook') self.notebookTools = XRCCTRL(self, 'notebookTools') self.lblPlanName = XRCCTRL(self, 'lblPlanName') self.lblRxDose = XRCCTRL(self, 'lblRxDose') self.lblPatientName = XRCCTRL(self, 'lblPatientName') self.lblPatientID = XRCCTRL(self, 'lblPatientID') self.lblPatientGender = XRCCTRL(self, 'lblPatientGender') self.lblPatientDOB = XRCCTRL(self, 'lblPatientDOB') self.choiceStructure = XRCCTRL(self, 'choiceStructure') self.lblStructureVolume = XRCCTRL(self, 'lblStructureVolume') self.lblStructureMinDose = XRCCTRL(self, 'lblStructureMinDose') self.lblStructureMaxDose = XRCCTRL(self, 'lblStructureMaxDose') self.lblStructureMeanDose = XRCCTRL(self, 'lblStructureMeanDose') self.cclbStructures = guiutil.ColorCheckListBox(self.notebookTools, 'structure') self.cclbIsodoses = guiutil.ColorCheckListBox(self.notebookTools, 'isodose') # Modify the control size on Mac controls = [self.notebookTools, self.choiceStructure] if guiutil.IsMac(): for control in controls: control.SetWindowVariant(wx.WINDOW_VARIANT_SMALL) # Setup the layout for the frame mainGrid = wx.BoxSizer(wx.VERTICAL) hGrid = wx.BoxSizer(wx.HORIZONTAL) if guiutil.IsMac(): hGrid.Add(self.panelGeneral, 1, flag=wx.EXPAND|wx.ALL|wx.ALIGN_CENTRE, border=4) else: hGrid.Add(self.panelGeneral, 1, flag=wx.EXPAND|wx.ALL|wx.ALIGN_CENTRE) mainGrid.Add(hGrid, 1, flag=wx.EXPAND|wx.ALL|wx.ALIGN_CENTRE) # Load the menu for the frame menuMain = self.res.LoadMenuBar('menuMain') # If we are running on Mac OS X, alter the menu location if guiutil.IsMac(): wx.PyApp.SetMacAboutMenuItemId(XRCID('menuAbout')) wx.PyApp.SetMacPreferencesMenuItemId(XRCID('menuPreferences')) wx.PyApp.SetMacExitMenuItemId(XRCID('menuExit')) # Set the menu as the default menu for this frame self.SetMenuBar(menuMain) # Setup Tools menu self.menuShowLogs = menuMain.FindItemById(XRCID('menuShowLogs')).GetMenu() self.menuPlugins = menuMain.FindItemById(XRCID('menuPluginManager')).GetMenu() # Setup Import menu self.menuImport = menuMain.FindItemById(XRCID('menuImportPlaceholder')).GetMenu() self.menuImport.Delete(menuMain.FindItemById(XRCID('menuImportPlaceholder')).GetId()) self.menuImportItem = menuMain.FindItemById(XRCID('menuImport')) self.menuImportItem.Enable(False) # Setup Export menu self.menuExport = menuMain.FindItemById(XRCID('menuExportPlaceholder')).GetMenu() self.menuExport.Delete(menuMain.FindItemById(XRCID('menuExportPlaceholder')).GetId()) self.menuExportItem = menuMain.FindItemById(XRCID('menuExport')) self.menuExportItem.Enable(False) # Bind menu events to the proper methods self.Bind(wx.EVT_MENU, self.OnOpenPatient, id=XRCID('menuOpen')) self.Bind(wx.EVT_MENU, self.OnClose, id=wx.ID_EXIT) self.Bind(wx.EVT_MENU, self.OnPreferences, id=wx.ID_PREFERENCES) self.Bind(wx.EVT_MENU, self.OnShowLogs, id=XRCID('menuShowLogs')) self.Bind( wx.EVT_MENU, self.OnPluginManager, id=XRCID('menuPluginManager')) self.Bind(wx.EVT_MENU, self.OnAbout, id=wx.ID_ABOUT) self.Bind(wx.EVT_MENU, self.OnHomepage, id=XRCID('menuHomepage')) self.Bind(wx.EVT_MENU, self.OnLicense, id=XRCID('menuLicense')) # Load the toolbar for the frame toolbarMain = self.res.LoadToolBar(self, 'toolbarMain') self.SetToolBar(toolbarMain) self.toolbar = self.GetToolBar() # Setup main toolbar controls folderbmp = wx.Bitmap(util.GetResourcePath('folder_user.png')) self.maintools = [{'label':"Open Patient", 'bmp':folderbmp, 'shortHelp':"Open Patient...", 'eventhandler':self.OnOpenPatient}] for m, tool in enumerate(self.maintools): self.toolbar.AddTool(m+1, tool['label'], tool['bmp'], shortHelp=tool['shortHelp']) self.Bind(wx.EVT_TOOL, tool['eventhandler'], id=m+1) self.toolbar.Realize() # Bind interface events to the proper methods self.Bind( wx.EVT_CHOICE, self.OnStructureSelect, id=XRCID('choiceStructure')) self.Bind(wx.EVT_ACTIVATE, self.OnActivate) self.Bind(wx.EVT_CLOSE, self.OnClose) self.notebook.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, self.OnPageChanged) # Events to work around a focus bug in Windows self.notebook.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self.notebook.Bind(wx.EVT_MOUSEWHEEL, self.OnMouseWheel) self.notebookTools.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self.notebookTools.Bind(wx.EVT_MOUSEWHEEL, self.OnMouseWheel) self.SetSizer(mainGrid) self.Layout() #Set the Minumum size self.SetMinSize(size) self.Centre(wx.BOTH) # Initialize the welcome notebook tab panelWelcome = self.res.LoadPanel(self.notebook, 'panelWelcome') self.notebook.AddPage(panelWelcome, 'Welcome') # Set the version on the welcome notebook tab XRCCTRL(self, 'lblVersion').SetLabel('Version ' + __version__) # Initialize the tools notebook self.notebookTools.AddPage(self.cclbStructures, 'Structures') self.notebookTools.AddPage(self.cclbIsodoses, 'Isodoses') # Create the data folder datapath = guiutil.get_data_dir() if not os.path.exists(datapath): os.mkdir(datapath) # Initialize the preferences if guiutil.IsMac(): self.prefmgr = preferences.PreferencesManager( parent = self, appname = 'dicompyler') else: self.prefmgr = preferences.PreferencesManager( parent = self, appname = 'dicompyler', name = 'Options') sp = wx.StandardPaths.Get() self.generalpreftemplate = [ {'DICOM Import Settings': [{'name':'Import Location', 'type':'choice', 'values':['Remember Last Used', 'Always Use Default'], 'default':'Remember Last Used', 'callback':'general.dicom.import_location_setting'}, {'name':'Default Location', 'type':'directory', 'default':sp.GetDocumentsDir(), 'callback':'general.dicom.import_location'}] }, {'Plugin Settings': [{'name':'User Plugins Location', 'type':'directory', 'default':os.path.join(datapath, 'plugins'), 'callback':'general.plugins.user_plugins_location', 'restart':True}] }, {'Calculation Settings': [{'name':'DVH Calculation', 'type':'choice', 'values':['Use RT Dose DVH if Present', 'Always Recalculate DVH'], 'default':'Use RT Dose DVH if Present', 'callback':'general.calculation.dvh_recalc'}] }, {'Advanced Settings': [{'name':'Enable Detailed Logging', 'type':'checkbox', 'default':False, 'callback':'general.advanced.detailed_logging'}] }] self.preftemplate = [{'General':self.generalpreftemplate}] pub.sendMessage('preferences.updated.template', msg=self.preftemplate) # Initialize variables self.ptdata = {} # Set up pubsub pub.subscribe(self.OnLoadPatientData, 'patient.updated.raw_data') pub.subscribe(self.OnStructureCheck, 'colorcheckbox.checked.structure') pub.subscribe(self.OnStructureUncheck, 'colorcheckbox.unchecked.structure') pub.subscribe(self.OnIsodoseCheck, 'colorcheckbox.checked.isodose') pub.subscribe(self.OnIsodoseUncheck, 'colorcheckbox.unchecked.isodose') pub.subscribe(self.OnUpdatePlugins, 'general.plugins.user_plugins_location') pub.subscribe(self.OnUpdatePreferences, 'general') pub.subscribe(self.OnUpdateStatusBar, 'main.update_statusbar') pub.subscribe(self.OnOpenPatient, 'dicomgui.show') # Send a message to the logging system to turn on/off detailed logging pub.sendMessage('preferences.requested.value', msg='general.advanced.detailed_logging') # Create the default user plugin path self.userpluginpath = os.path.join(datapath, 'plugins') if not os.path.exists(self.userpluginpath): os.mkdir(self.userpluginpath) # Load and initialize plugins self.plugins = [] self.pluginsDisabled = [] pub.sendMessage('preferences.requested.value', msg='general.plugins.user_plugins_location') pub.sendMessage('preferences.requested.value', msg='general.calculation.dvh_recalc') pub.sendMessage('preferences.requested.value', msg='general.plugins.disabled_list') pub.sendMessage('preferences.requested.values', msg='general.window')
def __init__(self, parent, id, title, res): # Initialize logging logger = logging.getLogger("dicompyler") # Configure the exception hook to process threads as well self.InstallThreadExcepthook() # Remap the exception hook so that we can log and display exceptions def LogExcepthook(*exc_info): # Log the exception text = "".join(traceback.format_exception(*exc_info)) logger.error("Unhandled exception: %s", text) pub.sendMessage("logging.exception", text) sys.excepthook = LogExcepthook # Modify the logging system from pydicom to capture important messages pydicom_logger = logging.getLogger("pydicom") for l in pydicom_logger.handlers: pydicom_logger.removeHandler(l) # Add file logger logpath = os.path.join(guiutil.get_data_dir(), "logs") if not os.path.exists(logpath): os.makedirs(logpath) self.fh = logging.handlers.RotatingFileHandler( os.path.join(logpath, "dicompyler.log"), maxBytes=524288, backupCount=7 ) self.fh.setFormatter(logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")) self.fh.setLevel(logging.WARNING) logger.addHandler(self.fh) pydicom_logger.addHandler(self.fh) # Add console logger if not frozen if not util.main_is_frozen(): self.ch = logging.StreamHandler() self.ch.setFormatter(logging.Formatter("%(levelname)s: %(message)s")) self.ch.setLevel(logging.WARNING) logger.addHandler(self.ch) pydicom_logger.addHandler(self.ch) # Otherwise if frozen, send stdout/stderror to /dev/null since # logging the messages seems to cause instability due to recursion else: devnull = open(os.devnull, "w") sys.stdout = devnull sys.stderr = devnull # Set the window size if guiutil.IsMac(): size = (900, 700) else: size = (850, 625) wx.Frame.__init__(self, parent, id, title, pos=wx.DefaultPosition, size=size, style=wx.DEFAULT_FRAME_STYLE) # Set up the status bar self.sb = self.CreateStatusBar(3) # set up resource file and config file self.res = res # Set window icon if not guiutil.IsMac(): self.SetIcon(guiutil.get_icon()) # Load the main panel for the program self.panelGeneral = self.res.LoadPanel(self, "panelGeneral") # Initialize the General panel controls self.notebook = XRCCTRL(self, "notebook") self.notebookTools = XRCCTRL(self, "notebookTools") self.lblPlanName = XRCCTRL(self, "lblPlanName") self.lblRxDose = XRCCTRL(self, "lblRxDose") self.lblPatientName = XRCCTRL(self, "lblPatientName") self.lblPatientID = XRCCTRL(self, "lblPatientID") self.lblPatientGender = XRCCTRL(self, "lblPatientGender") self.lblPatientDOB = XRCCTRL(self, "lblPatientDOB") self.choiceStructure = XRCCTRL(self, "choiceStructure") self.lblStructureVolume = XRCCTRL(self, "lblStructureVolume") self.lblStructureMinDose = XRCCTRL(self, "lblStructureMinDose") self.lblStructureMaxDose = XRCCTRL(self, "lblStructureMaxDose") self.lblStructureMeanDose = XRCCTRL(self, "lblStructureMeanDose") self.cclbStructures = guiutil.ColorCheckListBox(self.notebookTools, "structure") self.cclbIsodoses = guiutil.ColorCheckListBox(self.notebookTools, "isodose") # Modify the control and font size on Mac controls = [self.notebookTools, self.choiceStructure] if guiutil.IsMac(): font = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT) font.SetPointSize(10) for control in controls: control.SetWindowVariant(wx.WINDOW_VARIANT_SMALL) control.SetFont(font) # Setup the layout for the frame mainGrid = wx.BoxSizer(wx.VERTICAL) hGrid = wx.BoxSizer(wx.HORIZONTAL) if guiutil.IsMac(): hGrid.Add(self.panelGeneral, 1, flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTRE, border=4) else: hGrid.Add(self.panelGeneral, 1, flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTRE) mainGrid.Add(hGrid, 1, flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTRE) # Load the menu for the frame menuMain = self.res.LoadMenuBar("menuMain") # If we are running on Mac OS X, alter the menu location if guiutil.IsMac(): wx.App_SetMacAboutMenuItemId(XRCID("menuAbout")) wx.App_SetMacPreferencesMenuItemId(XRCID("menuPreferences")) wx.App_SetMacExitMenuItemId(XRCID("menuExit")) # Set the menu as the default menu for this frame self.SetMenuBar(menuMain) # Setup Tools menu self.menuShowLogs = menuMain.FindItemById(XRCID("menuShowLogs")).GetMenu() self.menuPlugins = menuMain.FindItemById(XRCID("menuPluginManager")).GetMenu() # Setup Import menu self.menuImport = menuMain.FindItemById(XRCID("menuImportPlaceholder")).GetMenu() self.menuImport.Delete(menuMain.FindItemById(XRCID("menuImportPlaceholder")).GetId()) self.menuImportItem = menuMain.FindItemById(XRCID("menuImport")) self.menuImportItem.Enable(False) # Setup Export menu self.menuExport = menuMain.FindItemById(XRCID("menuExportPlaceholder")).GetMenu() self.menuExport.Delete(menuMain.FindItemById(XRCID("menuExportPlaceholder")).GetId()) self.menuExportItem = menuMain.FindItemById(XRCID("menuExport")) self.menuExportItem.Enable(False) # Bind menu events to the proper methods wx.EVT_MENU(self, XRCID("menuOpen"), self.OnOpenPatient) wx.EVT_MENU(self, XRCID("menuExit"), self.OnClose) wx.EVT_MENU(self, XRCID("menuPreferences"), self.OnPreferences) wx.EVT_MENU(self, XRCID("menuShowLogs"), self.OnShowLogs) wx.EVT_MENU(self, XRCID("menuPluginManager"), self.OnPluginManager) wx.EVT_MENU(self, XRCID("menuAbout"), self.OnAbout) wx.EVT_MENU(self, XRCID("menuHomepage"), self.OnHomepage) wx.EVT_MENU(self, XRCID("menuLicense"), self.OnLicense) # Load the toolbar for the frame toolbarMain = self.res.LoadToolBar(self, "toolbarMain") self.SetToolBar(toolbarMain) self.toolbar = self.GetToolBar() # Setup main toolbar controls folderbmp = wx.Bitmap(util.GetResourcePath("folder_user.png")) self.maintools = [ { "label": "Open Patient", "bmp": folderbmp, "shortHelp": "Open Patient...", "eventhandler": self.OnOpenPatient, } ] for m, tool in enumerate(self.maintools): self.toolbar.AddLabelTool(m + 1, tool["label"], tool["bmp"], shortHelp=tool["shortHelp"]) self.Bind(wx.EVT_TOOL, tool["eventhandler"], id=m + 1) self.toolbar.Realize() # Bind interface events to the proper methods wx.EVT_CHOICE(self, XRCID("choiceStructure"), self.OnStructureSelect) self.Bind(wx.EVT_CLOSE, self.OnClose) self.notebook.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, self.OnPageChanged) # Events to work around a focus bug in Windows self.notebook.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self.notebook.Bind(wx.EVT_MOUSEWHEEL, self.OnMouseWheel) self.notebookTools.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self.notebookTools.Bind(wx.EVT_MOUSEWHEEL, self.OnMouseWheel) self.SetSizer(mainGrid) self.Layout() # Set the Minumum size self.SetMinSize(size) self.Centre(wx.BOTH) # Initialize the welcome notebook tab panelWelcome = self.res.LoadPanel(self.notebook, "panelWelcome") self.notebook.AddPage(panelWelcome, "Welcome") # Set the version on the welcome notebook tab XRCCTRL(self, "lblVersion").SetLabel("Version " + __version__) # Initialize the tools notebook self.notebookTools.AddPage(self.cclbStructures, "Structures") self.notebookTools.AddPage(self.cclbIsodoses, "Isodoses") # Create the data folder datapath = guiutil.get_data_dir() if not os.path.exists(datapath): os.mkdir(datapath) # Initialize the preferences if guiutil.IsMac(): self.prefmgr = preferences.PreferencesManager(parent=None, appname="dicompyler") else: self.prefmgr = preferences.PreferencesManager(parent=None, appname="dicompyler", name="Options") sp = wx.StandardPaths.Get() self.generalpreftemplate = [ { "DICOM Import Settings": [ { "name": "Import Location", "type": "choice", "values": ["Remember Last Used", "Always Use Default"], "default": "Remember Last Used", "callback": "general.dicom.import_location_setting", }, { "name": "Default Location", "type": "directory", "default": unicode(sp.GetDocumentsDir()), "callback": "general.dicom.import_location", }, ] }, { "Plugin Settings": [ { "name": "User Plugins Location", "type": "directory", "default": unicode(os.path.join(datapath, "plugins")), "callback": "general.plugins.user_plugins_location", "restart": True, } ] }, { "Calculation Settings": [ { "name": "DVH Calculation", "type": "choice", "values": ["Use RT Dose DVH if Present", "Always Recalculate DVH"], "default": "Use RT Dose DVH if Present", "callback": "general.calculation.dvh_recalc", } ] }, { "Advanced Settings": [ { "name": "Enable Detailed Logging", "type": "checkbox", "default": False, "callback": "general.advanced.detailed_logging", } ] }, ] self.preftemplate = [{"General": self.generalpreftemplate}] pub.sendMessage("preferences.updated.template", self.preftemplate) # Initialize variables self.ptdata = {} # Set up pubsub pub.subscribe(self.OnLoadPatientData, "patient.updated.raw_data") pub.subscribe(self.OnStructureCheck, "colorcheckbox.checked.structure") pub.subscribe(self.OnStructureUncheck, "colorcheckbox.unchecked.structure") pub.subscribe(self.OnIsodoseCheck, "colorcheckbox.checked.isodose") pub.subscribe(self.OnIsodoseUncheck, "colorcheckbox.unchecked.isodose") pub.subscribe(self.OnUpdatePlugins, "general.plugins.user_plugins_location") pub.subscribe(self.OnUpdatePreferences, "general") pub.subscribe(self.OnUpdateStatusBar, "main.update_statusbar") # Send a message to the logging system to turn on/off detailed logging pub.sendMessage("preferences.requested.value", "general.advanced.detailed_logging") # Create the default user plugin path self.userpluginpath = os.path.join(datapath, "plugins") if not os.path.exists(self.userpluginpath): os.mkdir(self.userpluginpath) # Load and initialize plugins self.plugins = [] pub.sendMessage("preferences.requested.value", "general.plugins.user_plugins_location") pub.sendMessage("preferences.requested.value", "general.calculation.dvh_recalc")
def __init__(self, parent, id, title, res): # Initialize logging logger = logging.getLogger("dicompyler") # Configure the exception hook to process threads as well self.InstallThreadExcepthook() # Remap the exception hook so that we can log and display exceptions def LogExcepthook(*exc_info): # Log the exception text = "".join(traceback.format_exception(*exc_info)) logger.error("Unhandled exception: %s", text) pub.sendMessage("logging.exception", msg=text) sys.excepthook = LogExcepthook # Modify the logging system from pydicom to capture important messages pydicom_logger = logging.getLogger("pydicom") for l in pydicom_logger.handlers: pydicom_logger.removeHandler(l) # Add file logger logpath = os.path.join(guiutil.get_data_dir(), "logs") if not os.path.exists(logpath): os.makedirs(logpath) self.fh = logging.handlers.RotatingFileHandler(os.path.join( logpath, "dicompyler.log"), maxBytes=524288, backupCount=7) self.fh.setFormatter( logging.Formatter( "%(asctime)s - %(name)s - %(levelname)s - %(message)s")) self.fh.setLevel(logging.WARNING) logger.addHandler(self.fh) pydicom_logger.addHandler(self.fh) # Add console logger if not frozen if not util.main_is_frozen(): self.ch = logging.StreamHandler() self.ch.setFormatter( logging.Formatter("%(levelname)s: %(message)s")) self.ch.setLevel(logging.WARNING) logger.addHandler(self.ch) pydicom_logger.addHandler(self.ch) # Otherwise if frozen, send stdout/stderror to /dev/null since # logging the messages seems to cause instability due to recursion else: devnull = open(os.devnull, "w") sys.stdout = devnull sys.stderr = devnull # Set the window size if guiutil.IsMac(): size = (1200, 700) else: size = (1200, 700) wx.Frame.__init__( self, parent, id, title, pos=wx.DefaultPosition, size=size, style=wx.DEFAULT_FRAME_STYLE, ) # Set up the status bar self.sb = self.CreateStatusBar(3) # set up resource file and config file self.res = res # Set window icon if not guiutil.IsMac(): self.SetIcon(guiutil.get_icon()) # Load the main panel for the program self.panelGeneral = self.res.LoadPanel(self, "panelGeneral") # Initialize the General panel controls self.notebook = XRCCTRL(self, "notebook") self.notebookTools = XRCCTRL(self, "notebookTools") self.lblPlanName = XRCCTRL(self, "lblPlanName") self.lblRxDose = XRCCTRL(self, "lblRxDose") self.lblPatientName = XRCCTRL(self, "lblPatientName") self.lblPatientID = XRCCTRL(self, "lblPatientID") self.lblPatientGender = XRCCTRL(self, "lblPatientGender") self.lblPatientDOB = XRCCTRL(self, "lblPatientDOB") self.choiceStructure = XRCCTRL(self, "choiceStructure") self.lblStructureVolume = XRCCTRL(self, "lblStructureVolume") self.lblStructureMinDose = XRCCTRL(self, "lblStructureMinDose") self.lblStructureMaxDose = XRCCTRL(self, "lblStructureMaxDose") self.lblStructureMeanDose = XRCCTRL(self, "lblStructureMeanDose") self.cclbStructures = guiutil.ColorCheckListBox( self.notebookTools, "structure") self.cclbIsodoses = guiutil.ColorCheckListBox(self.notebookTools, "isodose") """test code""" self.sidePanel = XRCCTRL(self, "sidePanel") sizer = wx.BoxSizer(wx.VERTICAL) self.sidePanel.SetSizer(sizer) self.histPanel = HistPanel(self.sidePanel) self.histPanel.plot_histogram_img(util.GetResourcePath("book.png")) sizer.Add(self.histPanel, 0, wx.ALL | wx.EXPAND) """test code""" # Modify the control size on Mac controls = [self.notebookTools, self.choiceStructure] if guiutil.IsMac(): for control in controls: control.SetWindowVariant(wx.WINDOW_VARIANT_SMALL) # Setup the layout for the frame mainGrid = wx.BoxSizer(wx.VERTICAL) hGrid = wx.BoxSizer(wx.HORIZONTAL) if guiutil.IsMac(): hGrid.Add( self.panelGeneral, 1, flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTRE, border=4, ) else: hGrid.Add(self.panelGeneral, 1, flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTRE) mainGrid.Add(hGrid, 1, flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTRE) # Load the menu for the frame menuMain = self.res.LoadMenuBar("menuMain") # If we are running on Mac OS X, alter the menu location if guiutil.IsMac(): wx.PyApp.SetMacAboutMenuItemId(XRCID("menuAbout")) wx.PyApp.SetMacPreferencesMenuItemId(XRCID("menuPreferences")) wx.PyApp.SetMacExitMenuItemId(XRCID("menuExit")) # Set the menu as the default menu for this frame self.SetMenuBar(menuMain) # Setup Tools menu self.menuShowLogs = menuMain.FindItemById( XRCID("menuShowLogs")).GetMenu() self.menuPlugins = menuMain.FindItemById( XRCID("menuPluginManager")).GetMenu() # Setup Import menu self.menuImport = menuMain.FindItemById( XRCID("menuImportPlaceholder")).GetMenu() self.menuImport.Delete( menuMain.FindItemById(XRCID("menuImportPlaceholder")).GetId()) self.menuImportItem = menuMain.FindItemById(XRCID("menuImport")) self.menuImportItem.Enable(False) # Setup Export menu self.menuExport = menuMain.FindItemById( XRCID("menuExportPlaceholder")).GetMenu() self.menuExport.Delete( menuMain.FindItemById(XRCID("menuExportPlaceholder")).GetId()) self.menuExportItem = menuMain.FindItemById(XRCID("menuExport")) self.menuExportItem.Enable(False) # Bind menu events to the proper methods self.Bind(wx.EVT_MENU, self.OnOpenPatient, id=XRCID("menuOpen")) self.Bind(wx.EVT_MENU, self.OnClose, id=wx.ID_EXIT) self.Bind(wx.EVT_MENU, self.OnPreferences, id=wx.ID_PREFERENCES) self.Bind(wx.EVT_MENU, self.OnShowLogs, id=XRCID("menuShowLogs")) self.Bind(wx.EVT_MENU, self.OnPluginManager, id=XRCID("menuPluginManager")) self.Bind(wx.EVT_MENU, self.OnAbout, id=wx.ID_ABOUT) self.Bind(wx.EVT_MENU, self.OnHomepage, id=XRCID("menuHomepage")) self.Bind(wx.EVT_MENU, self.OnLicense, id=XRCID("menuLicense")) # Load the toolbar for the frame toolbarMain = self.res.LoadToolBar(self, "toolbarMain") self.SetToolBar(toolbarMain) self.toolbar = self.GetToolBar() # Setup main toolbar controls folderbmp = wx.Bitmap(util.GetResourcePath("folder_user.png")) self.maintools = [{ "label": "Open Patient", "bmp": folderbmp, "shortHelp": "Open Patient...", "eventhandler": self.OnOpenPatient, }] for m, tool in enumerate(self.maintools): self.toolbar.AddTool(m + 1, tool["label"], tool["bmp"], shortHelp=tool["shortHelp"]) self.Bind(wx.EVT_TOOL, tool["eventhandler"], id=m + 1) self.toolbar.Realize() # Bind interface events to the proper methods self.Bind(wx.EVT_CHOICE, self.OnStructureSelect, id=XRCID("choiceStructure")) self.Bind(wx.EVT_ACTIVATE, self.OnActivate) self.Bind(wx.EVT_CLOSE, self.OnClose) self.notebook.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, self.OnPageChanged) # Events to work around a focus bug in Windows self.notebook.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self.notebook.Bind(wx.EVT_MOUSEWHEEL, self.OnMouseWheel) self.notebookTools.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self.notebookTools.Bind(wx.EVT_MOUSEWHEEL, self.OnMouseWheel) self.SetSizer(mainGrid) self.Layout() # Set the Minumum size self.SetMinSize(size) self.Centre(wx.BOTH) # Initialize the welcome notebook tab panelWelcome = self.res.LoadPanel(self.notebook, "panelWelcome") self.notebook.AddPage(panelWelcome, "Welcome") # Set the version on the welcome notebook tab XRCCTRL(self, "lblVersion").SetLabel("Version " + __version__) # Initialize the tools notebook self.notebookTools.AddPage(self.cclbStructures, "Structures") self.notebookTools.AddPage(self.cclbIsodoses, "Isodoses") # Create the data folder datapath = guiutil.get_data_dir() if not os.path.exists(datapath): os.mkdir(datapath) # Initialize the preferences if guiutil.IsMac(): self.prefmgr = preferences.PreferencesManager(parent=self, appname="dicompyler") else: self.prefmgr = preferences.PreferencesManager(parent=self, appname="dicompyler", name="Options") sp = wx.StandardPaths.Get() self.generalpreftemplate = [ { "DICOM Import Settings": [ { "name": "Import Location", "type": "choice", "values": ["Remember Last Used", "Always Use Default"], "default": "Remember Last Used", "callback": "general.dicom.import_location_setting", }, { "name": "Default Location", "type": "directory", "default": sp.GetDocumentsDir(), "callback": "general.dicom.import_location", }, ] }, { "Plugin Settings": [{ "name": "User Plugins Location", "type": "directory", "default": os.path.join(datapath, "plugins"), "callback": "general.plugins.user_plugins_location", "restart": True, }] }, { "Calculation Settings": [{ "name": "DVH Calculation", "type": "choice", "values": [ "Use RT Dose DVH if Present", "Always Recalculate DVH", ], "default": "Use RT Dose DVH if Present", "callback": "general.calculation.dvh_recalc", }] }, { "Advanced Settings": [{ "name": "Enable Detailed Logging", "type": "checkbox", "default": False, "callback": "general.advanced.detailed_logging", }] }, ] self.preftemplate = [{"General": self.generalpreftemplate}] pub.sendMessage("preferences.updated.template", msg=self.preftemplate) # Initialize variables self.ptdata = {} # Set up pubsub pub.subscribe(self.OnLoadPatientData, "patient.updated.raw_data") pub.subscribe(self.OnStructureCheck, "colorcheckbox.checked.structure") pub.subscribe(self.OnStructureUncheck, "colorcheckbox.unchecked.structure") pub.subscribe(self.OnIsodoseCheck, "colorcheckbox.checked.isodose") pub.subscribe(self.OnIsodoseUncheck, "colorcheckbox.unchecked.isodose") pub.subscribe(self.OnUpdatePlugins, "general.plugins.user_plugins_location") pub.subscribe(self.OnUpdatePreferences, "general") pub.subscribe(self.OnUpdateStatusBar, "main.update_statusbar") pub.subscribe(self.OnOpenPatient, "dicomgui.show") # Send a message to the logging system to turn on/off detailed logging pub.sendMessage("preferences.requested.value", msg="general.advanced.detailed_logging") # Create the default user plugin path self.userpluginpath = os.path.join(datapath, "plugins") if not os.path.exists(self.userpluginpath): os.mkdir(self.userpluginpath) # Load and initialize plugins self.plugins = [] self.pluginsDisabled = [] pub.sendMessage("preferences.requested.value", msg="general.plugins.user_plugins_location") pub.sendMessage("preferences.requested.value", msg="general.calculation.dvh_recalc") pub.sendMessage("preferences.requested.value", msg="general.plugins.disabled_list") pub.sendMessage("preferences.requested.values", msg="general.window")