Esempio n. 1
0
def get_image_path(main_frame):
    path = None
    file_info = _("Image files")
    file_types = [("png", wx.BITMAP_TYPE_PNG)]
    images_wildcard_helper = WildcardHelper(file_info, file_types)
    wildcard = images_wildcard_helper.wildcard_string()
    dialog = wx.FileDialog(main_frame, message=_("Export to Image"), wildcard=wildcard, style=wx.FD_SAVE)
    if dialog.ShowModal() == wx.ID_OK:
        path = images_wildcard_helper.get_path(dialog)
    dialog.Destroy()
    return path
Esempio n. 2
0
def get_path(main_frame):
    image_type = None
    path = None
    file_info = _("export files")
    file_types = [("csv", "")]
    images_wildcard_helper = WildcardHelper(file_info, file_types)
    wildcard = images_wildcard_helper.wildcard_string()
    dialog = wx.FileDialog(main_frame, message=_("Export"), wildcard=wildcard, style=wx.FD_SAVE)
    if dialog.ShowModal() == wx.ID_OK:
        path = images_wildcard_helper.get_path(dialog)
        image_type = images_wildcard_helper.get_extension_data(path)
    dialog.Destroy()
    return path, image_type
Esempio n. 3
0
def get_path(main_frame):
    image_type = None
    path = None
    file_info = _("export files")
    file_types = [("csv", "")]
    images_wildcard_helper = WildcardHelper(file_info, file_types)
    wildcard = images_wildcard_helper.wildcard_string()
    dialog = wx.FileDialog(main_frame, message=_("Export"), wildcard=wildcard, style=wx.FD_SAVE)
    if dialog.ShowModal() == wx.ID_OK:
        path = images_wildcard_helper.get_path(dialog)
        image_type = images_wildcard_helper.get_extension_data(path)
    dialog.Destroy()
    return path, image_type
Esempio n. 4
0
 def run(self, main_frame):
     if not has_pysvg_module():
         display_error_message(_("Could not find pysvg Python package. It is needed to export to SVG."), self)
         return
     helper = WildcardHelper(_("SVG files"), ["svg"])
     wildcard = helper.wildcard_string()
     dialog = wx.FileDialog(main_frame, message=_("Export to SVG"), wildcard=wildcard, style=wx.FD_SAVE)
     if dialog.ShowModal() == wx.ID_OK:
         path = helper.get_path(dialog)
         overwrite_question = _("File '%s' exists. Overwrite?") % path
         if (not os.path.exists(path) or _ask_question(overwrite_question, main_frame) == wx.YES):
             main_frame.main_panel.timeline_panel.timeline_canvas.SaveAsSvg(path)
     dialog.Destroy()
Esempio n. 5
0
 def _get_new_timeline_path_from_user(self):
     defaultDir = os.path.dirname(self.timeline.path)
     wildcard_helper = WildcardHelper(_("Timeline files"), ["timeline"])
     wildcard = wildcard_helper.wildcard_string()
     style = wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT
     message = _("Save Timeline As")
     dialog = wx.FileDialog(self, message=message, defaultDir=defaultDir,
                            wildcard=wildcard, style=style)
     if dialog.ShowModal() == wx.ID_OK:
         new_timeline_path = wildcard_helper.get_path(dialog)
     else:
         new_timeline_path = None
     dialog.Destroy()
     return new_timeline_path
Esempio n. 6
0
 def run(self, main_frame):
     if not has_pysvg_module():
         display_error_message(_("Could not find pysvg Python package. It is needed to export to SVG."), self)
         return
     helper = WildcardHelper(_("SVG files"), ["svg"])
     wildcard = helper.wildcard_string()
     dialog = wx.FileDialog(main_frame, message=_("Export to SVG"), wildcard=wildcard, style=wx.FD_SAVE)
     if dialog.ShowModal() == wx.ID_OK:
         path = helper.get_path(dialog)
         overwrite_question = _("File '%s' exists. Overwrite?") % path
         if (not os.path.exists(path) or _ask_question(overwrite_question, main_frame) == wx.YES):
             scene = main_frame.main_panel.get_scene()
             view_properties = main_frame.main_panel.get_view_properties()
             export(path, scene, view_properties)
     dialog.Destroy()
