コード例 #1
0
    def __init__(self, parent):
        config = coreaux_api.get_plugin_configuration('wxdbsearch')(
            'ContextualShortcuts')
        accelerators = {
            config["search"]: lambda event: self.search(),
            config["find"]: lambda event: self.results.find_in_tree(),
            config["edit"]: lambda event: self.results.edit_items(),
        }
        accelerators.update(wxgui_api.get_right_nb_generic_accelerators())
        acctable = wxgui_api.generate_right_nb_accelerators(accelerators)

        self.panel = SearchViewPanel(parent, self, acctable)
        self.box = wx.BoxSizer(wx.VERTICAL)
        self.panel.SetSizer(self.box)

        self.filters = SearchFilters(self)
        self.results = SearchResults(self)

        self.panel._init_tab_menu()

        self.threads = 0
        self.search_threaded_action = self._search_threaded_stop
        self.finish_search_action = self._finish_search_dummy

        self.box.Add(self.filters.box, flag=wx.EXPAND | wx.BOTTOM, border=4)
        self.box.Add(self.results.listview, 1, flag=wx.EXPAND)

        wxgui_api.bind_to_close_database(self._handle_close_database)
コード例 #2
0
ファイル: __init__.py プロジェクト: xguse/outspline
    def __init__(self, filename):
        self.filename = filename

        config = coreaux_api.get_plugin_configuration('wxlinks')('TreeIcons')
        char = config['symbol']

        if char != '':
            bits_to_colour = {b: wx.Colour() for b in xrange(1, 6)}
            bits_to_colour[1].SetFromString(config['color_valid'])
            bits_to_colour[2].SetFromString(config['color_broken'])
            bits_to_colour[3].SetFromString(config['color_target'])
            bits_to_colour[4].SetFromString(config['color_valid_and_target'])
            bits_to_colour[5].SetFromString(config['color_broken_and_target'])

            self.property_shift, self.property_mask = \
                                            wxgui_api.add_item_property(
                                            filename, 3, char, bits_to_colour)

            links_api.bind_to_upsert_link(self._handle_upsert_link)
            links_api.bind_to_delete_link(self._handle_delete_link)
            links_api.bind_to_break_link(self._handle_break_links)
            links_api.bind_to_history_insert(self._handle_history)
            links_api.bind_to_history_update(self._handle_history)
            links_api.bind_to_history_delete(self._handle_history)

            wxgui_api.bind_to_open_database(self._handle_open_database)
            wxgui_api.bind_to_close_database(self._handle_close_database)

            if wxcopypaste_api:
                wxcopypaste_api.bind_to_items_pasted(self._handle_paste)
コード例 #3
0
ファイル: __init__.py プロジェクト: xguse/outspline
    def __init__(self, filename):
        self.filename = filename

        config = coreaux_api.get_plugin_configuration('wxscheduler')(
                                                                'TreeIcons')
        char = config['symbol']

        if char != '':
            bits_to_colour = {1: wx.Colour()}
            bits_to_colour[1].SetFromString(config['color'])

            self.property_shift, self.property_mask = \
                                            wxgui_api.add_item_property(
                                            filename, 1, char, bits_to_colour)

            organism_api.bind_to_update_item_rules_conditional(
                                                    self._handle_update_rules)
            organism_api.bind_to_history_insert(self._handle_history)
            organism_api.bind_to_history_update(self._handle_history)

            wxgui_api.bind_to_open_database(self._handle_open_database)
            wxgui_api.bind_to_close_database(self._handle_close_database)

            if wxcopypaste_api:
                wxcopypaste_api.bind_to_items_pasted(self._handle_paste)
