Exemplo n.º 1
0
    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()
Exemplo n.º 2
0
    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
Exemplo n.º 3
0
    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
Exemplo n.º 4
0
    def OnUpdatePositionValues(self, evt=None):
        """Update the current position and value(s) of the mouse cursor."""

        if (evt == None):
            pos = np.array(self.mousepos)
        else:
            pos = np.array(evt.GetPosition())

        # On the Mac, the cursor position is shifted by 1 pixel to the left
        if guiutil.IsMac():
            pos = pos - 1

        # Determine the coordinates with respect to the current zoom and pan
        w, h = self.GetClientSize()
        xpos = int(pos[0] / self.zoom - self.pan[0] -
                   (w - self.bwidth * self.zoom) / (2 * self.zoom))
        ypos = int(pos[1] / self.zoom - self.pan[1] -
                   (h - self.bheight * self.zoom) / (2 * self.zoom))

        # Save the coordinates so they can be used by the 2dview plugins
        self.xpos = xpos
        self.ypos = ypos

        # Set an empty text placeholder if the coordinates are not within range
        text = ""
        value = ""
        # Only display if the mouse coordinates are within the image size range
        if ((0 <= xpos < len(self.structurepixlut[0]))
                and (0 <= ypos < len(self.structurepixlut[1]))
                and self.mouse_in_window):
            text = "X: " + unicode('%.2f' % self.structurepixlut[0][xpos]) + \
                " mm Y: " + unicode('%.2f' % self.structurepixlut[1][ypos]) + \
                " mm / X: " + unicode(xpos) + \
                " px Y:" + unicode(ypos) + " px"

            # Lookup the current image and find the value of the current pixel
            image = self.images[self.imagenum - 1]
            # Rescale the slope and intercept of the image if present
            if (image.ds.has_key('RescaleIntercept')
                    and image.ds.has_key('RescaleSlope')):
                pixel_array = image.ds.pixel_array*image.ds.RescaleSlope + \
                              image.ds.RescaleIntercept
            else:
                pixel_array = image.ds.pixel_array
            value = "Value: " + unicode(pixel_array[ypos, xpos])

            # Lookup the current dose plane and find the value of the current
            # pixel, if the dose has been loaded
            if not (self.dose == []):
                xdpos = np.argmin(np.fabs(np.array(self.dosepixlut[0]) - xpos))
                ydpos = np.argmin(np.fabs(np.array(self.dosepixlut[1]) - ypos))
                dosegrid = self.dose.GetDoseGrid(float(self.z))
                if not (dosegrid == []):
                    dose = dosegrid[ydpos, xdpos] * \
                           self.dosedata['dosegridscaling']
                    value = value + " / Dose: " + \
                            unicode('%.4g' % dose) + " Gy / " + \
                            unicode('%.4g' % float(dose*10000/self.rxdose)) + " %"
        # Send a message with the text to the 2nd and 3rd statusbar sections
        pub.sendMessage('main.update_statusbar', {1: text, 2: value})
Exemplo n.º 5
0
    def OnInit(self):
        # no-op in wxPython2.8 and later: wx.InitAllImageHandlers()
        wx.GetApp().SetAppName("dicompyler")

        # Load the XRC file for our gui resources
        self.res = XmlResource(util.GetResourcePath('main.xrc'))

        # Use the native listctrl on Mac OS X
        if guiutil.IsMac():
            wx.SystemOptions.SetOptionInt("mac.listctrl.always_use_generic", 0)

        dicompylerFrame = MainFrame(None, -1, "dicompyler", self.res)
        self.SetTopWindow(dicompylerFrame)
        dicompylerFrame.Show()
        return 1
Exemplo n.º 6
0
    def Init(self, res):
        """Method called after the panel has been initialized."""

        # Initialize the panel controls
        self.choiceDICOM = XRCCTRL(self, 'choiceDICOM')
        self.tlcTreeView = DICOMTree(self)
        res.AttachUnknownControl('tlcTreeView', self.tlcTreeView, self)

        # Bind interface events to the proper methods
        self.Bind(wx.EVT_CHOICE, self.OnLoadTree, id=XRCID('choiceDICOM'))
        self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy)

        # Decrease the font size on Mac
        font = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT)
        if guiutil.IsMac():
            font.SetPointSize(10)
            self.tlcTreeView.SetFont(font)

        # Set up pubsub
        pub.subscribe(self.OnUpdatePatient, 'patient.updated.raw_data')