Esempio n. 7
0
 def _get_new_timeline_path_from_user(self):
     defaultDir = os.path.dirname(self.timeline.path)
     wildcard_helper = WildcardHelper(_("Timeline files"), ["timeline"])
     wildcard = wildcard_helper.wildcard_string()
     style = wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT
     message = _("Save Timeline As")
     dialog = wx.FileDialog(self,
                            message=message,
                            defaultDir=defaultDir,
                            wildcard=wildcard,
                            style=style)
     if dialog.ShowModal() == wx.ID_OK:
         new_timeline_path = wildcard_helper.get_path(dialog)
     else:
         new_timeline_path = None
     dialog.Destroy()
     return new_timeline_path
Esempio n. 8
0
 def __init__(self, db, parent=None):
     Dialog.__init__(
         self,
         ImportEventsDialogController,
         parent, {
             "header_label":
             _("Select timeline to import from:"),
             "dialog_wildcard":
             WildcardHelper(_("Timeline files"),
                            ["timeline", "ics"]).wildcard_string(),
         },
         title=_("Import events"))
     self.controller.on_init(db)
Esempio n. 9
0
 def testReturnsNoExtensionDataIfPathDoesNotPathExtension(self):
     helper = WildcardHelper("Text files", [("txt", 4)])
     self.assertEquals(
         helper.get_extension_data("bar"),
         None)
Esempio n. 10
0
 def testReturnsExtensionDataIfExtensionDataGivenAndPathMatch(self):
     helper = WildcardHelper("Image files", [("png", 1), ("bmp", 2)])
     self.assertEquals(
         helper.get_extension_data("bar.png"),
         1)
Esempio n. 11
0
 def testGeneratesWildcardStringForUseInFileDialog(self):
     helper = WildcardHelper("Source code files", ["cpp", "py"])
     self.assertEquals(
         helper.wildcard_string(),
         "Source code files (*.cpp, *.py)|*.cpp;*.py")