コード例 #4
0
ファイル: __init__.py プロジェクト: xguse/outspline
    def __init__(self, parent):
        config = coreaux_api.get_plugin_configuration('wxdbsearch')(
                                                        'ContextualShortcuts')
        accelerators = {
            config["search"]: lambda event: self.search(),
            config["find"]: lambda event: self.results.find_in_tree(),
            config["edit"]: lambda event: self.results.edit_items(),
        }
        accelerators.update(wxgui_api.get_right_nb_generic_accelerators())
        acctable = wxgui_api.generate_right_nb_accelerators(accelerators)

        self.panel = SearchViewPanel(parent, self, acctable)
        self.box = wx.BoxSizer(wx.VERTICAL)
        self.panel.SetSizer(self.box)

        self.filters = SearchFilters(self)
        self.results = SearchResults(self)

        self.panel._init_tab_menu()

        self.threads = 0
        self.search_threaded_action = self._search_threaded_stop
        self.finish_search_action = self._finish_search_dummy

        self.box.Add(self.filters.box, flag=wx.EXPAND | wx.BOTTOM, border=4)
        self.box.Add(self.results.listview, 1, flag=wx.EXPAND)

        wxgui_api.bind_to_close_database(self._handle_close_database)
コード例 #5
0
ファイル: __init__.py プロジェクト: kynikos/outspline
    def __init__(self, filename):
        self.filename = filename

        config = coreaux_api.get_plugin_configuration('wxscheduler')(
                                                                'TreeIcons')
        char = config['symbol']

        if char != '':
            bits_to_colour = {1: wx.Colour()}
            bits_to_colour[1].SetFromString(config['color'])

            self.property_shift, self.property_mask = \
                                            wxgui_api.add_item_property(
                                            filename, 1, char, bits_to_colour)

            organism_api.bind_to_update_item_rules_conditional(
                                                    self._handle_update_rules)
            organism_api.bind_to_history_insert(self._handle_history)
            organism_api.bind_to_history_update(self._handle_history)

            wxgui_api.bind_to_open_database(self._handle_open_database)
            wxgui_api.bind_to_close_database(self._handle_close_database)

            if wxcopypaste_api:
                wxcopypaste_api.bind_to_items_pasted(self._handle_paste)
コード例 #6
0
ファイル: __init__.py プロジェクト: xguse/outspline
    def __init__(self, filename):
        self.filename = filename

        config = coreaux_api.get_plugin_configuration('wxlinks')('TreeIcons')
        char = config['symbol']

        if char != '':
            bits_to_colour = {b: wx.Colour() for b in xrange(1, 6)}
            bits_to_colour[1].SetFromString(config['color_valid'])
            bits_to_colour[2].SetFromString(config['color_broken'])
            bits_to_colour[3].SetFromString(config['color_target'])
            bits_to_colour[4].SetFromString(config['color_valid_and_target'])
            bits_to_colour[5].SetFromString(config['color_broken_and_target'])

            self.property_shift, self.property_mask = \
                                            wxgui_api.add_item_property(
                                            filename, 3, char, bits_to_colour)

            links_api.bind_to_upsert_link(self._handle_upsert_link)
            links_api.bind_to_delete_link(self._handle_delete_link)
            links_api.bind_to_break_link(self._handle_break_links)
            links_api.bind_to_history_insert(self._handle_history)
            links_api.bind_to_history_update(self._handle_history)
            links_api.bind_to_history_delete(self._handle_history)

            wxgui_api.bind_to_open_database(self._handle_open_database)
            wxgui_api.bind_to_close_database(self._handle_close_database)

            if wxcopypaste_api:
                wxcopypaste_api.bind_to_items_pasted(self._handle_paste)
コード例 #7
0
    def _enable(self):
        self.list_.enable_refresh()
        self.list_.refresh()
        self._update_tab_label()

        organism_alarms_api.bind_to_alarm(self._update_tab_label_after)
        organism_alarms_api.bind_to_alarm_off(self._update_tab_label)
        wxgui_api.bind_to_close_database(self._update_tab_label)
