# Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 Rickard Lindberg, Roger Lindberg
#
# This file is part of Timeline.
#
# Timeline is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Timeline is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Timeline. If not, see <http://www.gnu.org/licenses/>.
from functools import wraps
import wx
import wx.lib.newevent
from timelinelib.config.dotfile import read_config
from timelinelib.config.wxlocale import set_wx_locale
from timelinelib.db import db_open
from timelinelib.features.experimental.experimentalfeatures import ExperimentalFeatures
from timelinelib.meta.about import APPLICATION_NAME
from timelinelib.wxgui.frames.mainframe.mainframecontroller import MainFrameController
from timelinelib.wxgui.frames.mainframe.alertcontroller import AlertController
from timelinelib.wxgui.utils import load_icon_bundle
from timelinelib.wxgui.components.mainpanel import MainPanel
from timelinelib.wxgui.components.statusbaradapter import StatusBarAdapter
from timelinelib.wxgui.frames.mainframe.menus.filemenu import FileMenu
from timelinelib.wxgui.frames.mainframe.menus.editmenu import EditMenu
from timelinelib.wxgui.frames.mainframe.menus.viewmenu import ViewMenu
from timelinelib.wxgui.frames.mainframe.menus.timelinemenu import TimelineMenu
from timelinelib.wxgui.frames.mainframe.menus.navigatemenu import NavigateMenu
from timelinelib.wxgui.frames.mainframe.menus.helpmenu import HelpMenu
from timelinelib.wxgui.frames.mainframe.menucontroller import MenuController
from timelinelib.config.shortcut import ShortcutController
CatsViewChangedEvent, EVT_CATS_VIEW_CHANGED = wx.lib.newevent.NewCommandEvent()
LabelsChangedEvent, EVT_LABELS_CHANGED = wx.lib.newevent.NewCommandEvent()
[docs]class MainFrame(wx.Frame):
"""
The application main frame window contains
* menu
* toolbar
* main panel
* status bar
"""
[docs] def __init__(self):
self._config = read_config()
wx.Frame.__init__(self, None, size=self._config.get_window_size(),
pos=self._config.get_window_pos(),
style=wx.DEFAULT_FRAME_STYLE, name="main_frame")
self.locale = set_wx_locale()
self._controller = MainFrameController(self, db_open, self._config)
self._shortcut_controller = ShortcutController(self.config)
self._timeline = None
self._menu_controller = None
ExperimentalFeatures().set_active_state_on_all_features_from_config_string(
self._config.experimental_features)
self._create_gui()
self._bind_events()
self._main_panel.show_welcome_panel()
self._controller.populate()
self._alert_controller = AlertController(self).start_timer()
@property
def config(self):
"""
The :class:`~timelinelib.config.dotfile.Config` object, created by the main frame,
that hold user settings stored in persistent storage.
"""
return self._config
@property
def controller(self):
"""
The :class:`~timelinelib.wxgui.frames.mainframe.mainframecontroller.MainFrameController` object
, created by the main frame,
containing the business logic for the MainFrame window (view).
"""
return self._controller
@property
def shortcut_controller(self):
"""
The :class:`~timelinelib.config.shortcut.ShortcutController` object
, created by the main frame, containing the shortcuts in the menus.
"""
return self._shortcut_controller
@property
def menu_controller(self):
"""
The :class:`~timelinelib.wxgui.frames.mainframe.menucontroller.MenuController` object
, created by the main frame, containing menu operations.
"""
return self._menu_controller
@property
def timeline(self):
"""
The :class:`~timelinelib.canvas.data.memorydb.db.MemoryDB` object representing the data shown on
the timeline.
This object is passed in to the main frame through the function
:obj:`~timelinelib.wxgui.frames.mainframe.mainframe.MainFrame.DisplayTimeline`
"""
return self._timeline
@property
def main_panel(self):
"""
The :class:`~timelinelib.wxgui.components.mainpanel.MainPanel` object
, created by the main frame,
where the timeline and the sidebar is found.
"""
return self._main_panel
@property
def canvas(self):
"""
The :class:`~timelinelib.canvas.timelinecanvas.TimelineCanvas` object
where the timeline is drawn. It is actually a property of the main_panel.
"""
return self._main_panel.canvas
@property
def view_properties(self):
"""
The :class:`~timelinelib.canvas.drawing.viewproperties.ViewProperties` object
where the timeline is drawn. It is actually a property of the canvas object.
"""
return self.canvas.GetViewProperties()
[docs] def DisplayTimeline(self, timeline):
"""Render a new timeline."""
self._timeline = timeline
self._menu_controller.on_timeline_change(timeline)
self._main_panel.display_timeline(timeline)
self._controller.set_title()
self.DisplayReadonly(self._controller.get_readonly_text_in_status_bar())
[docs] def DisplayStatus(self, message):
"""Set the text in the first column of the status bar."""
self.status_bar_adapter.set_text(message)
[docs] def DisplayHiddenCount(self, message):
"""Set the text in the second column of the status bar."""
self.status_bar_adapter.set_hidden_event_count_text(message)
[docs] def DisplayReadonly(self, text):
"""Set the text in the third column of the status bar."""
self.status_bar_adapter.set_read_only_text(text)
[docs] def EnableDisableMenus(self):
"""Enable/Disable menus depending on number of selected events."""
timeline_view_visible = self._main_panel.timeline_panel_visible()
nbr_of_selected_events = self._main_panel.get_nbr_of_selected_events()
self._menu_controller.update_menus_enabled_state(timeline_view_visible, nbr_of_selected_events)
[docs] def UpdateOpenRecentSubmenu(self):
"""Update the submenu that has a list of recent opened timeline files."""
self._get_file_menu().UpdateRecentSubmenu()
[docs] def UpdateNavigationMenuItems(self):
"""
Updates the naivigation menu when a timeline with another timetype than
the current timeline is opened.
"""
self._get_navigate_menu().UpdateMenuItems()
if self._timeline:
self._shortcut_controller.add_navigation_functions()
[docs] def Exit(self, evt):
"""Clean up at application exit."""
self._alert_controller.stop_timer()
self._controller.exit()
def _get_navigate_menu(self):
return self._get_menu_by_name(_("&Navigate"))
def _get_file_menu(self):
return self._get_menu_by_name(_("&File"))
def _get_menu_by_name(self, name):
menu_bar = self.GetMenuBar()
if menu_bar:
menu_inx = menu_bar.FindMenu(name)
return menu_bar.GetMenu(menu_inx)
#
# GUI
#
def _create_gui(self):
# main panel must be created before the menu bar!!!
self._create_main_panel()
self._create_main_menu_bar()
self._create_status_bar()
self.SetTitle(APPLICATION_NAME)
self.SetIcons(load_icon_bundle())
self.Maximize(self._config.window_maximized)
def _create_status_bar(self):
self.status_bar_adapter = StatusBarAdapter(self.CreateStatusBar())
def _create_main_panel(self):
self._main_panel = MainPanel(self, self.config, self)
def _create_main_menu_bar(self):
self.SetMenuBar(self._create_menu_bar())
self.UpdateNavigationMenuItems()
self.UpdateOpenRecentSubmenu()
self.EnableDisableMenus()
def _create_menu_bar(self):
main_menu_bar = wx.MenuBar()
self._menu_controller = MenuController(main_menu_bar)
main_menu_bar.Append(FileMenu(self), _("&File"))
main_menu_bar.Append(EditMenu(self), _("&Edit"))
main_menu_bar.Append(ViewMenu(self), _("&View"))
main_menu_bar.Append(TimelineMenu(self, self._main_panel.timeline_panel), _("&Timeline"))
main_menu_bar.Append(NavigateMenu(self), _("&Navigate"))
main_menu_bar.Append(HelpMenu(self), _("&Help"))
return main_menu_bar
def _bind_events(self):
self.Bind(EVT_CATS_VIEW_CHANGED, self._main_panel.on_cats_view_changed)
self.Bind(EVT_LABELS_CHANGED, self._main_panel.on_labels_changed)
self.Bind(wx.EVT_CLOSE, self.Exit)