Esempio n. 12
0
class MainFrame(wx.Frame, guic.GuiCreator, MainFrameApiUsedByController):

    def __init__(self, application_arguments):
        self.config = read_config(application_arguments.get_config_file_path())
        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.Bind(EVT_CATS_VIEW_CHANGED, self._on_cats_view_changed)
        # To enable translations of wx stock items.
        self.locale = wx.Locale(wx.LANGUAGE_DEFAULT)
        self.locale.AddCatalogLookupPathPrefix(LOCALE_DIR)
        self.locale.AddCatalog("wxstd")
        self.help_browser = HelpBrowserFrame(self)
        self.controller = MainFrameController(self, db_open, self.config)
        self.menu_controller = MenuController()
        self._set_initial_values_to_member_variables()
        self._create_print_data()
        self._set_experimental_features()
        self._create_gui()
        self.Maximize(self.config.window_maximized)
        self.SetTitle(APPLICATION_NAME)
        self.SetIcons(self._load_icon_bundle())
        self.main_panel.show_welcome_panel()
        self.enable_disable_menus()
        self.controller.on_started(application_arguments)
        self._create_and_start_timer()
        self.prev_time_period = None

    def DisplayErrorMessage(self, message):
        display_error_message(message, parent=self)

    def DisplayStatus(self, message):
        self.status_bar_adapter.set_text(message)

    # API:s used by time types
    def week_starts_on_monday(self):
        return self.controller.week_starts_on_monday()

    def display_time_editor_dialog(self, time_type, initial_time,
                                   handle_new_time_fn, title):
        dialog = TimeEditorDialog(self, self.config, time_type, initial_time, title)
        dialog.ShowModal()
        result = dialog.GetReturnCode()
        if result == wx.ID_OK:
            handle_new_time_fn(dialog.GetTime())
        dialog.Destroy()

    def display_now_date_editor_dialog(self, handle_new_time_fn, title):
        dialog = ChangeNowDateDialog(self, self.config, self.timeline, handle_new_time_fn, title)
        dialog.Show()

    def save_time_period(self):
        self.prev_time_period = self.main_panel.get_time_period()

    # Concurrent editing
    def ok_to_edit(self):
        try:
            return self.controller.ok_to_edit()
        except LockedException:
            return False

    def get_lockfile_path(self):
        return self.controller._get_lockpath()

    def edit_ends(self):
        self.controller.edit_ends()

    def get_view_properties(self, ):
        return self.main_panel.get_view_properties()

    def _on_cats_view_changed(self, evt):
        self.main_panel.get_view_properties().change_view_cats_individually(evt.GetClientData())

    # Creation process methods
    def _set_initial_values_to_member_variables(self):
        self.timeline = None
        self.timeline_wildcard_helper = WildcardHelper(
            _("Timeline files"), ["timeline", "ics"])
        self.images_svg_wildcard_helper = WildcardHelper(
            _("SVG files"), ["svg"])

    def _create_print_data(self):
        self.printData = wx.PrintData()
        self.printData.SetPaperId(wx.PAPER_A4)
        self.printData.SetPrintMode(wx.PRINT_MODE_PRINTER)
        self.printData.SetOrientation(wx.LANDSCAPE)

    def _create_and_start_timer(self):
        self.alert_dialog_open = False
        self.timer = TimelineTimer(self)
        self.timer.register(self._timer_tick)
        self.timer.start(10000)

    def _timer_tick(self, evt):
        self._handle_event_alerts()

    def _set_experimental_features(self):
        ExperimentalFeatures().set_active_state_on_all_features_from_config_string(self.config.experimental_features)

    def _load_icon_bundle(self):
        bundle = wx.IconBundle()
        for size in ["16", "32", "48"]:
            iconpath = os.path.join(ICONS_DIR, "%s.png" % size)
            icon = wx.IconFromBitmap(wx.BitmapFromImage(wx.Image(iconpath)))
            bundle.AddIcon(icon)
        return bundle

    # File Menu action handlers
    def _create_new_timeline(self):
        path = self._get_file_path()
        if path is not None:
            self.controller.open_timeline(path)

    def _create_new_bosparanian_timeline(self):
        path = self._get_file_path()
        if path is not None:
            timetype = BosparanianTimeType()
            self.controller.open_timeline(path, timetype)

    def _create_new_numeric_timeline(self):
        path = self._get_file_path()
        if path is not None:
            timetype = NumTimeType()
            self.controller.open_timeline(path, timetype)

    def _get_file_path(self):
        path = None
        wildcard = self.timeline_wildcard_helper.wildcard_string()
        dialog = wx.FileDialog(self, message=_("Create Timeline"),
                               wildcard=wildcard, style=wx.FD_SAVE)
        if dialog.ShowModal() == wx.ID_OK:
            path = self.timeline_wildcard_helper.get_path(dialog)
            if os.path.exists(path):
                msg_first_part = _("The specified timeline already exists.")
                msg_second_part = _("Opening timeline instead of creating new.")
                wx.MessageBox("%s\n\n%s" % (msg_first_part, msg_second_part),
                              _("Information"),
                              wx.OK | wx.ICON_INFORMATION, self)
        dialog.Destroy()
        return path

    def _create_new_dir_timeline(self):
        dialog = wx.DirDialog(self, message=_("Create Timeline"))
        if dialog.ShowModal() == wx.ID_OK:
            self.controller.open_timeline(dialog.GetPath())
        dialog.Destroy()

    def _open_existing_timeline(self):
        directory = ""
        if self.timeline is not None:
            directory = os.path.dirname(self.timeline.path)
        wildcard = self.timeline_wildcard_helper.wildcard_string()
        dialog = wx.FileDialog(self, message=_("Open Timeline"),
                               defaultDir=directory,
                               wildcard=wildcard, style=wx.FD_OPEN)
        if dialog.ShowModal() == wx.ID_OK:
            self.controller.open_timeline(dialog.GetPath())
        dialog.Destroy()

    def _save_as(self):
        new_timeline_path = self._get_new_timeline_path_from_user()
        self._save_timeline_to_new_path(new_timeline_path)

    def _get_new_timeline_path_from_user(self):
        defaultDir = os.path.dirname(self.timeline.path)
        wildcard_helper = WildcardHelper(_("Timeline files"), ["timeline"])
        wildcard = wildcard_helper.wildcard_string()
        style = wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT
        message = _("Save Timeline As")
        dialog = wx.FileDialog(self, message=message, defaultDir=defaultDir,
                               wildcard=wildcard, style=style)
        if dialog.ShowModal() == wx.ID_OK:
            new_timeline_path = wildcard_helper.get_path(dialog)
        else:
            new_timeline_path = None
        dialog.Destroy()
        return new_timeline_path

    def _save_timeline_to_new_path(self, new_timeline_path):
        if new_timeline_path is not None:
            assert new_timeline_path.endswith(".timeline")
            export_db_to_timeline_xml(self.timeline, new_timeline_path)
            self.controller.open_timeline(new_timeline_path)

    def _window_on_close(self, event):
        self.timer.stop()
        self._save_application_config()
        try:
            if self.ok_to_edit():
                self.save_current_timeline_data()
        finally:
            self.edit_ends()
        self.Destroy()

    def _save_application_config(self):
        self.config.set_window_size(self.GetSize())
        self.config.set_window_pos(self.GetPosition())
        self.config.window_maximized = self.IsMaximized()
        self.config.sidebar_width = self.main_panel.get_sidebar_width()
        try:
            self.config.write()
        except IOError as ex:
            friendly = _("Unable to write configuration file.")
            msg = "%s\n\n%s" % (friendly, ex_msg(ex))
            display_error_message(msg, self)

    def save_current_timeline_data(self):
        if self.timeline:
            self.main_panel.save_view_properties(self.timeline)

    # Timeline Menu action handlers
    def _measure_distance_between_events(self):
        event1, event2 = self._get_selected_events()
        self._display_distance(event1.distance_to(event2))

    def _get_selected_events(self):
        event_id_1, event_id_2 = self.main_panel.get_ids_of_two_first_selected_events()
        event1 = self.timeline.find_event_with_id(event_id_1)
        event2 = self.timeline.find_event_with_id(event_id_2)
        return event1, event2

    def _display_distance(self, distance):
        caption = _("Distance between selected events")
        if distance is None:
            distance_text = _("Events are overlapping or distance is 0")
        else:
            distance_text = self.timeline.get_time_type().format_delta(distance)
        display_information_message(caption, distance_text)

    def _set_category(self):
        dialog = SetCategoryDialog(self, self.timeline)
        dialog.ShowModal()
        dialog.Destroy()
        self.main_panel.redraw_timeline()

    def _set_category_to_selected_events(self):
        selected_event_ids = self.main_panel.get_selected_event_ids()
        dialog = SetCategoryDialog(self, self.timeline, selected_event_ids)
        dialog.ShowModal()
        dialog.Destroy()

    def _edit_categories(self):
        display_categories_editor_moved_message(self)

    def _edit_eras(self):
        dialog = ErasEditorDialog(self, self.timeline, self.config)
        dialog.ShowModal()
        dialog.Destroy()
        self.main_panel.redraw_timeline()

    def _fit_all_events(self):
        all_period = self._period_for_all_visible_events()
        if all_period is None:
            return
        if all_period.is_period():
            self.main_panel.Navigate(lambda tp: tp.update(all_period.start_time, all_period.end_time))
        else:
            self.main_panel.Navigate(lambda tp: tp.center(all_period.mean_time()))

    def _period_for_all_visible_events(self):
        try:
            visible_events = self._all_visible_events()
            if len(visible_events) > 0:
                start = self._first_time(visible_events)
                end = self._last_time(visible_events)
                return TimePeriod(start, end).zoom(-1)
            else:
                return None
        except ValueError as ex:
            display_error_message(ex.message)
        return None

    def _all_visible_events(self):
        all_events = self.timeline.get_all_events()
        return self.main_panel.get_visible_events(all_events)

    def _first_time(self, events):
        start_time = lambda event: event.get_start_time()
        return start_time(min(events, key=start_time))

    def _last_time(self, events):
        end_time = lambda event: event.get_end_time()
        return end_time(max(events, key=end_time))

    def get_export_periods(self):
        events = self._all_visible_events()
        first_time = self._first_time(events)
        last_time = self._last_time(events)
        return self.main_panel.get_export_periods(first_time, last_time)

    # Timer event handlers
    def _handle_event_alerts(self):
        if self.timeline is None:
            return
        if self.alert_dialog_open:
            return
        self._display_events_alerts()
        self.alert_dialog_open = False

    def _display_events_alerts(self):
        self.alert_dialog_open = True
        all_events = self.timeline.get_all_events()
        AlertController(self).display_events_alerts(all_events, self.timeline.get_time_type())