コード例 #8
0
ファイル: __init__.py プロジェクト: kynikos/outspline
    def __init__(self):
        self.items = {}
        self.itemicons = {}

        ViewMenu(self)

        wxgui_api.bind_to_creating_tree(self._handle_creating_tree)
        wxgui_api.bind_to_close_database(self._handle_close_database)
        wxgui_api.bind_to_open_editor(self._handle_open_editor)
        wxgui_api.bind_to_close_editor(self._handle_close_editor)
コード例 #9
0
ファイル: __init__.py プロジェクト: xguse/outspline
    def __init__(self):
        self.items = {}
        self.itemicons = {}

        ViewMenu(self)

        wxgui_api.bind_to_creating_tree(self._handle_creating_tree)
        wxgui_api.bind_to_close_database(self._handle_close_database)
        wxgui_api.bind_to_open_editor(self._handle_open_editor)
        wxgui_api.bind_to_close_editor(self._handle_close_editor)
コード例 #10
0
ファイル: __init__.py プロジェクト: xguse/outspline
    def __init__(self):
        wxgui_api.install_bundled_icon("wxalarmslog", '@alarmslog',
                                                        ("alarmslog16.png", ))

        self.alarmlogs = {}
        self.mainmenu = LogsMenu(self)

        wxgui_api.bind_to_creating_tree(self._handle_creating_tree)
        wxgui_api.bind_to_load_property_options(self._handle_load_options)
        wxgui_api.bind_to_close_database(self._handle_close_database)
コード例 #11
0
ファイル: __init__.py プロジェクト: mikpim01/outspline
    def __init__(self):
        wxgui_api.install_bundled_icon("wxalarmslog", '@alarmslog',
                                       ("alarmslog16.png", ))

        self.alarmlogs = {}
        self.mainmenu = LogsMenu(self)

        wxgui_api.bind_to_creating_tree(self._handle_creating_tree)
        wxgui_api.bind_to_load_property_options(self._handle_load_options)
        wxgui_api.bind_to_close_database(self._handle_close_database)
コード例 #12
0
ファイル: __init__.py プロジェクト: xguse/outspline
    def __init__(self):
        self.items = {}
        self.itemicons = {}

        wxgui_api.install_bundled_icon("wxlinks", '@links',
                                                    ("Tango", "links16.png"))

        ViewMenu(self)

        wxgui_api.bind_to_creating_tree(self._handle_creating_tree)
        wxgui_api.bind_to_close_database(self._handle_close_database)
        wxgui_api.bind_to_open_editor(self._handle_open_editor)
        wxgui_api.bind_to_close_editor(self._handle_close_editor)
コード例 #13
0
ファイル: __init__.py プロジェクト: xguse/outspline
    def __init__(self):
        self.items = {}
        self.itemicons = {}

        wxgui_api.install_bundled_icon("wxlinks", '@links',
                                       ("Tango", "links16.png"))

        ViewMenu(self)

        wxgui_api.bind_to_creating_tree(self._handle_creating_tree)
        wxgui_api.bind_to_close_database(self._handle_close_database)
        wxgui_api.bind_to_open_editor(self._handle_open_editor)
        wxgui_api.bind_to_close_editor(self._handle_close_editor)
コード例 #14
0
ファイル: __init__.py プロジェクト: xguse/outspline
    def _finish_search_close(self):
        wxgui_api.close_right_nb_page(self.panel)

        global searches
        searches.remove(self)

        # Unbind the handlers, otherwise they would be called also for closed
        # searches when closing all databases (e.g. when quitting the
        # application) raising an exception when trying to remove self from
        # the searches list
        wxgui_api.bind_to_close_database(self._handle_close_database, False)

        self.finish_search_action = self._finish_search_dummy
コード例 #15
0
    def _finish_search_close(self):
        wxgui_api.close_right_nb_page(self.panel)

        global searches
        searches.remove(self)

        # Unbind the handlers, otherwise they would be called also for closed
        # searches when closing all databases (e.g. when quitting the
        # application) raising an exception when trying to remove self from
        # the searches list
        wxgui_api.bind_to_close_database(self._handle_close_database, False)

        self.finish_search_action = self._finish_search_dummy