Exemplo n.º 7
0
    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))
Exemplo n.º 8
0
    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')
Exemplo n.º 9
0
    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()
Exemplo n.º 10
0
    def Init(self, res):
        """Method called after the panel has been initialized."""

        self.guiDVH = guidvh.guiDVH(self)
        res.AttachUnknownControl("panelDVH", self.guiDVH.panelDVH, self)

        # Initialize the Constraint selector controls
        self.lblType = XRCCTRL(self, "lblType")
        self.choiceConstraint = XRCCTRL(self, "choiceConstraint")
        self.txtConstraint = XRCCTRL(self, "txtConstraint")
        self.sliderConstraint = XRCCTRL(self, "sliderConstraint")
        self.lblResultType = XRCCTRL(self, "lblResultType")
        self.lblConstraintUnits = XRCCTRL(self, "lblConstraintUnits")
        self.lblConstraintTypeUnits = XRCCTRL(self, "lblConstraintTypeUnits")

        # Initialize the result labels
        self.lblConstraintType = XRCCTRL(self, "lblConstraintType")
        self.lblResultDivider = XRCCTRL(self, "lblResultDivider")
        self.lblConstraintPercent = XRCCTRL(self, "lblConstraintPercent")

        # Modify the control and font size on Mac
        controls = [
            self.lblType,
            self.choiceConstraint,
            self.sliderConstraint,
            self.lblResultType,
            self.lblConstraintUnits,
            self.lblConstraintPercent,
            self.lblConstraintType,
            self.lblConstraintTypeUnits,
            self.lblResultDivider,
        ]
        # Add children of composite controls to modification list
        compositecontrols = [self.txtConstraint]
        for control in compositecontrols:
            for child in control.GetChildren():
                controls.append(child)
        # Add the constraint static box to the modification list
        controls.append(self.lblType.GetContainingSizer().GetStaticBox())

        if guiutil.IsMac():
            for control in controls:
                control.SetWindowVariant(wx.WINDOW_VARIANT_SMALL)

        # Adjust the control size for the result value labels
        te = self.lblType.GetTextExtent("0")
        self.lblConstraintUnits.SetMinSize((te[0] * 10, te[1]))
        self.lblConstraintPercent.SetMinSize((te[0] * 6, te[1]))
        self.Layout()

        # Bind ui events to the proper methods
        self.Bind(wx.EVT_CHOICE,
                  self.OnToggleConstraints,
                  id=XRCID("choiceConstraint"))
        self.Bind(wx.EVT_SPINCTRL,
                  self.OnChangeConstraint,
                  id=XRCID("txtConstraint"))
        self.Bind(
            wx.EVT_COMMAND_SCROLL_THUMBTRACK,
            self.OnChangeConstraint,
            id=XRCID("sliderConstraint"),
        )
        self.Bind(
            wx.EVT_COMMAND_SCROLL_CHANGED,
            self.OnChangeConstraint,
            id=XRCID("sliderConstraint"),
        )
        self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy)

        # Initialize variables
        self.structures = {}  # structures from initial DICOM data
        self.checkedstructures = {}  # structures that need to be shown
        self.dvhs = {}  # raw dvhs from initial DICOM data
        self.dvharray = {}  # dict of dvh data processed from dvhdata
        self.dvhscaling = {}  # dict of dvh scaling data
        self.plan = {}  # used for rx dose
        self.structureid = 1  # used to indicate current constraint structure

        # Set up pubsub
        pub.subscribe(self.OnUpdatePatient, "patient.updated.parsed_data")
        pub.subscribe(self.OnStructureCheck, "structures.checked")
        pub.subscribe(self.OnStructureSelect, "structure.selected")