Esempio n. 13
0
 def testReturnsNoExtensionDataIfPathDoesNotPathExtension(self):
     helper = WildcardHelper("Text files", [("txt", 4)])
     self.assertEquals(helper.get_extension_data("bar"), None)
Esempio n. 14
0
 def testAddsFirstExtensionIfNoExtensionInPathFromDialog(self):
     helper = WildcardHelper("Image files", ["png", "bmp"])
     self.assertEquals(
         helper.get_path(self.aFileDialogReturningPath("bar")),
         "bar.png")
Esempio n. 15
0
 def testGeneratesWildcardStringForUseInFileDialog(self):
     helper = WildcardHelper("Source code files", ["cpp", "py"])
     self.assertEquals(helper.wildcard_string(),
                       "Source code files (*.cpp, *.py)|*.cpp;*.py")
Esempio n. 16
0
 def _set_initial_values_to_member_variables(self):
     self.timeline = None
     self.timeline_wildcard_helper = WildcardHelper(_("Timeline files"),
                                                    ["timeline", "ics"])
     self.images_svg_wildcard_helper = WildcardHelper(
         _("SVG files"), ["svg"])
Esempio n. 17
0
 def testAddsFirstExtensionIfNoExtensionInPathFromDialog(self):
     helper = WildcardHelper("Image files", ["png", "bmp"])
     self.assertEquals(
         helper.get_path(self.aFileDialogReturningPath("bar")), "bar.png")