コード例 #16
0
ファイル: __init__.py プロジェクト: xguse/outspline
    def _handle_close_database(self, kwargs):
        if kwargs['filename'] == self.filename:
            organism_api.bind_to_update_item_rules_conditional(
                                            self._handle_update_rules, False)
            organism_api.bind_to_history_insert(self._handle_history, False)
            organism_api.bind_to_history_update(self._handle_history, False)

            wxgui_api.bind_to_open_database(self._handle_open_database, False)
            wxgui_api.bind_to_close_database(self._handle_close_database,
                                                                        False)

            if wxcopypaste_api:
                wxcopypaste_api.bind_to_items_pasted(self._handle_paste, False)
コード例 #17
0
ファイル: __init__.py プロジェクト: kynikos/outspline
    def _handle_close_database(self, kwargs):
        if kwargs['filename'] == self.filename:
            organism_api.bind_to_update_item_rules_conditional(
                                            self._handle_update_rules, False)
            organism_api.bind_to_history_insert(self._handle_history, False)
            organism_api.bind_to_history_update(self._handle_history, False)

            wxgui_api.bind_to_open_database(self._handle_open_database, False)
            wxgui_api.bind_to_close_database(self._handle_close_database,
                                                                        False)

            if wxcopypaste_api:
                wxcopypaste_api.bind_to_items_pasted(self._handle_paste, False)
コード例 #18
0
ファイル: __init__.py プロジェクト: xguse/outspline
    def _handle_close_database(self, kwargs):
        if kwargs['filename'] == self.filename:
            links_api.bind_to_upsert_link(self._handle_upsert_link, False)
            links_api.bind_to_delete_link(self._handle_delete_link, False)
            links_api.bind_to_break_link(self._handle_break_links, False)

            wxgui_api.bind_to_open_database(self._handle_open_database, False)
            wxgui_api.bind_to_close_database(self._handle_close_database,
                                                                        False)
            links_api.bind_to_history_insert(self._handle_history, False)
            links_api.bind_to_history_update(self._handle_history, False)
            links_api.bind_to_history_delete(self._handle_history, False)

            if wxcopypaste_api:
                wxcopypaste_api.bind_to_items_pasted(self._handle_paste, False)
コード例 #19
0
ファイル: __init__.py プロジェクト: xguse/outspline
    def _handle_close_database(self, kwargs):
        if kwargs['filename'] == self.filename:
            links_api.bind_to_upsert_link(self._handle_upsert_link, False)
            links_api.bind_to_delete_link(self._handle_delete_link, False)
            links_api.bind_to_break_link(self._handle_break_links, False)

            wxgui_api.bind_to_open_database(self._handle_open_database, False)
            wxgui_api.bind_to_close_database(self._handle_close_database,
                                             False)
            links_api.bind_to_history_insert(self._handle_history, False)
            links_api.bind_to_history_update(self._handle_history, False)
            links_api.bind_to_history_delete(self._handle_history, False)

            if wxcopypaste_api:
                wxcopypaste_api.bind_to_items_pasted(self._handle_paste, False)