Exemplo n.º 11
0
    def OnPaint(self, evt):
        """Update the panel when it needs to be refreshed."""

        # Bind motion event when the panel has been painted to avoid a blank
        # image on Windows if a file is loaded too quickly before the plugin
        # is initialized
        self.Bind(wx.EVT_MOTION, self.OnMouseMotion)

        # Special case for Windows to account for flickering
        # if and only if images are loaded
        if (guiutil.IsMSWindows() and len(self.images)):
            dc = wx.BufferedPaintDC(self)
            self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
        else:
            dc = wx.PaintDC(self)

        width, height = self.GetClientSize()
        try:
            gc = wx.GraphicsContext.Create(dc)
        except NotImplementedError:
            dc.DrawText(
                "This build of wxPython does not support the "
                "wx.GraphicsContext family of classes.", 25, 25)
            return

        # If we have images loaded, process and show the image
        if len(self.images):
            # Save the original drawing state
            gc.PushState()
            # Scale the image by the zoom factor
            gc.Scale(self.zoom, self.zoom)

            # Redraw the background on Windows
            if guiutil.IsMSWindows():
                gc.SetBrush(wx.Brush(wx.Colour(0, 0, 0)))
                gc.SetPen(wx.Pen(wx.Colour(0, 0, 0)))
                gc.DrawRectangle(0, 0, width, height)

            image = guiutil.convert_pil_to_wx(
                self.images[self.imagenum - 1].GetImage(
                    self.window, self.level))
            bmp = wx.Bitmap(image)
            self.bwidth, self.bheight = image.GetSize()

            # Center the image
            transx = self.pan[0] + (width -
                                    self.bwidth * self.zoom) / (2 * self.zoom)
            transy = self.pan[1] + (height -
                                    self.bheight * self.zoom) / (2 * self.zoom)
            gc.Translate(transx, transy)
            gc.DrawBitmap(bmp, 0, 0, self.bwidth, self.bheight)
            gc.SetBrush(wx.Brush(wx.Colour(0, 0, 255, 30)))
            gc.SetPen(wx.Pen(wx.Colour(0, 0, 255, 30)))

            # Draw the structures if present
            imdata = self.images[self.imagenum - 1].GetImageData()
            self.z = '%.2f' % imdata['position'][2]

            # Determine whether the patient is prone or supine
            if 'p' in imdata['patientposition'].lower():
                prone = True
            else:
                prone = False
            # Determine whether the patient is feet first or head first
            if 'ff' in imdata['patientposition'].lower():
                feetfirst = True
            else:
                feetfirst = False
            for id, structure in self.structures.items():
                self.DrawStructure(structure, gc, self.z, prone, feetfirst)

            # Draw the isodoses if present
            if len(self.isodoses):
                grid = self.dose.GetDoseGrid(float(self.z))
                if not (grid == []):
                    x, y = np.meshgrid(np.arange(grid.shape[1]),
                                       np.arange(grid.shape[0]))
                    # Instantiate the isodose generator for this slice
                    isodosegen = cntr.Cntr(x, y, grid)
                    for id, isodose in iter(sorted(self.isodoses.items())):
                        self.DrawIsodose(isodose, gc, isodosegen)

            # Restore the translation and scaling
            gc.PopState()

            # Prepare the font for drawing the information text
            font = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT)
            if guiutil.IsMac():
                font.SetPointSize(10)
            gc.SetFont(font, wx.WHITE)

            # Draw the information text
            imtext = "Image: " + str(self.imagenum) + "/" + str(
                len(self.images))
            te = gc.GetFullTextExtent(imtext)
            gc.DrawText(imtext, 10, 7)
            impos = "Position: " + str(self.z) + " mm"
            gc.DrawText(impos, 10, 7 + te[1] * 1.1)
            if ("%.3f" % self.zoom == "1.000"):
                zoom = "1"
            else:
                zoom = "%.3f" % self.zoom
            imzoom = "Zoom: " + zoom + ":1"
            gc.DrawText(imzoom, 10, height - 17)
            imsize = "Image Size: " + str(self.bheight) + "x" + str(
                self.bwidth) + " px"
            gc.DrawText(imsize, 10, height - 17 - te[1] * 1.1)
            imwinlevel = "W/L: " + str(self.window) + ' / ' + str(self.level)
            te = gc.GetFullTextExtent(imwinlevel)
            gc.DrawText(imwinlevel, width - te[0] - 7, 7)
            impatpos = "Patient Position: " + imdata['patientposition']
            te = gc.GetFullTextExtent(impatpos)
            gc.DrawText(impatpos, width - te[0] - 7, height - 17)

            # Send message with the current image number and various properties
            pub.sendMessage(
                '2dview.updated.image',
                msg={
                    'number': self.imagenum,  # slice number
                    'z': self.z,  # slice location
                    'window': self.window,  # current window value
                    'level': self.level,  # curent level value
                    'gc': gc,  # wx.GraphicsContext
                    'scale': self.zoom,  # current zoom level
                    'transx': transx,  # current x translation
                    'transy': transy,  # current y translation
                    'imdata': imdata,  # image data dictionary
                    'patientpixlut': self.structurepixlut
                })
Exemplo n.º 12
0
    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")