コード例 #1
0
    def __init__(self, properties, parent, id=-1, **kwargs):

        from cpa.icons import get_icon, get_cpa_icon

        wx.Frame.__init__(self,
                          parent,
                          id=id,
                          title='CellProfiler Analyst %s' % (display_version),
                          **kwargs)
        self.properties = properties
        self.SetIcon(get_cpa_icon())
        self.tbicon = None
        self.SetName('CPA')
        self.Center(wx.HORIZONTAL)
        self.CreateStatusBar()
        self.log_io = True

        #
        # Setup toolbar
        #
        tb = self.CreateToolBar(wx.TB_HORZ_TEXT | wx.TB_FLAT)
        tb.SetToolBitmapSize((32, 32))
        tb.SetSize((-1, 132))
        tb.AddTool(ID_IMAGE_GALLERY.GetId(),
                   'Image Gallery',
                   get_icon("image_gallery").ConvertToBitmap(),
                   shortHelp='Image Gallery')
        tb.AddTool(ID_CLASSIFIER.GetId(),
                   'Classifier',
                   get_icon("classifier").ConvertToBitmap(),
                   shortHelp='Classifier')
        # tb.AddLabelTool(ID_CLASSIFIER, 'PixelClassifier', get_icon("pixelclassifier").ConvertToBitmap(), shortHelp='Pixel-based Classifier', longHelp='Launch pixel-based Classifier')
        tb.AddTool(ID_PLATE_VIEWER.GetId(),
                   'Plate Viewer',
                   get_icon("platemapbrowser").ConvertToBitmap(),
                   shortHelp='Plate Viewer')
        # tb.AddLabelTool(ID_IMAGE_VIEWER, 'ImageViewer', get_icon("image_viewer").ConvertToBitmap(), shortHelp='Image Viewer', longHelp='Launch ImageViewer')
        tb.AddTool(ID_SCATTER.GetId(),
                   'Scatter Plot',
                   get_icon("scatter").ConvertToBitmap(),
                   shortHelp='Scatter Plot')
        tb.AddTool(ID_HISTOGRAM.GetId(),
                   'Histogram',
                   get_icon("histogram").ConvertToBitmap(),
                   shortHelp='Histogram')
        tb.AddTool(ID_DENSITY.GetId(),
                   'Density Plot',
                   get_icon("density").ConvertToBitmap(),
                   shortHelp='Density Plot')
        tb.AddTool(ID_BOXPLOT.GetId(),
                   'Box Plot',
                   get_icon("boxplot").ConvertToBitmap(),
                   shortHelp='Box Plot')
        tb.AddTool(ID_TABLE_VIEWER.GetId(),
                   'Table Viewer',
                   get_icon("data_grid").ConvertToBitmap(),
                   shortHelp='Table Viewer')
        # tb.AddLabelTool(ID_NORMALIZE, 'Normalize', get_icon("normalize").ConvertToBitmap(), shortHelp='Normalization Tool', longHelp='Launch Feature Normalization Tool')
        tb.Realize()

        #
        # Setup menu items
        #
        self.SetMenuBar(wx.MenuBar())
        fileMenu = wx.Menu()
        loadPropertiesMenuItem = fileMenu.Append(
            -1, 'Load properties file', helpString='Load a properties file.')
        savePropertiesMenuItem = fileMenu.Append(
            -1, 'Save properties\tCtrl+S', helpString='Save the properties.')
        ##        loadWorkspaceMenuItem = fileMenu.Append(-1, 'Load properties\tCtrl+O', helpString='Open another properties file.')
        fileMenu.AppendSeparator()
        saveWorkspaceMenuItem = fileMenu.Append(
            -1,
            'Save workspace\tCtrl+Shift+S',
            helpString='Save the currently open plots and settings.')
        loadWorkspaceMenuItem = fileMenu.Append(
            -1,
            'Load workspace\tCtrl+Shift+O',
            helpString='Open plots saved in a previous workspace.')
        fileMenu.AppendSeparator()
        saveLogMenuItem = fileMenu.Append(
            -1, 'Save log', helpString='Save the contents of the log window.')
        fileMenu.AppendSeparator()
        self.exitMenuItem = fileMenu.Append(wx.ID_EXIT,
                                            'Exit\tCtrl+Q',
                                            helpString='Exit classifier')
        self.GetMenuBar().Append(fileMenu, 'File')

        toolsMenu = wx.Menu()
        imageGalleryMenuItem = toolsMenu.Append(
            ID_IMAGE_GALLERY,
            'Image Gallery Viewer\tCtrl+Shift+I',
            helpString='Launches the Image Gallery')
        classifierMenuItem = toolsMenu.Append(
            ID_CLASSIFIER,
            'Classifier\tCtrl+Shift+C',
            helpString='Launches Classifier.')
        plateMapMenuItem = toolsMenu.Append(
            ID_PLATE_VIEWER,
            'Plate Viewer\tCtrl+Shift+P',
            helpString='Launches the Plate Viewer tool.')
        #imageViewerMenuItem = toolsMenu.Append(ID_IMAGE_VIEWER, 'Image Viewer\tCtrl+Shift+I', helpString='Launches the ImageViewer tool.')
        scatterMenuItem = toolsMenu.Append(
            ID_SCATTER,
            'Scatter Plot\tCtrl+Shift+A',
            helpString='Launches the Scatter Plot tool.')
        histogramMenuItem = toolsMenu.Append(
            ID_HISTOGRAM,
            'Histogram Plot\tCtrl+Shift+H',
            helpString='Launches the Histogram Plot tool.')
        densityMenuItem = toolsMenu.Append(
            ID_DENSITY,
            'Density Plot\tCtrl+Shift+D',
            helpString='Launches the Density Plot tool.')
        boxplotMenuItem = toolsMenu.Append(
            ID_BOXPLOT,
            'Box Plot\tCtrl+Shift+B',
            helpString='Launches the Box Plot tool.')
        dataTableMenuItem = toolsMenu.Append(
            ID_TABLE_VIEWER,
            'Table Viewer\tCtrl+Shift+T',
            helpString='Launches the Table Viewer tool.')
        normalizeMenuItem = toolsMenu.Append(
            ID_NORMALIZE,
            'Normalization Tool\tCtrl+Shift+T',
            helpString=
            'Launches a tool for generating normalized values for measurement columns in your tables.'
        )
        self.GetMenuBar().Append(toolsMenu, 'Tools')

        logMenu = wx.Menu()
        debugMenuItem = logMenu.AppendRadioItem(
            -1,
            'Debug\tCtrl+1',
            help='Logging window will display debug-level messages.')
        infoMenuItem = logMenu.AppendRadioItem(
            -1,
            'Info\tCtrl+2',
            help='Logging window will display info-level messages.')
        warnMenuItem = logMenu.AppendRadioItem(
            -1,
            'Warnings\tCtrl+3',
            help='Logging window will display warning-level messages.')
        errorMenuItem = logMenu.AppendRadioItem(
            -1,
            'Errors\tCtrl+4',
            help='Logging window will display error-level messages.')
        criticalMenuItem = logMenu.AppendRadioItem(
            -1,
            'Critical\tCtrl+5',
            help='Logging window will only display critical messages.')
        logioItem = logMenu.AppendCheckItem(-1,
                                            item='Log image loading',
                                            help='Log image loader events')
        infoMenuItem.Check()
        logioItem.Check()
        self.GetMenuBar().Append(logMenu, 'Logging')

        advancedMenu = wx.Menu()
        #normalizeMenuItem = advancedMenu.Append(-1, 'Launch feature normalization tool', helpString='Launches a tool for generating normalized values for measurement columns in your tables.')
        queryMenuItem = advancedMenu.Append(
            -1,
            'Launch SQL query tool',
            helpString=
            'Opens a tool for making SQL queries to the CPA database. Advanced users only.'
        )
        clearTableLinksMenuItem = advancedMenu.Append(
            -1,
            'Clear table linking information',
            helpString=
            'Removes the tables from your database that tell CPA how to link your tables.'
        )
        self.GetMenuBar().Append(advancedMenu, 'Advanced')
        import cpa.helpmenu
        self.GetMenuBar().Append(cpa.helpmenu.make_help_menu(self, main=True),
                                 'Help')

        # console and logging
        self.console = wx.TextCtrl(self,
                                   -1,
                                   '',
                                   style=wx.TE_MULTILINE | wx.TE_READONLY
                                   | wx.TE_RICH2)
        self.console.SetFont(
            wx.Font(10, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL,
                    wx.FONTWEIGHT_NORMAL))

        # Black background and white font
        self.console.SetDefaultStyle(wx.TextAttr(wx.WHITE, wx.BLACK))
        self.console.SetBackgroundColour('#000000')

        log_level = logging.INFO  # INFO is the default log level
        self.logr = logging.getLogger()
        self.set_log_level(log_level)
        self.log_text = ""

        def update(x):
            self.log_text += x + '\n'

        hdlr = FuncLog(update)
        #        hdlr.setFormatter(logging.Formatter('[%(levelname)s] %(message)s'))
        #        hdlr.setFormatter(logging.Formatter('%(levelname)s | %(name)s | %(message)s [@ %(asctime)s in %(filename)s:%(lineno)d]'))
        self.logr.addHandler(hdlr)
        # log_levels are 10,20,30,40,50
        logMenu.GetMenuItems()[(log_level // 10) - 1].Check()

        self.Bind(wx.EVT_MENU, lambda _: self.set_log_level(logging.DEBUG),
                  debugMenuItem)
        self.Bind(wx.EVT_MENU, lambda _: self.set_log_level(logging.INFO),
                  infoMenuItem)
        self.Bind(wx.EVT_MENU, lambda _: self.set_log_level(logging.WARN),
                  warnMenuItem)
        self.Bind(wx.EVT_MENU, lambda _: self.set_log_level(logging.ERROR),
                  errorMenuItem)
        self.Bind(wx.EVT_MENU, lambda _: self.set_log_level(logging.CRITICAL),
                  criticalMenuItem)
        self.Bind(wx.EVT_MENU, self.on_toggle_iologging, logioItem)
        self.Bind(wx.EVT_MENU, self.on_load_properties, loadPropertiesMenuItem)
        self.Bind(wx.EVT_MENU, self.on_save_properties, savePropertiesMenuItem)
        self.Bind(wx.EVT_MENU, self.on_save_workspace, saveWorkspaceMenuItem)
        self.Bind(wx.EVT_MENU, self.on_load_workspace, loadWorkspaceMenuItem)
        self.Bind(wx.EVT_MENU, self.save_log, saveLogMenuItem)
        self.Bind(wx.EVT_MENU, self.launch_normalization_tool,
                  normalizeMenuItem)
        self.Bind(wx.EVT_MENU, self.clear_link_tables, clearTableLinksMenuItem)
        self.Bind(wx.EVT_MENU, self.launch_query_maker, queryMenuItem)
        self.Bind(wx.EVT_TOOL, self.launch_classifier, id=ID_CLASSIFIER)
        self.Bind(wx.EVT_TOOL,
                  self.launch_plate_map_browser,
                  id=ID_PLATE_VIEWER)
        self.Bind(wx.EVT_TOOL, self.launch_table_viewer, id=ID_TABLE_VIEWER)
        self.Bind(wx.EVT_TOOL, self.launch_image_viewer, id=ID_IMAGE_VIEWER)
        self.Bind(wx.EVT_TOOL, self.launch_image_gallery, id=ID_IMAGE_GALLERY)
        self.Bind(wx.EVT_TOOL, self.launch_scatter_plot, id=ID_SCATTER)
        self.Bind(wx.EVT_TOOL, self.launch_histogram_plot, id=ID_HISTOGRAM)
        self.Bind(wx.EVT_TOOL, self.launch_density_plot, id=ID_DENSITY)
        self.Bind(wx.EVT_TOOL, self.launch_box_plot, id=ID_BOXPLOT)
        self.Bind(wx.EVT_TOOL, self.launch_normalization_tool, id=ID_NORMALIZE)
        self.Bind(wx.EVT_MENU, self.on_close, self.exitMenuItem)
        self.Bind(wx.EVT_CLOSE, self.on_close)
        self.Bind(wx.EVT_IDLE, self.on_idle)
コード例 #2
0
    def __init__(self, properties, parent, id=-1, **kwargs):
        wx.Frame.__init__(self, parent, id=id, title='CellProfiler Analyst 2.0 (r%s)'%(__version__), **kwargs)

        self.properties = properties
        self.SetIcon(get_cpa_icon())
        if not sys.platform.startswith('win'):
            # this is good for Mac, but on windows creates a (currently) unused icon in the system tray
            self.tbicon = wx.TaskBarIcon()
            self.tbicon.SetIcon(get_cpa_icon(), 'CellProfiler Analyst 2.0')
        else:
            self.tbicon = None
        self.SetName('CPA')
        self.Center(wx.HORIZONTAL)
        self.CreateStatusBar()

        #
        # Setup toolbar
        #
        tb = self.CreateToolBar(wx.TB_HORZ_TEXT|wx.TB_FLAT)
        tb.SetToolBitmapSize((32,32))
        tb.SetSize((-1,132))
        tb.AddLabelTool(ID_CLASSIFIER, 'Classifier', cpa.icons.classifier.ConvertToBitmap(), shortHelp='Classifier', longHelp='Launch Classifier')
        tb.AddLabelTool(ID_PLATE_VIEWER, 'PlateViewer', cpa.icons.platemapbrowser.ConvertToBitmap(), shortHelp='Plate Viewer', longHelp='Launch Plate Viewer')
        tb.AddLabelTool(ID_TABLE_VIEWER, 'TableViewer', cpa.icons.data_grid.ConvertToBitmap(), shortHelp='Table Viewer', longHelp='Launch TableViewer')
        tb.AddLabelTool(ID_IMAGE_VIEWER, 'ImageViewer', cpa.icons.image_viewer.ConvertToBitmap(), shortHelp='Image Viewer', longHelp='Launch ImageViewer')
        tb.AddLabelTool(ID_SCATTER, 'ScatterPlot', cpa.icons.scatter.ConvertToBitmap(), shortHelp='Scatter Plot', longHelp='Launch Scatter Plot')
        tb.AddLabelTool(ID_HISTOGRAM, 'Histogram', cpa.icons.histogram.ConvertToBitmap(), shortHelp='Histogram', longHelp='Launch Histogram')
        tb.AddLabelTool(ID_DENSITY, 'DensityPlot', cpa.icons.density.ConvertToBitmap(), shortHelp='Density Plot', longHelp='Launch Density Plot')
        tb.AddLabelTool(ID_BOXPLOT, 'BoxPlot', cpa.icons.boxplot.ConvertToBitmap(), shortHelp='Box Plot', longHelp='Launch Box Plot')
        tb.Realize()
        # TODO: IMG-1071 - The following was meant to resize based on the toolbar size but GetEffectiveMinSize breaks on Macs
        #self.SetDimensions(-1, -1, tb.GetEffectiveMinSize().width, -1, wx.SIZE_USE_EXISTING)

        #
        # Setup menu items
        #
        self.SetMenuBar(wx.MenuBar())
        fileMenu = wx.Menu()
        savePropertiesMenuItem = fileMenu.Append(-1, 'Save properties\tCtrl+S', help='Save the properties.')
##        loadWorkspaceMenuItem = fileMenu.Append(-1, 'Load properties\tCtrl+O', help='Open another properties file.')
        fileMenu.AppendSeparator()
        saveWorkspaceMenuItem = fileMenu.Append(-1, 'Save workspace\tCtrl+Shift+S', help='Save the currently open plots and settings.')
        loadWorkspaceMenuItem = fileMenu.Append(-1, 'Load workspace\tCtrl+Shift+O', help='Open plots saved in a previous workspace.')
        fileMenu.AppendSeparator()
        saveLogMenuItem = fileMenu.Append(-1, 'Save log', help='Save the contents of the log window.')
        fileMenu.AppendSeparator()
        self.exitMenuItem = fileMenu.Append(wx.ID_EXIT, 'Exit\tCtrl+Q', help='Exit classifier')
        self.GetMenuBar().Append(fileMenu, 'File')

        toolsMenu = wx.Menu()
        classifierMenuItem  = toolsMenu.Append(ID_CLASSIFIER, 'Classifier\tCtrl+Shift+C', help='Launches Classifier.')
        plateMapMenuItem    = toolsMenu.Append(ID_PLATE_VIEWER, 'Plate Viewer\tCtrl+Shift+P', help='Launches the Plate Viewer tool.')
        dataTableMenuItem   = toolsMenu.Append(ID_TABLE_VIEWER, 'Data Table\tCtrl+Shift+T', help='Launches the Data Table tool.')
        imageViewerMenuItem = toolsMenu.Append(ID_IMAGE_VIEWER, 'Image Viewer\tCtrl+Shift+I', help='Launches the ImageViewer tool.')
        scatterMenuItem     = toolsMenu.Append(ID_SCATTER, 'Scatter Plot\tCtrl+Shift+A', help='Launches the Scatter Plot tool.')
        histogramMenuItem   = toolsMenu.Append(ID_HISTOGRAM, 'Histogram Plot\tCtrl+Shift+H', help='Launches the Histogram Plot tool.')
        densityMenuItem     = toolsMenu.Append(ID_DENSITY, 'Density Plot\tCtrl+Shift+D', help='Launches the Density Plot tool.')
        boxplotMenuItem     = toolsMenu.Append(ID_BOXPLOT, 'Box Plot\tCtrl+Shift+B', help='Launches the Box Plot tool.')
        self.GetMenuBar().Append(toolsMenu, 'Tools')

        logMenu = wx.Menu()
        debugMenuItem    = logMenu.AppendRadioItem(-1, 'Debug\tCtrl+1', help='Logging window will display debug-level messages.')
        infoMenuItem     = logMenu.AppendRadioItem(-1, 'Info\tCtrl+2', help='Logging window will display info-level messages.')
        warnMenuItem     = logMenu.AppendRadioItem(-1, 'Warnings\tCtrl+3', help='Logging window will display warning-level messages.')
        errorMenuItem    = logMenu.AppendRadioItem(-1, 'Errors\tCtrl+4', help='Logging window will display error-level messages.')
        criticalMenuItem = logMenu.AppendRadioItem(-1, 'Critical\tCtrl+5', help='Logging window will only display critical messages.')
        infoMenuItem.Check()
        self.GetMenuBar().Append(logMenu, 'Logging')

        advancedMenu = wx.Menu()
        normalizeMenuItem = advancedMenu.Append(-1, 'Launch feature normalization tool', help='Launches a tool for generating normalized values for measurement columns in your tables.')
        queryMenuItem = advancedMenu.Append(-1, 'Launch SQL query tool', help='Opens a tool for making SQL queries to the CPA database. Advanced users only.')
        clearTableLinksMenuItem = advancedMenu.Append(-1, 'Clear table linking information', help='Removes the tables from your database that tell CPA how to link your tables.')
        self.GetMenuBar().Append(advancedMenu, 'Advanced')

        self.GetMenuBar().Append(cpa.helpmenu.make_help_menu(self), 'Help')

        # console and logging
        self.console = wx.TextCtrl(self, -1, '', style=wx.TE_MULTILINE|wx.TE_READONLY)
        self.console.SetFont(wx.Font(10, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL))
        self.console.SetBackgroundColour('#111111')

        self.console.SetForegroundColour('#DDDDDD')
        log_level = logging.DEBUG
        self.logr = logging.getLogger()
        self.set_log_level(log_level)
        self.log_text = ''
        def update(x):
            self.log_text += x+'\n'
        hdlr = FuncLog(update)
#        hdlr.setFormatter(logging.Formatter('[%(levelname)s] %(message)s'))
#        hdlr.setFormatter(logging.Formatter('%(levelname)s | %(name)s | %(message)s [@ %(asctime)s in %(filename)s:%(lineno)d]'))
        self.logr.addHandler(hdlr)
        # log_levels are 10,20,30,40,50
        logMenu.GetMenuItems()[(log_level/10)-1].Check()

        self.Bind(wx.EVT_MENU, lambda(_):self.set_log_level(logging.DEBUG), debugMenuItem)
        self.Bind(wx.EVT_MENU, lambda(_):self.set_log_level(logging.INFO), infoMenuItem)
        self.Bind(wx.EVT_MENU, lambda(_):self.set_log_level(logging.WARN), warnMenuItem)
        self.Bind(wx.EVT_MENU, lambda(_):self.set_log_level(logging.ERROR), errorMenuItem)
        self.Bind(wx.EVT_MENU, lambda(_):self.set_log_level(logging.CRITICAL), criticalMenuItem)
        self.Bind(wx.EVT_MENU, self.on_save_properties, savePropertiesMenuItem)
        self.Bind(wx.EVT_MENU, self.on_save_workspace, saveWorkspaceMenuItem)
        self.Bind(wx.EVT_MENU, self.on_load_workspace, loadWorkspaceMenuItem)
        self.Bind(wx.EVT_MENU, self.save_log, saveLogMenuItem)
        self.Bind(wx.EVT_MENU, self.launch_normalization_tool, normalizeMenuItem)
        self.Bind(wx.EVT_MENU, self.clear_link_tables, clearTableLinksMenuItem)
        self.Bind(wx.EVT_MENU, self.launch_query_maker, queryMenuItem)
        self.Bind(wx.EVT_TOOL, self.launch_classifier, id=ID_CLASSIFIER)
        self.Bind(wx.EVT_TOOL, self.launch_plate_map_browser, id=ID_PLATE_VIEWER)
        self.Bind(wx.EVT_TOOL, self.launch_table_viewer, id=ID_TABLE_VIEWER)
        self.Bind(wx.EVT_TOOL, self.launch_image_viewer, id=ID_IMAGE_VIEWER)
        self.Bind(wx.EVT_TOOL, self.launch_scatter_plot, id=ID_SCATTER)
        self.Bind(wx.EVT_TOOL, self.launch_histogram_plot, id=ID_HISTOGRAM)
        self.Bind(wx.EVT_TOOL, self.launch_density_plot, id=ID_DENSITY)
        self.Bind(wx.EVT_TOOL, self.launch_box_plot, id=ID_BOXPLOT)
        self.Bind(wx.EVT_MENU, self.on_close, self.exitMenuItem)
        self.Bind(wx.EVT_CLOSE, self.on_close)
        self.Bind(wx.EVT_IDLE, self.on_idle)
コード例 #3
0
    def __init__(self, properties, parent, id=-1, **kwargs):
        wx.Frame.__init__(self,
                          parent,
                          id=id,
                          title='CellProfiler Analyst 2.0 (r%s)' %
                          (__version__),
                          **kwargs)

        self.properties = properties
        self.SetIcon(get_cpa_icon())
        if not sys.platform.startswith('win'):
            # this is good for Mac, but on windows creates a (currently) unused icon in the system tray
            self.tbicon = wx.TaskBarIcon()
            self.tbicon.SetIcon(get_cpa_icon(), 'CellProfiler Analyst 2.0')
        else:
            self.tbicon = None
        self.SetName('CPA')
        self.Center(wx.HORIZONTAL)
        self.CreateStatusBar()

        #
        # Setup toolbar
        #
        tb = self.CreateToolBar(wx.TB_HORZ_TEXT | wx.TB_FLAT)
        tb.SetToolBitmapSize((32, 32))
        tb.SetSize((-1, 132))
        tb.AddLabelTool(ID_CLASSIFIER,
                        'Classifier',
                        cpa.icons.classifier.ConvertToBitmap(),
                        shortHelp='Classifier',
                        longHelp='Launch Classifier')
        tb.AddLabelTool(ID_PLATE_VIEWER,
                        'PlateViewer',
                        cpa.icons.platemapbrowser.ConvertToBitmap(),
                        shortHelp='Plate Viewer',
                        longHelp='Launch Plate Viewer')
        tb.AddLabelTool(ID_TABLE_VIEWER,
                        'TableViewer',
                        cpa.icons.data_grid.ConvertToBitmap(),
                        shortHelp='Table Viewer',
                        longHelp='Launch TableViewer')
        tb.AddLabelTool(ID_IMAGE_VIEWER,
                        'ImageViewer',
                        cpa.icons.image_viewer.ConvertToBitmap(),
                        shortHelp='Image Viewer',
                        longHelp='Launch ImageViewer')
        tb.AddLabelTool(ID_SCATTER,
                        'ScatterPlot',
                        cpa.icons.scatter.ConvertToBitmap(),
                        shortHelp='Scatter Plot',
                        longHelp='Launch Scatter Plot')
        tb.AddLabelTool(ID_HISTOGRAM,
                        'Histogram',
                        cpa.icons.histogram.ConvertToBitmap(),
                        shortHelp='Histogram',
                        longHelp='Launch Histogram')
        tb.AddLabelTool(ID_DENSITY,
                        'DensityPlot',
                        cpa.icons.density.ConvertToBitmap(),
                        shortHelp='Density Plot',
                        longHelp='Launch Density Plot')
        tb.AddLabelTool(ID_BOXPLOT,
                        'BoxPlot',
                        cpa.icons.boxplot.ConvertToBitmap(),
                        shortHelp='Box Plot',
                        longHelp='Launch Box Plot')
        tb.Realize()
        # TODO: IMG-1071 - The following was meant to resize based on the toolbar size but GetEffectiveMinSize breaks on Macs
        #self.SetDimensions(-1, -1, tb.GetEffectiveMinSize().width, -1, wx.SIZE_USE_EXISTING)

        #
        # Setup menu items
        #
        self.SetMenuBar(wx.MenuBar())
        fileMenu = wx.Menu()
        savePropertiesMenuItem = fileMenu.Append(-1,
                                                 'Save properties\tCtrl+S',
                                                 help='Save the properties.')
        ##        loadWorkspaceMenuItem = fileMenu.Append(-1, 'Load properties\tCtrl+O', help='Open another properties file.')
        fileMenu.AppendSeparator()
        saveWorkspaceMenuItem = fileMenu.Append(
            -1,
            'Save workspace\tCtrl+Shift+S',
            help='Save the currently open plots and settings.')
        loadWorkspaceMenuItem = fileMenu.Append(
            -1,
            'Load workspace\tCtrl+Shift+O',
            help='Open plots saved in a previous workspace.')
        fileMenu.AppendSeparator()
        saveLogMenuItem = fileMenu.Append(
            -1, 'Save log', help='Save the contents of the log window.')
        fileMenu.AppendSeparator()
        self.exitMenuItem = fileMenu.Append(wx.ID_EXIT,
                                            'Exit\tCtrl+Q',
                                            help='Exit classifier')
        self.GetMenuBar().Append(fileMenu, 'File')

        toolsMenu = wx.Menu()
        classifierMenuItem = toolsMenu.Append(ID_CLASSIFIER,
                                              'Classifier\tCtrl+Shift+C',
                                              help='Launches Classifier.')
        plateMapMenuItem = toolsMenu.Append(
            ID_PLATE_VIEWER,
            'Plate Viewer\tCtrl+Shift+P',
            help='Launches the Plate Viewer tool.')
        dataTableMenuItem = toolsMenu.Append(
            ID_TABLE_VIEWER,
            'Data Table\tCtrl+Shift+T',
            help='Launches the Data Table tool.')
        imageViewerMenuItem = toolsMenu.Append(
            ID_IMAGE_VIEWER,
            'Image Viewer\tCtrl+Shift+I',
            help='Launches the ImageViewer tool.')
        scatterMenuItem = toolsMenu.Append(
            ID_SCATTER,
            'Scatter Plot\tCtrl+Shift+A',
            help='Launches the Scatter Plot tool.')
        histogramMenuItem = toolsMenu.Append(
            ID_HISTOGRAM,
            'Histogram Plot\tCtrl+Shift+H',
            help='Launches the Histogram Plot tool.')
        densityMenuItem = toolsMenu.Append(
            ID_DENSITY,
            'Density Plot\tCtrl+Shift+D',
            help='Launches the Density Plot tool.')
        boxplotMenuItem = toolsMenu.Append(ID_BOXPLOT,
                                           'Box Plot\tCtrl+Shift+B',
                                           help='Launches the Box Plot tool.')
        self.GetMenuBar().Append(toolsMenu, 'Tools')

        logMenu = wx.Menu()
        debugMenuItem = logMenu.AppendRadioItem(
            -1,
            'Debug\tCtrl+1',
            help='Logging window will display debug-level messages.')
        infoMenuItem = logMenu.AppendRadioItem(
            -1,
            'Info\tCtrl+2',
            help='Logging window will display info-level messages.')
        warnMenuItem = logMenu.AppendRadioItem(
            -1,
            'Warnings\tCtrl+3',
            help='Logging window will display warning-level messages.')
        errorMenuItem = logMenu.AppendRadioItem(
            -1,
            'Errors\tCtrl+4',
            help='Logging window will display error-level messages.')
        criticalMenuItem = logMenu.AppendRadioItem(
            -1,
            'Critical\tCtrl+5',
            help='Logging window will only display critical messages.')
        infoMenuItem.Check()
        self.GetMenuBar().Append(logMenu, 'Logging')

        advancedMenu = wx.Menu()
        normalizeMenuItem = advancedMenu.Append(
            -1,
            'Launch feature normalization tool',
            help=
            'Launches a tool for generating normalized values for measurement columns in your tables.'
        )
        queryMenuItem = advancedMenu.Append(
            -1,
            'Launch SQL query tool',
            help=
            'Opens a tool for making SQL queries to the CPA database. Advanced users only.'
        )
        clearTableLinksMenuItem = advancedMenu.Append(
            -1,
            'Clear table linking information',
            help=
            'Removes the tables from your database that tell CPA how to link your tables.'
        )
        self.GetMenuBar().Append(advancedMenu, 'Advanced')

        self.GetMenuBar().Append(cpa.helpmenu.make_help_menu(self), 'Help')

        # console and logging
        self.console = wx.TextCtrl(self,
                                   -1,
                                   '',
                                   style=wx.TE_MULTILINE | wx.TE_READONLY)
        self.console.SetFont(
            wx.Font(10, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL,
                    wx.FONTWEIGHT_NORMAL))
        self.console.SetBackgroundColour('#111111')

        self.console.SetForegroundColour('#DDDDDD')
        log_level = logging.DEBUG
        self.logr = logging.getLogger()
        self.set_log_level(log_level)
        self.log_text = ''

        def update(x):
            self.log_text += x + '\n'

        hdlr = FuncLog(update)
        #        hdlr.setFormatter(logging.Formatter('[%(levelname)s] %(message)s'))
        #        hdlr.setFormatter(logging.Formatter('%(levelname)s | %(name)s | %(message)s [@ %(asctime)s in %(filename)s:%(lineno)d]'))
        self.logr.addHandler(hdlr)
        # log_levels are 10,20,30,40,50
        logMenu.GetMenuItems()[(log_level / 10) - 1].Check()

        self.Bind(wx.EVT_MENU, lambda (_): self.set_log_level(logging.DEBUG),
                  debugMenuItem)
        self.Bind(wx.EVT_MENU, lambda (_): self.set_log_level(logging.INFO),
                  infoMenuItem)
        self.Bind(wx.EVT_MENU, lambda (_): self.set_log_level(logging.WARN),
                  warnMenuItem)
        self.Bind(wx.EVT_MENU, lambda (_): self.set_log_level(logging.ERROR),
                  errorMenuItem)
        self.Bind(wx.EVT_MENU, lambda
                  (_): self.set_log_level(logging.CRITICAL), criticalMenuItem)
        self.Bind(wx.EVT_MENU, self.on_save_properties, savePropertiesMenuItem)
        self.Bind(wx.EVT_MENU, self.on_save_workspace, saveWorkspaceMenuItem)
        self.Bind(wx.EVT_MENU, self.on_load_workspace, loadWorkspaceMenuItem)
        self.Bind(wx.EVT_MENU, self.save_log, saveLogMenuItem)
        self.Bind(wx.EVT_MENU, self.launch_normalization_tool,
                  normalizeMenuItem)
        self.Bind(wx.EVT_MENU, self.clear_link_tables, clearTableLinksMenuItem)
        self.Bind(wx.EVT_MENU, self.launch_query_maker, queryMenuItem)
        self.Bind(wx.EVT_TOOL, self.launch_classifier, id=ID_CLASSIFIER)
        self.Bind(wx.EVT_TOOL,
                  self.launch_plate_map_browser,
                  id=ID_PLATE_VIEWER)
        self.Bind(wx.EVT_TOOL, self.launch_table_viewer, id=ID_TABLE_VIEWER)
        self.Bind(wx.EVT_TOOL, self.launch_image_viewer, id=ID_IMAGE_VIEWER)
        self.Bind(wx.EVT_TOOL, self.launch_scatter_plot, id=ID_SCATTER)
        self.Bind(wx.EVT_TOOL, self.launch_histogram_plot, id=ID_HISTOGRAM)
        self.Bind(wx.EVT_TOOL, self.launch_density_plot, id=ID_DENSITY)
        self.Bind(wx.EVT_TOOL, self.launch_box_plot, id=ID_BOXPLOT)
        self.Bind(wx.EVT_MENU, self.on_close, self.exitMenuItem)
        self.Bind(wx.EVT_CLOSE, self.on_close)
        self.Bind(wx.EVT_IDLE, self.on_idle)