コード例 #20
0
ファイル: __init__.py プロジェクト: xguse/outspline
    def __init__(self, parent, filename, mainmenu):
        self.filename = filename

        self.view = wx.dataview.DataViewCtrl(parent,
                        style=wx.dataview.DV_MULTIPLE |
                        wx.dataview.DV_ROW_LINES | wx.dataview.DV_NO_HEADER)

        self.data = []
        self.dvmodel = AlarmsLogModel(self.data)
        self.view.AssociateModel(self.dvmodel)
        # According to DataViewModel's documentation (as of September 2014)
        # its reference count must be decreased explicitly to avoid memory
        # leaks; the wxPython demo, however, doesn't do it, and if done here,
        # the application crashes with a segfault when closing all databases
        # See also bug #104
        #self.dvmodel.DecRef()

        # Temporary workaround for bug #279
        #self.view.AppendDateColumn('Timestamp', 0,
        #        width=wx.COL_WIDTH_AUTOSIZE, align=wx.ALIGN_CENTER_VERTICAL)
        self.view.AppendTextColumn('Timestamp', 0, width=wx.COL_WIDTH_AUTOSIZE)
        self.view.AppendTextColumn('Action', 1, width=wx.COL_WIDTH_AUTOSIZE)
        self.view.AppendTextColumn('Item', 2)

        config = coreaux_api.get_plugin_configuration('wxalarmslog')(
                                                        'ContextualShortcuts')
        wxgui_api.install_accelerators(self.view, {
            config["find"]: lambda event: self.find_in_tree(),
        })

        self.reasons = {0: '[snoozed]',
                        1: '[dismissed]',
                        2: '[deleted]'}

        cmenu = ContextMenu(mainmenu, self)

        self.tool_id, menu_items, popup_cmenu = wxgui_api.add_log(filename,
                                self.view, "Alarms",
                                wxgui_api.get_log_icon('@alarmslog'),
                                cmenu.get_items(), cmenu.update)
        cmenu.store_items(menu_items)

        self.view.Bind(wx.dataview.EVT_DATAVIEW_ITEM_CONTEXT_MENU,
                                                                popup_cmenu)
        organism_alarms_api.bind_to_alarm_off(self._handle_alarm_off)
        wxgui_api.bind_to_close_database(self._handle_close_database)

        self._refresh()
コード例 #21
0
ファイル: __init__.py プロジェクト: mikpim01/outspline
    def __init__(self, parent, filename, mainmenu):
        self.filename = filename

        self.view = wx.dataview.DataViewCtrl(parent,
                                             style=wx.dataview.DV_MULTIPLE
                                             | wx.dataview.DV_ROW_LINES
                                             | wx.dataview.DV_NO_HEADER)

        self.data = []
        self.dvmodel = AlarmsLogModel(self.data)
        self.view.AssociateModel(self.dvmodel)
        # According to DataViewModel's documentation (as of September 2014)
        # its reference count must be decreased explicitly to avoid memory
        # leaks; the wxPython demo, however, doesn't do it, and if done here,
        # the application crashes with a segfault when closing all databases
        # See also bug #104
        #self.dvmodel.DecRef()

        # Temporary workaround for bug #279
        #self.view.AppendDateColumn('Timestamp', 0,
        #        width=wx.COL_WIDTH_AUTOSIZE, align=wx.ALIGN_CENTER_VERTICAL)
        self.view.AppendTextColumn('Timestamp', 0, width=wx.COL_WIDTH_AUTOSIZE)
        self.view.AppendTextColumn('Action', 1, width=wx.COL_WIDTH_AUTOSIZE)
        self.view.AppendTextColumn('Item', 2)

        config = coreaux_api.get_plugin_configuration('wxalarmslog')(
            'ContextualShortcuts')
        wxgui_api.install_accelerators(
            self.view, {
                config["find"]: lambda event: self.find_in_tree(),
            })

        self.reasons = {0: '[snoozed]', 1: '[dismissed]', 2: '[deleted]'}

        cmenu = ContextMenu(mainmenu, self)

        self.tool_id, menu_items, popup_cmenu = wxgui_api.add_log(
            filename,
            self.view, "Alarms", wxgui_api.get_log_icon('@alarmslog'),
            cmenu.get_items(), cmenu.update)
        cmenu.store_items(menu_items)

        self.view.Bind(wx.dataview.EVT_DATAVIEW_ITEM_CONTEXT_MENU, popup_cmenu)
        organism_alarms_api.bind_to_alarm_off(self._handle_alarm_off)
        wxgui_api.bind_to_close_database(self._handle_close_database)

        self._refresh()
コード例 #22
0
    def _disable(self):
        self.list_.disable_refresh()

        organism_alarms_api.bind_to_alarm(self._update_tab_label_after, False)
        organism_alarms_api.bind_to_alarm_off(self._update_tab_label, False)
        wxgui_api.bind_to_close_database(self._update_tab_label, False)