Esempio n. 18
0
 def testDoesNotAddExtensionIfExtensionAlreadyInPathFromDialog(self):
     helper = WildcardHelper("Image files", ["png", "bmp"])
     self.assertEquals(
         helper.get_path(self.aFileDialogReturningPath("bar.bmp")),
         "bar.bmp")
Esempio n. 19
0
 def testReturnsNoExtensionDataIfNoExtensionDataGiven(self):
     helper = WildcardHelper("Text files", ["txt"])
     self.assertEquals(helper.get_extension_data("foo.txt"), None)
Esempio n. 20
0
 def testReturnsNoExtensionDataIfNoExtensionDataGiven(self):
     helper = WildcardHelper("Text files", ["txt"])
     self.assertEquals(
         helper.get_extension_data("foo.txt"),
         None)
Esempio n. 21
0
 def testDoesNotAddExtensionIfExtensionAlreadyInPathFromDialog(self):
     helper = WildcardHelper("Image files", ["png", "bmp"])
     self.assertEquals(
         helper.get_path(self.aFileDialogReturningPath("bar.bmp")),
         "bar.bmp")
Esempio n. 22
0
class MainFrame(wx.Frame, guic.GuiCreator, MainFrameApiUsedByController):
    def __init__(self, application_arguments):
        self.config = read_config(application_arguments.get_config_file_path())
        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.Bind(EVT_CATS_VIEW_CHANGED, self._on_cats_view_changed)
        # To enable translations of wx stock items.
        self.locale = wx.Locale(wx.LANGUAGE_DEFAULT)
        self.locale.AddCatalogLookupPathPrefix(LOCALE_DIR)
        self.locale.AddCatalog("wxstd")
        self.help_browser = HelpBrowserFrame(self)
        self.controller = MainFrameController(self, db_open, self.config)
        self.menu_controller = MenuController()
        self._set_initial_values_to_member_variables()
        self._create_print_data()
        self._set_experimental_features()
        self._create_gui()
        self.Maximize(self.config.window_maximized)
        self.SetTitle(APPLICATION_NAME)
        self.SetIcons(self._load_icon_bundle())
        self.main_panel.show_welcome_panel()
        self.enable_disable_menus()
        self.controller.on_started(application_arguments)
        self._create_and_start_timer()
        self.prev_time_period = None

    def DisplayErrorMessage(self, message):
        display_error_message(message, parent=self)

    def DisplayStatus(self, message):
        self.status_bar_adapter.set_text(message)

    # API:s used by time types
    def week_starts_on_monday(self):
        return self.controller.week_starts_on_monday()

    def display_time_editor_dialog(self, time_type, initial_time,
                                   handle_new_time_fn, title):
        dialog = TimeEditorDialog(self, self.config, time_type, initial_time,
                                  title)
        dialog.ShowModal()
        result = dialog.GetReturnCode()
        if result == wx.ID_OK:
            handle_new_time_fn(dialog.GetTime())
        dialog.Destroy()

    def display_now_date_editor_dialog(self, handle_new_time_fn, title):
        dialog = ChangeNowDateDialog(self, self.config, self.timeline,
                                     handle_new_time_fn, title)
        dialog.Show()

    def save_time_period(self):
        self.prev_time_period = self.main_panel.get_time_period()

    # Concurrent editing
    def ok_to_edit(self):
        try:
            return self.controller.ok_to_edit()
        except LockedException:
            return False

    def get_lockfile_path(self):
        return self.controller._get_lockpath()

    def edit_ends(self):
        self.controller.edit_ends()

    def get_view_properties(self, ):
        return self.main_panel.get_view_properties()

    def _on_cats_view_changed(self, evt):
        self.main_panel.get_view_properties().change_view_cats_individually(
            evt.GetClientData())

    # Creation process methods
    def _set_initial_values_to_member_variables(self):
        self.timeline = None
        self.timeline_wildcard_helper = WildcardHelper(_("Timeline files"),
                                                       ["timeline", "ics"])
        self.images_svg_wildcard_helper = WildcardHelper(
            _("SVG files"), ["svg"])

    def _create_print_data(self):
        self.printData = wx.PrintData()
        self.printData.SetPaperId(wx.PAPER_A4)
        self.printData.SetPrintMode(wx.PRINT_MODE_PRINTER)
        self.printData.SetOrientation(wx.LANDSCAPE)

    def _create_and_start_timer(self):
        self.alert_dialog_open = False
        self.timer = TimelineTimer(self)
        self.timer.register(self._timer_tick)
        self.timer.start(10000)

    def _timer_tick(self, evt):
        self._handle_event_alerts()

    def _set_experimental_features(self):
        ExperimentalFeatures(
        ).set_active_state_on_all_features_from_config_string(
            self.config.experimental_features)

    def _load_icon_bundle(self):
        bundle = wx.IconBundle()
        for size in ["16", "32", "48"]:
            iconpath = os.path.join(ICONS_DIR, "%s.png" % size)
            icon = wx.Icon(wx.Bitmap(wx.Image(iconpath)))
            bundle.AddIcon(icon)
        return bundle

    # File Menu action handlers
    def _create_new_timeline(self, timetype=None):
        path = self._get_file_path()
        if path is not None:
            self.controller.open_timeline(path, timetype)

    def _create_new_bosparanian_timeline(self):
        self._create_new_timeline(BosparanianTimeType())

    def _create_new_coptic_timeline(self):
        self._create_new_timeline(CopticTimeType())

    def _create_new_pharaonic_timeline(self):
        self._create_new_timeline(PharaonicTimeType())

    def _create_new_numeric_timeline(self):
        self._create_new_timeline(NumTimeType())

    def _get_file_path(self):
        path = None
        wildcard = self.timeline_wildcard_helper.wildcard_string()
        dialog = wx.FileDialog(self,
                               message=_("Create Timeline"),
                               wildcard=wildcard,
                               style=wx.FD_SAVE)
        if dialog.ShowModal() == wx.ID_OK:
            path = self.timeline_wildcard_helper.get_path(dialog)
            if os.path.exists(path):
                msg_first_part = _("The specified timeline already exists.")
                msg_second_part = _(
                    "Opening timeline instead of creating new.")
                wx.MessageBox("%s\n\n%s" % (msg_first_part, msg_second_part),
                              _("Information"), wx.OK | wx.ICON_INFORMATION,
                              self)
        dialog.Destroy()
        return path

    def _create_new_dir_timeline(self):
        dialog = wx.DirDialog(self, message=_("Create Timeline"))
        if dialog.ShowModal() == wx.ID_OK:
            self.controller.open_timeline(dialog.GetPath())
        dialog.Destroy()

    def _open_existing_timeline(self):
        directory = ""
        if self.timeline is not None:
            directory = os.path.dirname(self.timeline.path)
        wildcard = self.timeline_wildcard_helper.wildcard_string()
        dialog = wx.FileDialog(self,
                               message=_("Open Timeline"),
                               defaultDir=directory,
                               wildcard=wildcard,
                               style=wx.FD_OPEN)
        if dialog.ShowModal() == wx.ID_OK:
            self.controller.open_timeline(dialog.GetPath())
        dialog.Destroy()

    def _save_as(self):
        new_timeline_path = self._get_new_timeline_path_from_user()
        self._save_timeline_to_new_path(new_timeline_path)

    def _get_new_timeline_path_from_user(self):
        defaultDir = os.path.dirname(self.timeline.path)
        wildcard_helper = WildcardHelper(_("Timeline files"), ["timeline"])
        wildcard = wildcard_helper.wildcard_string()
        style = wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT
        message = _("Save Timeline As")
        dialog = wx.FileDialog(self,
                               message=message,
                               defaultDir=defaultDir,
                               wildcard=wildcard,
                               style=style)
        if dialog.ShowModal() == wx.ID_OK:
            new_timeline_path = wildcard_helper.get_path(dialog)
        else:
            new_timeline_path = None
        dialog.Destroy()
        return new_timeline_path

    def _save_timeline_to_new_path(self, new_timeline_path):
        if new_timeline_path is not None:
            assert new_timeline_path.endswith(".timeline")
            export_db_to_timeline_xml(self.timeline, new_timeline_path)
            self.controller.open_timeline(new_timeline_path)

    def _window_on_close(self, event):
        self.timer.stop()
        self._save_application_config()
        try:
            if self.ok_to_edit():
                self.save_current_timeline_data()
        finally:
            self.edit_ends()
        self.Destroy()

    def _save_application_config(self):
        self.config.set_window_size(self.GetSize())
        self.config.set_window_pos(self.GetPosition())
        self.config.window_maximized = self.IsMaximized()
        self.config.sidebar_width = self.main_panel.get_sidebar_width()
        try:
            self.config.write()
        except IOError as ex:
            friendly = _("Unable to write configuration file.")
            msg = "%s\n\n%s" % (friendly, ex_msg(ex))
            display_error_message(msg, self)

    def save_current_timeline_data(self):
        if self.timeline:
            self.main_panel.save_view_properties(self.timeline)

    # Timeline Menu action handlers
    def _measure_distance_between_events(self):
        event1, event2 = self._get_selected_events()
        self._display_distance(event1.distance_to(event2))

    def _get_selected_events(self):
        event_id_1, event_id_2 = self.main_panel.get_ids_of_two_first_selected_events(
        )
        event1 = self.timeline.find_event_with_id(event_id_1)
        event2 = self.timeline.find_event_with_id(event_id_2)
        return event1, event2

    def _display_distance(self, distance):
        caption = _("Distance between selected events")
        if distance is None:
            distance_text = _("Events are overlapping or distance is 0")
        else:
            distance_text = self.timeline.get_time_type().format_delta(
                distance)
        display_information_message(caption, distance_text)

    def _set_category(self):
        dialog = SetCategoryDialog(self, self.timeline)
        dialog.ShowModal()
        dialog.Destroy()
        self.main_panel.redraw_timeline()

    def _set_category_to_selected_events(self):
        selected_event_ids = self.main_panel.get_selected_event_ids()
        dialog = SetCategoryDialog(self, self.timeline, selected_event_ids)
        dialog.ShowModal()
        dialog.Destroy()

    def _edit_categories(self):
        display_categories_editor_moved_message(self)

    def _edit_eras(self):
        dialog = ErasEditorDialog(self, self.timeline, self.config)
        dialog.ShowModal()
        dialog.Destroy()
        self.main_panel.redraw_timeline()

    def _fit_all_events(self):
        all_period = self._period_for_all_visible_events()
        if all_period is None:
            return
        if all_period.is_period():
            self.main_panel.Navigate(lambda tp: tp.update(
                all_period.start_time, all_period.end_time))
        else:
            self.main_panel.Navigate(
                lambda tp: tp.center(all_period.mean_time()))

    def _period_for_all_visible_events(self):
        try:
            visible_events = self._all_visible_events()
            if len(visible_events) > 0:
                start = self._first_time(visible_events)
                end = self._last_time(visible_events)
                return TimePeriod(start, end).zoom(-1)
            else:
                return None
        except ValueError as ex:
            display_error_message(str(ex))
        return None

    def _all_visible_events(self):
        all_events = self.timeline.get_all_events()
        return self.main_panel.get_visible_events(all_events)

    def _first_time(self, events):
        start_time = lambda event: event.get_start_time()
        return start_time(min(events, key=start_time))

    def _last_time(self, events):
        end_time = lambda event: event.get_end_time()
        return end_time(max(events, key=end_time))

    def get_export_periods(self):
        events = self._all_visible_events()
        first_time = self._first_time(events)
        last_time = self._last_time(events)
        return self.main_panel.get_export_periods(first_time, last_time)

    # Timer event handlers
    def _handle_event_alerts(self):
        if self.timeline is None:
            return
        if self.alert_dialog_open:
            return
        self._display_events_alerts()
        self.alert_dialog_open = False

    def _display_events_alerts(self):
        self.alert_dialog_open = True
        all_events = self.timeline.get_all_events()
        AlertController(self).display_events_alerts(
            all_events, self.timeline.get_time_type())
Esempio n. 23
0
 def _set_initial_values_to_member_variables(self):
     self.timeline = None
     self.timeline_wildcard_helper = WildcardHelper(
         _("Timeline files"), ["timeline", "ics"])
     self.images_svg_wildcard_helper = WildcardHelper(
         _("SVG files"), ["svg"])
Esempio n. 24
0
 def testReturnsExtensionDataIfExtensionDataGivenAndPathMatch(self):
     helper = WildcardHelper("Image files", [("png", 1), ("bmp", 2)])
     self.assertEquals(helper.get_extension_data("bar.png"), 1)