コード例 #23
0
ファイル: __init__.py プロジェクト: mikpim01/outspline
    def __init__(self):
        self.dbs = {}
        self.mainmenu = MainMenu(self.dbs)

        wxgui_api.bind_to_creating_tree(self._handle_creating_tree)
        wxgui_api.bind_to_close_database(self._handle_close_database)
コード例 #24
0
ファイル: __init__.py プロジェクト: xguse/outspline
    def __init__(self, parent):
        wxgui_api.install_icon_bundle(
            "wxalarms",
            "&alarmswin",
            (
                ("alarmswin16.png",),
                ("alarmswin24.png",),
                ("alarmswin32.png",),
                ("alarmswin48.png",),
                ("alarmswin64.png",),
                ("alarmswin128.png",),
            ),
        )

        self.ALARMS_MIN_HEIGHT = 140
        self.ALARMS_ICON_BUNDLE = wxgui_api.get_frame_icon_bundle("&alarmswin")

        self.config = coreaux_api.get_plugin_configuration("wxalarms")

        self.window = wx.Frame(parent, size=[int(s) for s in self.config["initial_geometry"].split("x")])

        self.window.SetIcons(self.ALARMS_ICON_BUNDLE)

        self.alarms = {}
        self._update_title()

        self.box = wx.BoxSizer(wx.VERTICAL)
        self.window.SetSizer(self.box)

        self.panel = wx.ScrolledWindow(self.window, style=wx.BORDER_THEME)
        self.panel.SetScrollRate(20, 20)
        self.pbox = wx.BoxSizer(wx.VERTICAL)
        self.panel.SetSizer(self.pbox)
        self.box.Add(self.panel, proportion=1, flag=wx.EXPAND | wx.ALL, border=4)

        self.hidden_panel = wx.BoxSizer(wx.HORIZONTAL)
        self._init_hidden_panel()
        self.box.Add(self.hidden_panel, flag=wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND, border=4)
        self._hide_hidden_panel()

        self.bottom = wx.BoxSizer(wx.HORIZONTAL)
        self._init_bottom()
        self.box.Add(self.bottom, flag=wx.LEFT | wx.RIGHT | wx.EXPAND, border=4)

        # Set the minimum width so that the bottom controls can fit, and also
        # add 20 px for the stretch spacer
        minwidth = self.bottom.ComputeFittingWindowSize(self.window).GetWidth()
        self.window.SetMinSize((minwidth + 20, self.ALARMS_MIN_HEIGHT))

        self.DELAY = 50
        # Set CDELAY shorter than DELAY, so that if an alarm is activated at
        # the same time an alarm is dismissed, there's a better chance that
        # the alarm window requests the user attention
        self.CDELAY = 30

        # Initialize self.timer and self.stimer with a dummy function (int)
        self.timer = wx.CallLater(1, int)
        self.stimer = wx.CallLater(1, int)

        self.LIMIT = self.config.get_int("limit")
        self.hiddenalarms = set()

        self.ID_SHOW_MENU = wx.NewId()
        self.menushow = wx.MenuItem(
            wxgui_api.get_menu_view(),
            self.ID_SHOW_MENU,
            "Show &alarms window\t{}".format(self.config("GlobalShortcuts")["show"]),
            "Show the alarms window",
            kind=wx.ITEM_CHECK,
        )
        wxgui_api.add_menu_view_item(self.menushow)

        TrayMenu(self)

        self.window.Bind(wx.EVT_CLOSE, self._handle_close)

        wxgui_api.bind_to_menu(self.toggle_shown, self.menushow)
        wxgui_api.bind_to_menu_view_update(self._handle_menu_view_update)

        organism_alarms_api.bind_to_alarm(self._handle_alarm)
        organism_alarms_api.bind_to_alarm_off(self._handle_alarm_off)
        wxgui_api.bind_to_close_database(self._handle_close_db)
コード例 #25
0
ファイル: __init__.py プロジェクト: kynikos/outspline
    def __init__(self):
        self.dbs = {}
        self.mainmenu = MainMenu(self.dbs)

        wxgui_api.bind_to_creating_tree(self._handle_creating_tree)
        wxgui_api.bind_to_close_database(self._handle_close_database)
コード例 #26
0
ファイル: __init__.py プロジェクト: xguse/outspline
    def __init__(self, parent):
        wxgui_api.install_icon_bundle("wxalarms", '&alarmswin',
                                (("alarmswin16.png", ), ("alarmswin24.png", ),
                                ("alarmswin32.png", ), ("alarmswin48.png", ),
                                ("alarmswin64.png", ), ("alarmswin128.png", )))

        self.ALARMS_MIN_HEIGHT = 140
        self.ALARMS_ICON_BUNDLE = wxgui_api.get_frame_icon_bundle('&alarmswin')

        self.config = coreaux_api.get_plugin_configuration('wxalarms')

        self.window = wx.Frame(parent, size=[int(s)
                          for s in self.config['initial_geometry'].split('x')])

        self.window.SetIcons(self.ALARMS_ICON_BUNDLE)

        self.alarms = {}
        self._update_title()

        self.box = wx.BoxSizer(wx.VERTICAL)
        self.window.SetSizer(self.box)

        self.panel = wx.ScrolledWindow(self.window, style=wx.BORDER_THEME)
        self.panel.SetScrollRate(20, 20)
        self.pbox = wx.BoxSizer(wx.VERTICAL)
        self.panel.SetSizer(self.pbox)
        self.box.Add(self.panel, proportion=1, flag=wx.EXPAND | wx.ALL,
                                                                    border=4)

        self.hidden_panel = wx.BoxSizer(wx.HORIZONTAL)
        self._init_hidden_panel()
        self.box.Add(self.hidden_panel, flag=wx.LEFT | wx.RIGHT | wx.BOTTOM |
                                                        wx.EXPAND, border=4)
        self._hide_hidden_panel()

        self.bottom = wx.BoxSizer(wx.HORIZONTAL)
        self._init_bottom()
        self.box.Add(self.bottom, flag=wx.LEFT | wx.RIGHT | wx.EXPAND,
                                                                    border=4)

        # Set the minimum width so that the bottom controls can fit, and also
        # add 20 px for the stretch spacer
        minwidth = self.bottom.ComputeFittingWindowSize(self.window).GetWidth()
        self.window.SetMinSize((minwidth + 20, self.ALARMS_MIN_HEIGHT))

        self.DELAY = 50
        # Set CDELAY shorter than DELAY, so that if an alarm is activated at
        # the same time an alarm is dismissed, there's a better chance that
        # the alarm window requests the user attention
        self.CDELAY = 30

        # Initialize self.timer and self.stimer with a dummy function (int)
        self.timer = wx.CallLater(1, int)
        self.stimer = wx.CallLater(1, int)

        self.LIMIT = self.config.get_int('limit')
        self.hiddenalarms = set()

        self.ID_SHOW_MENU = wx.NewId()
        self.menushow = wx.MenuItem(wxgui_api.get_menu_view(),
                                self.ID_SHOW_MENU,
                                "Show &alarms window\t{}".format(
                                    self.config('GlobalShortcuts')['show']),
                                "Show the alarms window", kind=wx.ITEM_CHECK)
        wxgui_api.add_menu_view_item(self.menushow)

        TrayMenu(self)

        self.window.Bind(wx.EVT_CLOSE, self._handle_close)

        wxgui_api.bind_to_menu(self.toggle_shown, self.menushow)
        wxgui_api.bind_to_menu_view_update(self._handle_menu_view_update)

        organism_alarms_api.bind_to_alarm(self._handle_alarm)
        organism_alarms_api.bind_to_alarm_off(self._handle_alarm_off)
        wxgui_api.bind_to_close_database(self._handle_close_db)