Beispiel #1
0
def get_icons_pixbuffers():
    result = []
    for icon_filename in WINDOW_ICON_FILENAMES:
        abs_filename = get_ui_file_location(icon_filename, silent=True)
        if abs_filename:
            try:
                result.append(gtk.gdk.pixbuf_new_from_file(abs_filename))
            except gobject.GError, err_msg:
                # ignore icons that are not found
                log.debug("Failed to process window icon (%s): %s" \
                        % (abs_filename, err_msg))
        else:
            log.debug("Failed to locate window icon: %s" % icon_filename)
Beispiel #2
0
def get_icons_pixbuffers():
    result = []
    for icon_filename in WINDOW_ICON_FILENAMES:
        abs_filename = get_ui_file_location(icon_filename, silent=True)
        if abs_filename:
            try:
                result.append(gtk.gdk.pixbuf_new_from_file(abs_filename))
            except gobject.GError, err_msg:
                # ignore icons that are not found
                log.debug("Failed to process window icon (%s): %s" \
                        % (abs_filename, err_msg))
        else:
            log.debug("Failed to locate window icon: %s" % icon_filename)
Beispiel #3
0
    def __init__(self, event_manager):
        super().__init__(event_manager)
        self._event_handlers = []
        self.gui_is_active = False
        self.gui = Gtk.Builder()
        self._mainloop_is_running = False
        self.mainloop = get_mainloop(use_gtk=True)
        gtk_build_file = get_ui_file_location(GTKBUILD_FILE)
        if gtk_build_file is None:
            raise InitializationError(
                "Failed to load GTK layout specification file: {}".format(
                    gtk_build_file))
        self.gui.add_from_file(gtk_build_file)
        if pycam.Utils.get_platform() == pycam.Utils.OSPlatform.WINDOWS:
            gtkrc_file = get_ui_file_location(GTKRC_FILE_WINDOWS)
            if gtkrc_file:
                Gtk.rc_add_default_file(gtkrc_file)
                Gtk.rc_reparse_all_for_settings(Gtk.settings_get_default(),
                                                True)
        action_group = Gio.SimpleActionGroup()
        self.settings.set("gtk_action_group_prefix", "pycam")
        self.settings.set("gtk_action_group", action_group)
        self.window = self.gui.get_object("ProjectWindow")
        self.window.insert_action_group(
            self.settings.get("gtk_action_group_prefix"),
            self.settings.get("gtk_action_group"))
        self.settings.set("main_window", self.window)
        # show stock items on buttons
        # increase the initial width of the window (due to hidden elements)
        self.window.set_default_size(400, -1)
        # initialize the RecentManager (TODO: check for Windows)
        if False and pycam.Utils.get_platform(
        ) == pycam.Utils.OSPlatform.WINDOWS:
            # The pyinstaller binary for Windows fails mysteriously when trying
            # to display the stock item.
            # Error message: Gtk:ERROR:gtkrecentmanager.c:1942:get_icon_fallback:
            #    assertion failed: (retval != NULL)
            self.recent_manager = None
        else:
            try:
                self.recent_manager = Gtk.recent_manager_get_default()
            except AttributeError:
                # GTK 2.12.1 seems to have problems with "RecentManager" on
                # Windows. Sadly this is the version, that is shipped with the
                # "appunti" GTK packages for Windows (April 2010).
                # see http://www.daa.com.au/pipermail/pygtk/2009-May/017052.html
                self.recent_manager = None
        # file loading
        self.last_dirname = None
        self.last_model_uri = None
        # define callbacks and accelerator keys for the menu actions
        for objname, callback, data, accel_key in (
            ("OpenModel", self.load_model_file, None,
             "<Control>o"), ("Quit", self.destroy, None, "<Control>q"),
            ("GeneralSettings", self.toggle_preferences_window, None,
             "<Control>p"), ("UndoButton", self.restore_undo_state, None,
                             "<Control>z"),
            ("HelpIntroduction", self.show_help, "introduction", "F1"),
            ("HelpSupportedFormats", self.show_help, "supported-formats",
             None), ("HelpModelTransformations", self.show_help,
                     "model-transformations", None),
            ("HelpProcessSettings", self.show_help, "process-settings",
             None), ("HelpBoundsSettings", self.show_help, "bounding-box",
                     None), ("HelpTouchOff", self.show_help, "touch-off",
                             None), ("Help3DView", self.show_help, "3d-view",
                                     None), ("HelpServerMode", self.show_help,
                                             "server-mode", None),
            ("HelpCommandLine", self.show_help, "cli-examples",
             None), ("HelpHotkeys", self.show_help, "keyboard-shortcuts",
                     None), ("ProjectWebsite", self.show_help,
                             "http://pycam.sourceforge.net",
                             None), ("DevelopmentBlog", self.show_help,
                                     "http://fab.senselab.org/pycam", None),
            ("Forum", self.show_help,
             "http://sourceforge.net/projects/pycam/forums",
             None), ("BugTracker", self.show_help,
                     "https://github.com/SebKuzminsky/pycam/issues/",
                     None), ("FeatureRequest", self.show_help,
                             "https://github.com/SebKuzminsky/pycam/issues/",
                             None)):
            item = self.gui.get_object(objname)
            action = "activate"
            if data is None:
                item.connect(action, callback)
            else:
                item.connect(action, callback, data)
            if accel_key:
                key, mod = Gtk.accelerator_parse(accel_key)
                accel_path = "<pycam>/%s" % objname
                item.set_accel_path(accel_path)
                # Gtk.accel_map_change_entry(accel_path, key, mod, True) FIXME
        # LinkButton does not work on Windows: https://bugzilla.gnome.org/show_bug.cgi?id=617874
        if pycam.Utils.get_platform() == pycam.Utils.OSPlatform.WINDOWS:

            def open_url(widget, data=None):
                webbrowser.open(widget.get_uri())

            Gtk.link_button_set_uri_hook(open_url)
        # configure drag-n-drop for config files and models
        self.settings.set("configure-drag-drop-func",
                          self.configure_drag_and_drop)
        self.settings.get("configure-drag-drop-func")(self.window)
        # other events
        self.window.connect("destroy", self.destroy)
        self.window.connect("delete-event", self.destroy)
        # the settings window
        self.gui.get_object("CloseSettingsWindow").connect(
            "clicked", self.toggle_preferences_window, False)
        self.gui.get_object("ResetPreferencesButton").connect(
            "clicked", self.reset_preferences)
        self.preferences_window = self.gui.get_object("GeneralSettingsWindow")
        self.preferences_window.connect("delete-event",
                                        self.toggle_preferences_window, False)
        self.preferences_window.insert_action_group(
            self.settings.get("gtk_action_group_prefix"),
            self.settings.get("gtk_action_group"))
        self._preferences_window_position = None
        self._preferences_window_visible = False
        # "about" window
        self.about_window = self.gui.get_object("AboutWindow")
        self.about_window.set_version(VERSION)
        self.about_window.insert_action_group(
            self.settings.get("gtk_action_group_prefix"),
            self.settings.get("gtk_action_group"))
        self.gui.get_object("About").connect("activate",
                                             self.toggle_about_window, True)
        # we assume, that the last child of the window is the "close" button
        # TODO: fix this ugly hack!
        about_window_children = self.gui.get_object(
            "AboutWindowButtons").get_children()
        if about_window_children:
            # it seems to be possible that there are no children - weird :(
            # see https://github.com/SebKuzminsky/pycam/issues/59
            about_window_children[-1].connect("clicked",
                                              self.toggle_about_window, False)
        self.about_window.connect("delete-event", self.toggle_about_window,
                                  False)
        # menu bar
        uimanager = Gtk.UIManager()
        self.settings.set("gtk-uimanager", uimanager)
        self._accel_group = uimanager.get_accel_group()
        # send a "delete" event on "CTRL-w" for every window
        self._accel_group.connect(
            ord('w'), Gdk.ModifierType.CONTROL_MASK, Gtk.AccelFlags.LOCKED,
            lambda accel_group, window, *args: window.emit(
                "delete-event", Gdk.Event()))
        self._accel_group.connect(ord('q'), Gdk.ModifierType.CONTROL_MASK,
                                  Gtk.AccelFlags.LOCKED,
                                  lambda *args: self.destroy())
        self.settings.add_item("gtk-accel-group", lambda: self._accel_group)
        for obj in self.gui.get_objects():
            if isinstance(obj, Gtk.Window):
                obj.add_accel_group(self._accel_group)
        # preferences tab
        preferences_book = self.gui.get_object("PreferencesNotebook")

        def clear_preferences():
            for child in preferences_book.get_children():
                preferences_book.remove(child)

        def add_preferences_item(item, name):
            preferences_book.append_page(item, Gtk.Label(name))

        self.settings.register_ui_section("preferences", add_preferences_item,
                                          clear_preferences)
        for obj_name, label, priority in (("GeneralSettingsPrefTab", "General",
                                           -50), ("ProgramsPrefTab",
                                                  "Programs", 50)):
            obj = self.gui.get_object(obj_name)
            obj.unparent()
            self.settings.register_ui("preferences", label, obj, priority)
        # general preferences
        general_prefs = self.gui.get_object("GeneralPreferencesBox")

        def clear_general_prefs():
            for item in general_prefs.get_children():
                general_prefs.remove(item)

        def add_general_prefs_item(item, name):
            general_prefs.pack_start(item, expand=False, fill=False, padding=3)

        self.settings.register_ui_section("preferences_general",
                                          add_general_prefs_item,
                                          clear_general_prefs)
        # set defaults
        main_tab = self.gui.get_object("MainTabs")

        def clear_main_tab():
            while main_tab.get_n_pages() > 0:
                main_tab.remove_page(0)

        def add_main_tab_item(item, name):
            main_tab.append_page(item, Gtk.Label(name))

        # TODO: move these to plugins, as well
        self.settings.register_ui_section("main", add_main_tab_item,
                                          clear_main_tab)
        main_window = self.gui.get_object("WindowBox")

        def clear_main_window():
            main_window.foreach(main_window.remove)

        def add_main_window_item(item, name, **extra_args):
            # some widgets may want to override the defaults
            args = {"expand": False, "fill": False, "padding": 3}
            args.update(extra_args)
            main_window.pack_start(item, **args)

        main_tab.unparent()
        self.settings.register_ui_section("main_window", add_main_window_item,
                                          clear_main_window)
        self.settings.register_ui("main_window",
                                  "Tabs",
                                  main_tab,
                                  -20,
                                  args_dict={
                                      "expand": True,
                                      "fill": True
                                  })

        def disable_gui():
            self.menubar.set_sensitive(False)
            main_tab.set_sensitive(False)

        def enable_gui():
            self.menubar.set_sensitive(True)
            main_tab.set_sensitive(True)

        # configure locations of external programs
        for auto_control_name, location_control_name, browse_button, key in (
            ("ExternalProgramInkscapeAuto", "ExternalProgramInkscapeControl",
             "ExternalProgramInkscapeBrowse", "inkscape"),
            ("ExternalProgramPstoeditAuto", "ExternalProgramPstoeditControl",
             "ExternalProgramPstoeditBrowse", "pstoedit")):
            self.gui.get_object(auto_control_name).connect(
                "clicked", self._locate_external_program, key)
            location_control = self.gui.get_object(location_control_name)
            self.settings.add_item("external_program_%s" % key,
                                   location_control.get_text,
                                   location_control.set_text)
            self.gui.get_object(browse_button).connect(
                "clicked", self._browse_external_program_location, key)
        for objname, callback in (
            ("ResetWorkspace", lambda widget: self.reset_workspace()),
            ("LoadWorkspace", lambda widget: self.load_workspace_dialog()),
            ("SaveWorkspace",
             lambda widget: self.save_workspace_dialog(self.last_workspace_uri)
             ), ("SaveAsWorkspace",
                 lambda widget: self.save_workspace_dialog())):
            self.gui.get_object(objname).connect("activate", callback)
        # set the icons (in different sizes) for all windows
        # Gtk.window_set_default_icon_list(*get_icons_pixbuffers()) FIXME
        # load menu data
        gtk_menu_file = get_ui_file_location(GTKMENU_FILE)
        if gtk_menu_file is None:
            raise InitializationError(
                "Failed to load GTK menu specification file: {}".format(
                    gtk_menu_file))
        uimanager.add_ui_from_file(gtk_menu_file)
        # make the actions defined in the GTKBUILD file available in the menu
        actiongroup = Gtk.ActionGroup("menubar")
        for action in [
                aobj for aobj in self.gui.get_objects()
                if isinstance(aobj, Gtk.Action)
        ]:
            actiongroup.add_action(action)
        # the "pos" parameter is optional since 2.12 - we can remove it later
        uimanager.insert_action_group(actiongroup)
        # the "recent files" sub-menu
        if self.recent_manager is not None:
            recent_files_menu = Gtk.RecentChooserMenu(self.recent_manager)
            recent_files_menu.set_name("RecentFilesMenu")
            recent_menu_filter = Gtk.RecentFilter()
            case_converter = pycam.Utils.get_case_insensitive_file_pattern
            for filter_name, patterns in FILTER_MODEL:
                if not isinstance(patterns, (list, set, tuple)):
                    patterns = [patterns]
                # convert it into a mutable list (instead of set/tuple)
                patterns = list(patterns)
                for index in range(len(patterns)):
                    patterns[index] = case_converter(patterns[index])
                for pattern in patterns:
                    recent_menu_filter.add_pattern(pattern)
            recent_files_menu.add_filter(recent_menu_filter)
            recent_files_menu.set_show_numbers(True)
            # non-local files (without "file://") are not supported. yet
            recent_files_menu.set_local_only(False)
            # most recent files to the top
            recent_files_menu.set_sort_type(Gtk.RECENT_SORT_MRU)
            # show only ten files
            recent_files_menu.set_limit(10)
            uimanager.get_widget("/MenuBar/FileMenu/OpenRecentModelMenu"
                                 ).set_submenu(recent_files_menu)
            recent_files_menu.connect("item-activated",
                                      self.load_recent_model_file)
        else:
            self.gui.get_object("OpenRecentModel").set_visible(False)
        # load the menubar and connect functions to its items
        self.menubar = uimanager.get_widget("/MenuBar")
        # dict of all merge-ids
        menu_merges = {}

        def clear_menu(menu_key):
            for merge in menu_merges.get(menu_key, []):
                uimanager.remove_ui(merge)

        def append_menu_item(menu_key, base_path, widget, name):
            merge_id = uimanager.new_merge_id()
            if widget:
                action_group = widget.props.action_group
                if action_group not in uimanager.get_action_groups():
                    uimanager.insert_action_group(action_group, -1)
                widget_name = widget.get_name()
                item_type = Gtk.UIManagerItemType.MENU
            else:
                widget_name = name
                item_type = Gtk.UIManagerItemType.SEPARATOR
            uimanager.add_ui(merge_id, base_path, name, widget_name, item_type,
                             False)
            if menu_key not in menu_merges:
                menu_merges[menu_key] = []
            menu_merges[menu_key].append(merge_id)

        def get_menu_funcs(menu_key, base_path):
            return (lambda widget, name: append_menu_item(
                menu_key, base_path, widget, name),
                    lambda: clear_menu(menu_key))

        for ui_name, base_path in (("view_menu", "/MenuBar/ViewMenu"),
                                   ("file_menu", "/MenuBar/FileMenu"),
                                   ("edit_menu", "/MenuBar/EditMenu"),
                                   ("export_menu",
                                    "/MenuBar/FileMenu/ExportMenu")):
            append_func, clear_func = get_menu_funcs(ui_name, base_path)
            self.settings.register_ui_section(ui_name, append_func, clear_func)
        self.settings.register_ui("file_menu", "Quit",
                                  self.gui.get_object("Quit"), 100)
        self.settings.register_ui("file_menu", "QuitSeparator", None, 95)
        self.settings.register_ui("main_window", "Main", self.menubar, -100)
        self.settings.set("set_last_filename", self.add_to_recent_file_list)
        self._event_handlers.extend((
            ("history-changed", self._update_undo_button),
            ("model-change-after", "visual-item-updated"),
            ("gui-disable", disable_gui),
            ("gui-enable", enable_gui),
            ("notify-file-saved", self.add_to_recent_file_list),
            ("notify-file-opened", self.add_to_recent_file_list),
        ))
        for name, target in self._event_handlers:
            self.settings.register_event(name, target)
        # allow the task settings control to be updated
        self.mainloop.update()
        # register a logging handler for displaying error messages
        pycam.Utils.log.add_gtk_gui(self.window, logging.ERROR)
        self.window.show()
        self.mainloop.update()
Beispiel #4
0
    def __init__(self, no_dialog=False):
        self.settings = EventCore()
        self.gui_is_active = False
        # during initialization any dialog (e.g. "Unit change") is not allowed
        # we set the final value later
        self.no_dialog = True
        self._batch_queue = []
        self._undo_states = []
        self.gui = gtk.Builder()
        gtk_build_file = get_ui_file_location(GTKBUILD_FILE)
        if gtk_build_file is None:
            gtk.main_quit()
        self.gui.add_from_file(gtk_build_file)
        if pycam.Utils.get_platform() == pycam.Utils.PLATFORM_WINDOWS:
            gtkrc_file = get_ui_file_location(GTKRC_FILE_WINDOWS)
            if gtkrc_file:
                gtk.rc_add_default_file(gtkrc_file)
                gtk.rc_reparse_all_for_settings(gtk.settings_get_default(),
                                                True)
        self.window = self.gui.get_object("ProjectWindow")
        self.settings.set("main_window", self.window)
        # show stock items on buttons
        # increase the initial width of the window (due to hidden elements)
        self.window.set_default_size(400, -1)
        # initialize the RecentManager (TODO: check for Windows)
        if False and pycam.Utils.get_platform(
        ) == pycam.Utils.PLATFORM_WINDOWS:
            # The pyinstaller binary for Windows fails mysteriously when trying
            # to display the stock item.
            # Error message: Gtk:ERROR:gtkrecentmanager.c:1942:get_icon_fallback: assertion failed: (retval != NULL)
            self.recent_manager = None
        else:
            try:
                self.recent_manager = gtk.recent_manager_get_default()
            except AttributeError:
                # GTK 2.12.1 seems to have problems with "RecentManager" on
                # Windows. Sadly this is the version, that is shipped with the
                # "appunti" GTK packages for Windows (April 2010).
                # see http://www.daa.com.au/pipermail/pygtk/2009-May/017052.html
                self.recent_manager = None
        # file loading
        self.last_dirname = None
        self.last_task_settings_uri = None
        self.last_model_uri = None
        # define callbacks and accelerator keys for the menu actions
        for objname, callback, data, accel_key in (
            ("LoadTaskSettings", self.load_task_settings_file, None,
             "<Control>t"), ("SaveTaskSettings", self.save_task_settings_file,
                             lambda: self.last_task_settings_uri, None),
            ("SaveAsTaskSettings", self.save_task_settings_file, None,
             None), ("OpenModel", self.load_model_file, None,
                     "<Control>o"), ("Quit", self.destroy, None, "<Control>q"),
            ("GeneralSettings", self.toggle_preferences_window, None,
             "<Control>p"), ("UndoButton", self._restore_undo_state, None,
                             "<Control>z"), ("HelpUserManual", self.show_help,
                                             "User_Manual", "F1"),
            ("HelpIntroduction", self.show_help, "Introduction", None),
            ("HelpSupportedFormats", self.show_help, "SupportedFormats",
             None), ("HelpModelTransformations", self.show_help,
                     "ModelTransformations",
                     None), ("HelpToolTypes", self.show_help, "ToolTypes",
                             None), ("HelpProcessSettings", self.show_help,
                                     "ProcessSettings", None),
            ("HelpBoundsSettings", self.show_help, "BoundsSettings",
             None), ("HelpTaskSetup", self.show_help, "TaskSetup", None),
            ("HelpGCodeExport", self.show_help, "GCodeExport",
             None), ("HelpTouchOff", self.show_help, "TouchOff",
                     None), ("HelpSimulation", self.show_help, "Simulation",
                             None), ("Help3DView", self.show_help, "3D_View",
                                     None), ("HelpServerMode", self.show_help,
                                             "ServerMode", None),
            ("HelpCommandLine", self.show_help, "CommandlineExamples",
             None), ("HelpHotkeys", self.show_help, "KeyboardShortcuts",
                     None), ("ProjectWebsite", self.show_help,
                             "http://pycam.sourceforge.net",
                             None), ("DevelopmentBlog", self.show_help,
                                     "http://fab.senselab.org/pycam", None),
            ("Forum", self.show_help,
             "http://sourceforge.net/projects/pycam/forums", None),
            ("BugTracker", self.show_help,
             "http://sourceforge.net/tracker/?group_id=237831&atid=1104176",
             None),
            ("FeatureRequest", self.show_help,
             "http://sourceforge.net/tracker/?group_id=237831&atid=1104179",
             None)):
            item = self.gui.get_object(objname)
            action = "activate"
            if data is None:
                item.connect(action, callback)
            else:
                item.connect(action, callback, data)
            if accel_key:
                key, mod = gtk.accelerator_parse(accel_key)
                accel_path = "<pycam>/%s" % objname
                item.set_accel_path(accel_path)
                gtk.accel_map_change_entry(accel_path, key, mod, True)
        # LinkButton does not work on Windows: https://bugzilla.gnome.org/show_bug.cgi?id=617874
        if pycam.Utils.get_platform() == pycam.Utils.PLATFORM_WINDOWS:

            def open_url(widget, data=None):
                webbrowser.open(widget.get_uri())

            gtk.link_button_set_uri_hook(open_url)
        # no undo is allowed at the beginning
        self.gui.get_object("UndoButton").set_sensitive(False)
        self.settings.register_event("model-change-before",
                                     self._store_undo_state)
        self.settings.register_event(
            "model-change-after",
            lambda: self.settings.emit_event("visual-item-updated"))
        # set the availability of ODE
        self.enable_ode_control = self.gui.get_object("SettingEnableODE")
        self.settings.add_item("enable_ode",
                               self.enable_ode_control.get_active,
                               self.enable_ode_control.set_active)
        self.settings.register_event("parallel-processing-changed",
                                     self.update_ode_settings)
        # configure drag-n-drop for config files and models
        self.settings.set("configure-drag-drop-func",
                          self.configure_drag_and_drop)
        self.settings.get("configure-drag-drop-func")(self.window)
        # other events
        self.window.connect("destroy", self.destroy)
        self.window.connect("delete-event", self.destroy)
        # the settings window
        self.gui.get_object("CloseSettingsWindow").connect(
            "clicked", self.toggle_preferences_window, False)
        self.gui.get_object("ResetPreferencesButton").connect(
            "clicked", self.reset_preferences)
        self.preferences_window = self.gui.get_object("GeneralSettingsWindow")
        self.preferences_window.connect("delete-event",
                                        self.toggle_preferences_window, False)
        self._preferences_window_position = None
        self._preferences_window_visible = False
        # "about" window
        self.about_window = self.gui.get_object("AboutWindow")
        self.about_window.set_version(VERSION)
        self.gui.get_object("About").connect("activate",
                                             self.toggle_about_window, True)
        # we assume, that the last child of the window is the "close" button
        # TODO: fix this ugly hack!
        self.gui.get_object("AboutWindowButtons").get_children()[-1].connect(
            "clicked", self.toggle_about_window, False)
        self.about_window.connect("delete-event", self.toggle_about_window,
                                  False)
        # menu bar
        uimanager = gtk.UIManager()
        self.settings.set("gtk-uimanager", uimanager)
        self._accel_group = uimanager.get_accel_group()

        # send a "delete" event on "CTRL-w" for every window
        def handle_window_close(accel_group, window, *args):
            window.emit("delete-event", gtk.gdk.Event(gtk.gdk.DELETE))

        self._accel_group.connect_group(ord('w'), gtk.gdk.CONTROL_MASK,
                                        gtk.ACCEL_LOCKED, handle_window_close)
        self.settings.add_item("gtk-accel-group", lambda: self._accel_group)
        for obj in self.gui.get_objects():
            if isinstance(obj, gtk.Window):
                obj.add_accel_group(self._accel_group)
        # preferences tab
        preferences_book = self.gui.get_object("PreferencesNotebook")

        def clear_preferences():
            for child in preferences_book.get_children():
                preferences_book.remove(child)

        def add_preferences_item(item, name):
            preferences_book.append_page(item, gtk.Label(name))

        self.settings.register_ui_section("preferences", add_preferences_item,
                                          clear_preferences)
        for obj_name, label, priority in (("GeneralSettingsPrefTab", "General",
                                           -50), ("ProgramsPrefTab",
                                                  "Programs", 50)):
            obj = self.gui.get_object(obj_name)
            obj.unparent()
            self.settings.register_ui("preferences", label, obj, priority)
        # general preferences
        general_prefs = self.gui.get_object("GeneralPreferencesBox")

        def clear_general_prefs():
            for item in general_prefs.get_children():
                general_prefs.remove(item)

        def add_general_prefs_item(item, name):
            general_prefs.pack_start(item, expand=False, padding=3)

        self.settings.register_ui_section("preferences_general",
                                          add_general_prefs_item,
                                          clear_general_prefs)
        for obj_name, priority in (("SettingEnableODE", 10),
                                   ("TaskSettingsDefaultFileBox", 30)):
            obj = self.gui.get_object(obj_name)
            obj.unparent()
            self.settings.register_ui("preferences_general", None, obj,
                                      priority)
        # set defaults
        self.cutter = None
        # add some dummies - to be implemented later ...
        self.settings.add_item("cutter", lambda: self.cutter)
        main_tab = self.gui.get_object("MainTabs")

        def clear_main_tab():
            while main_tab.get_n_pages() > 0:
                main_tab.remove_page(0)

        def add_main_tab_item(item, name):
            main_tab.append_page(item, gtk.Label(name))

        # TODO: move these to plugins, as well
        self.settings.register_ui_section("main", add_main_tab_item,
                                          clear_main_tab)
        main_window = self.gui.get_object("WindowBox")

        def clear_main_window():
            main_window.foreach(lambda x: main_window.remove(x))

        def add_main_window_item(item, name, **extra_args):
            # some widgets may want to override the defaults
            args = {"expand": False, "fill": False}
            args.update(extra_args)
            main_window.pack_start(item, **args)

        main_tab.unparent()
        self.settings.register_ui_section("main_window", add_main_window_item,
                                          clear_main_window)
        self.settings.register_ui("main_window",
                                  "Tabs",
                                  main_tab,
                                  -20,
                                  args_dict={
                                      "expand": True,
                                      "fill": True
                                  })
        # autoload task settings file on startup
        autoload_enable = self.gui.get_object("AutoLoadTaskFile")
        autoload_box = self.gui.get_object("StartupTaskFileBox")
        autoload_source = self.gui.get_object("StartupTaskFile")

        # TODO: fix the extension filter
        #for one_filter in get_filters_from_list(FILTER_CONFIG):
        #    autoload_source.add_filter(one_filter)
        #    autoload_source.set_filter(one_filter)
        def get_autoload_task_file(autoload_source=autoload_source):
            if autoload_enable.get_active():
                return autoload_source.get_filename()
            else:
                return ""

        def set_autoload_task_file(filename):
            if filename:
                autoload_enable.set_active(True)
                autoload_box.show()
                autoload_source.set_filename(filename)
            else:
                autoload_enable.set_active(False)
                autoload_box.hide()
                autoload_source.unselect_all()

        def autoload_enable_switched(widget, box):
            if not widget.get_active():
                set_autoload_task_file(None)
            else:
                autoload_box.show()

        autoload_enable.connect("toggled", autoload_enable_switched,
                                autoload_box)
        self.settings.add_item("default_task_settings_file",
                               get_autoload_task_file, set_autoload_task_file)

        def disable_gui():
            self.menubar.set_sensitive(False)
            main_tab.set_sensitive(False)

        def enable_gui():
            self.menubar.set_sensitive(True)
            main_tab.set_sensitive(True)

        self.settings.register_event("gui-disable", disable_gui)
        self.settings.register_event("gui-enable", enable_gui)
        # configure locations of external programs
        for auto_control_name, location_control_name, browse_button, key in (
            ("ExternalProgramInkscapeAuto", "ExternalProgramInkscapeControl",
             "ExternalProgramInkscapeBrowse", "inkscape"),
            ("ExternalProgramPstoeditAuto", "ExternalProgramPstoeditControl",
             "ExternalProgramPstoeditBrowse", "pstoedit")):
            self.gui.get_object(auto_control_name).connect(
                "clicked", self._locate_external_program, key)
            location_control = self.gui.get_object(location_control_name)
            self.settings.add_item("external_program_%s" % key,
                                   location_control.get_text,
                                   location_control.set_text)
            self.gui.get_object(browse_button).connect(
                "clicked", self._browse_external_program_location, key)
        # set the icons (in different sizes) for all windows
        gtk.window_set_default_icon_list(*get_icons_pixbuffers())
        # load menu data
        gtk_menu_file = get_ui_file_location(GTKMENU_FILE)
        if gtk_menu_file is None:
            gtk.main_quit()
        uimanager.add_ui_from_file(gtk_menu_file)
        # make the actions defined in the GTKBUILD file available in the menu
        actiongroup = gtk.ActionGroup("menubar")
        for action in [
                action for action in self.gui.get_objects()
                if isinstance(action, gtk.Action)
        ]:
            actiongroup.add_action(action)
        # the "pos" parameter is optional since 2.12 - we can remove it later
        uimanager.insert_action_group(actiongroup, pos=-1)
        # the "recent files" sub-menu
        if not self.recent_manager is None:
            recent_files_menu = gtk.RecentChooserMenu(self.recent_manager)
            recent_files_menu.set_name("RecentFilesMenu")
            recent_menu_filter = gtk.RecentFilter()
            case_converter = pycam.Utils.get_case_insensitive_file_pattern
            for filter_name, patterns in FILTER_MODEL:
                if not isinstance(patterns, (list, set, tuple)):
                    patterns = [patterns]
                # convert it into a mutable list (instead of set/tuple)
                patterns = list(patterns)
                for index in range(len(patterns)):
                    patterns[index] = case_converter(patterns[index])
                for pattern in patterns:
                    recent_menu_filter.add_pattern(pattern)
            recent_files_menu.add_filter(recent_menu_filter)
            recent_files_menu.set_show_numbers(True)
            # non-local files (without "file://") are not supported. yet
            recent_files_menu.set_local_only(False)
            # most recent files to the top
            recent_files_menu.set_sort_type(gtk.RECENT_SORT_MRU)
            # show only ten files
            recent_files_menu.set_limit(10)
            uimanager.get_widget("/MenuBar/FileMenu/OpenRecentModelMenu")\
                    .set_submenu(recent_files_menu)
            recent_files_menu.connect("item-activated",
                                      self.load_recent_model_file)
        else:
            self.gui.get_object("OpenRecentModel").set_visible(False)
        # load the menubar and connect functions to its items
        self.menubar = uimanager.get_widget("/MenuBar")
        # dict of all merge-ids
        menu_merges = {}

        def clear_menu(menu_key):
            for merge in menu_merges.get(menu_key, []):
                uimanager.remove_ui(merge)

        def append_menu_item(menu_key, base_path, widget, name):
            merge_id = uimanager.new_merge_id()
            if widget:
                action_group = widget.props.action_group
                if not action_group in uimanager.get_action_groups():
                    uimanager.insert_action_group(action_group, -1)
                widget_name = widget.get_name()
                item_type = gtk.UI_MANAGER_MENUITEM
            else:
                widget_name = name
                item_type = gtk.UI_MANAGER_SEPARATOR
            uimanager.add_ui(merge_id, base_path, name, widget_name, item_type,
                             False)
            if not menu_key in menu_merges:
                menu_merges[menu_key] = []
            menu_merges[menu_key].append(merge_id)

        def get_menu_funcs(menu_key, base_path):
            append_func = lambda widget, name: \
                    append_menu_item(menu_key, base_path, widget, name)
            clear_func = lambda: clear_menu(menu_key)
            return append_func, clear_func

        for ui_name, base_path in (("view_menu", "/MenuBar/ViewMenu"),
                                   ("file_menu", "/MenuBar/FileMenu"),
                                   ("edit_menu", "/MenuBar/EditMenu"),
                                   ("export_menu",
                                    "/MenuBar/FileMenu/ExportMenu")):
            append_func, clear_func = get_menu_funcs(ui_name, base_path)
            self.settings.register_ui_section(ui_name, append_func, clear_func)
        self.settings.register_ui("file_menu", "Quit",
                                  self.gui.get_object("Quit"), 100)
        self.settings.register_ui("file_menu", "QuitSeparator", None, 95)
        self.settings.register_ui("main_window", "Main", self.menubar, -100)
        # initialize plugins
        self.plugin_manager = pycam.Plugins.PluginManager(core=self.settings)
        self.plugin_manager.import_plugins()
        # some more initialization
        self.reset_preferences()
        # TODO: preferences are not loaded until the new format is stable
        #self.load_preferences()
        #self.load_task_settings()
        self.settings.register_event("notify-file-saved",
                                     self.add_to_recent_file_list)
        self.settings.register_event("notify-file-opened",
                                     self.add_to_recent_file_list)
        # fallback - in case of a failure when opening a model file
        model = pycam.Importers.TestModel.get_test_model()
        self.settings.get("models").add_model(model, "Tiny pyramid")
        # Without this "gkt.main_iteration" loop the task settings file
        # control would not be updated in time.
        while gtk.events_pending():
            gtk.main_iteration()
        autoload_task_filename = self.settings.get(
            "default_task_settings_file")
        if autoload_task_filename:
            self.open_task_settings_file(autoload_task_filename)
        self.update_all_controls()
        self.no_dialog = no_dialog
        if not self.no_dialog:
            # register a logging handler for displaying error messages
            pycam.Utils.log.add_gtk_gui(self.window, logging.ERROR)
            self.window.show()
Beispiel #5
0
 def __init__(self, no_dialog=False):
     self.settings = EventCore()
     self.gui_is_active = False
     # during initialization any dialog (e.g. "Unit change") is not allowed
     # we set the final value later
     self.no_dialog = True
     self._batch_queue = []
     self._undo_states = []
     self.gui = gtk.Builder()
     gtk_build_file = get_ui_file_location(GTKBUILD_FILE)
     if gtk_build_file is None:
         gtk.main_quit()
     self.gui.add_from_file(gtk_build_file)
     if pycam.Utils.get_platform() == pycam.Utils.PLATFORM_WINDOWS:
         gtkrc_file = get_ui_file_location(GTKRC_FILE_WINDOWS)
         if gtkrc_file:
             gtk.rc_add_default_file(gtkrc_file)
             gtk.rc_reparse_all_for_settings(gtk.settings_get_default(), True)
     self.window = self.gui.get_object("ProjectWindow")
     self.settings.set("main_window", self.window)
     # show stock items on buttons
     # increase the initial width of the window (due to hidden elements)
     self.window.set_default_size(400, -1)
     # initialize the RecentManager (TODO: check for Windows)
     if False and pycam.Utils.get_platform() == pycam.Utils.PLATFORM_WINDOWS:
         # The pyinstaller binary for Windows fails mysteriously when trying
         # to display the stock item.
         # Error message: Gtk:ERROR:gtkrecentmanager.c:1942:get_icon_fallback: assertion failed: (retval != NULL)
         self.recent_manager = None
     else:
         try:
             self.recent_manager = gtk.recent_manager_get_default()
         except AttributeError:
             # GTK 2.12.1 seems to have problems with "RecentManager" on
             # Windows. Sadly this is the version, that is shipped with the
             # "appunti" GTK packages for Windows (April 2010).
             # see http://www.daa.com.au/pipermail/pygtk/2009-May/017052.html
             self.recent_manager = None
     # file loading
     self.last_dirname = None
     self.last_task_settings_uri = None
     self.last_model_uri = None
     # define callbacks and accelerator keys for the menu actions
     for objname, callback, data, accel_key in (
             ("LoadTaskSettings", self.load_task_settings_file, None, "<Control>t"),
             ("SaveTaskSettings", self.save_task_settings_file, lambda: self.last_task_settings_uri, None),
             ("SaveAsTaskSettings", self.save_task_settings_file, None, None),
             ("OpenModel", self.load_model_file, None, "<Control>o"),
             ("Quit", self.destroy, None, "<Control>q"),
             ("GeneralSettings", self.toggle_preferences_window, None, "<Control>p"),
             ("UndoButton", self._restore_undo_state, None, "<Control>z"),
             ("HelpUserManual", self.show_help, "User_Manual", "F1"),
             ("HelpIntroduction", self.show_help, "Introduction", None),
             ("HelpSupportedFormats", self.show_help, "SupportedFormats", None),
             ("HelpModelTransformations", self.show_help, "ModelTransformations", None),
             ("HelpToolTypes", self.show_help, "ToolTypes", None),
             ("HelpProcessSettings", self.show_help, "ProcessSettings", None),
             ("HelpBoundsSettings", self.show_help, "BoundsSettings", None),
             ("HelpTaskSetup", self.show_help, "TaskSetup", None),
             ("HelpGCodeExport", self.show_help, "GCodeExport", None),
             ("HelpTouchOff", self.show_help, "TouchOff", None),
             ("HelpSimulation", self.show_help, "Simulation", None),
             ("Help3DView", self.show_help, "3D_View", None),
             ("HelpServerMode", self.show_help, "ServerMode", None),
             ("HelpCommandLine", self.show_help, "CommandlineExamples", None),
             ("HelpHotkeys", self.show_help, "KeyboardShortcuts", None),
             ("ProjectWebsite", self.show_help, "http://pycam.sourceforge.net", None),
             ("DevelopmentBlog", self.show_help, "http://fab.senselab.org/pycam", None),
             ("Forum", self.show_help, "http://sourceforge.net/projects/pycam/forums", None),
             ("BugTracker", self.show_help, "http://sourceforge.net/tracker/?group_id=237831&atid=1104176", None),
             ("FeatureRequest", self.show_help, "http://sourceforge.net/tracker/?group_id=237831&atid=1104179", None)):
         item = self.gui.get_object(objname)
         action = "activate"
         if data is None:
             item.connect(action, callback)
         else:
             item.connect(action, callback, data)
         if accel_key:
             key, mod = gtk.accelerator_parse(accel_key)
             accel_path = "<pycam>/%s" % objname
             item.set_accel_path(accel_path)
             gtk.accel_map_change_entry(accel_path, key, mod, True)
     # LinkButton does not work on Windows: https://bugzilla.gnome.org/show_bug.cgi?id=617874
     if pycam.Utils.get_platform() == pycam.Utils.PLATFORM_WINDOWS:
         def open_url(widget, data=None):
             webbrowser.open(widget.get_uri())
         gtk.link_button_set_uri_hook(open_url)
     # no undo is allowed at the beginning
     self.gui.get_object("UndoButton").set_sensitive(False)
     self.settings.register_event("model-change-before",
             self._store_undo_state)
     self.settings.register_event("model-change-after",
             lambda: self.settings.emit_event("visual-item-updated"))
     # set the availability of ODE
     self.enable_ode_control = self.gui.get_object("SettingEnableODE")
     self.settings.add_item("enable_ode", self.enable_ode_control.get_active,
             self.enable_ode_control.set_active)
     self.settings.register_event("parallel-processing-changed",
             self.update_ode_settings)
     # configure drag-n-drop for config files and models
     self.settings.set("configure-drag-drop-func",
             self.configure_drag_and_drop)
     self.settings.get("configure-drag-drop-func")(self.window)
     # other events
     self.window.connect("destroy", self.destroy)
     self.window.connect("delete-event", self.destroy)
     # the settings window
     self.gui.get_object("CloseSettingsWindow").connect("clicked", self.toggle_preferences_window, False)
     self.gui.get_object("ResetPreferencesButton").connect("clicked", self.reset_preferences)
     self.preferences_window = self.gui.get_object("GeneralSettingsWindow")
     self.preferences_window.connect("delete-event", self.toggle_preferences_window, False)
     self._preferences_window_position = None
     self._preferences_window_visible = False
     # "about" window
     self.about_window = self.gui.get_object("AboutWindow")
     self.about_window.set_version(VERSION)
     self.gui.get_object("About").connect("activate", self.toggle_about_window, True)
     # we assume, that the last child of the window is the "close" button
     # TODO: fix this ugly hack!
     self.gui.get_object("AboutWindowButtons").get_children()[-1].connect("clicked", self.toggle_about_window, False)
     self.about_window.connect("delete-event", self.toggle_about_window, False)
     # menu bar
     uimanager = gtk.UIManager()
     self.settings.set("gtk-uimanager", uimanager)
     self._accel_group = uimanager.get_accel_group()
     # send a "delete" event on "CTRL-w" for every window
     def handle_window_close(accel_group, window, *args):
         window.emit("delete-event", gtk.gdk.Event(gtk.gdk.DELETE))
     self._accel_group.connect_group(ord('w'), gtk.gdk.CONTROL_MASK,
             gtk.ACCEL_LOCKED, handle_window_close)
     self.settings.add_item("gtk-accel-group", lambda: self._accel_group)
     for obj in self.gui.get_objects():
         if isinstance(obj, gtk.Window):
             obj.add_accel_group(self._accel_group)
     # preferences tab
     preferences_book = self.gui.get_object("PreferencesNotebook")
     def clear_preferences():
         for child in preferences_book.get_children():
             preferences_book.remove(child)
     def add_preferences_item(item, name):
         preferences_book.append_page(item, gtk.Label(name))
     self.settings.register_ui_section("preferences",
             add_preferences_item, clear_preferences)
     for obj_name, label, priority in (
             ("GeneralSettingsPrefTab", "General", -50),
             ("ProgramsPrefTab", "Programs", 50)):
         obj = self.gui.get_object(obj_name)
         obj.unparent()
         self.settings.register_ui("preferences", label, obj, priority)
     # general preferences
     general_prefs = self.gui.get_object("GeneralPreferencesBox")
     def clear_general_prefs():
         for item in general_prefs.get_children():
             general_prefs.remove(item)
     def add_general_prefs_item(item, name):
         general_prefs.pack_start(item, expand=False, padding=3)
     self.settings.register_ui_section("preferences_general",
             add_general_prefs_item, clear_general_prefs)
     for obj_name, priority in (("SettingEnableODE", 10),
             ("TaskSettingsDefaultFileBox", 30)):
         obj = self.gui.get_object(obj_name)
         obj.unparent()
         self.settings.register_ui("preferences_general", None,
                 obj, priority)
     # set defaults
     self.cutter = None
     # add some dummies - to be implemented later ...
     self.settings.add_item("cutter", lambda: self.cutter)
     main_tab = self.gui.get_object("MainTabs")
     def clear_main_tab():
         while main_tab.get_n_pages() > 0:
             main_tab.remove_page(0)
     def add_main_tab_item(item, name):
         main_tab.append_page(item, gtk.Label(name))
     # TODO: move these to plugins, as well
     self.settings.register_ui_section("main", add_main_tab_item,
             clear_main_tab)
     main_window = self.gui.get_object("WindowBox")
     def clear_main_window():
         main_window.foreach(lambda x: main_window.remove(x))
     def add_main_window_item(item, name, **extra_args):
         # some widgets may want to override the defaults
         args = {"expand": False, "fill": False}
         args.update(extra_args)
         main_window.pack_start(item, **args)
     main_tab.unparent()
     self.settings.register_ui_section("main_window", add_main_window_item,
             clear_main_window)
     self.settings.register_ui("main_window", "Tabs", main_tab, -20,
             args_dict={"expand": True, "fill": True})
     # autoload task settings file on startup
     autoload_enable = self.gui.get_object("AutoLoadTaskFile")
     autoload_box = self.gui.get_object("StartupTaskFileBox")
     autoload_source = self.gui.get_object("StartupTaskFile")
     # TODO: fix the extension filter
     #for one_filter in get_filters_from_list(FILTER_CONFIG):
     #    autoload_source.add_filter(one_filter)
     #    autoload_source.set_filter(one_filter)
     def get_autoload_task_file(autoload_source=autoload_source):
         if autoload_enable.get_active():
             return autoload_source.get_filename()
         else:
             return ""
     def set_autoload_task_file(filename):
         if filename:
             autoload_enable.set_active(True)
             autoload_box.show()
             autoload_source.set_filename(filename)
         else:
             autoload_enable.set_active(False)
             autoload_box.hide()
             autoload_source.unselect_all()
     def autoload_enable_switched(widget, box):
         if not widget.get_active():
             set_autoload_task_file(None)
         else:
             autoload_box.show()
     autoload_enable.connect("toggled", autoload_enable_switched,
             autoload_box)
     self.settings.add_item("default_task_settings_file",
             get_autoload_task_file, set_autoload_task_file)
     def disable_gui():
         self.menubar.set_sensitive(False)
         main_tab.set_sensitive(False)
     def enable_gui():
         self.menubar.set_sensitive(True)
         main_tab.set_sensitive(True)
     self.settings.register_event("gui-disable", disable_gui)
     self.settings.register_event("gui-enable", enable_gui)
     # configure locations of external programs
     for auto_control_name, location_control_name, browse_button, key in (
             ("ExternalProgramInkscapeAuto",
             "ExternalProgramInkscapeControl",
             "ExternalProgramInkscapeBrowse", "inkscape"),
             ("ExternalProgramPstoeditAuto",
             "ExternalProgramPstoeditControl",
             "ExternalProgramPstoeditBrowse", "pstoedit")):
         self.gui.get_object(auto_control_name).connect("clicked",
                 self._locate_external_program, key)
         location_control = self.gui.get_object(location_control_name)
         self.settings.add_item("external_program_%s" % key,
                 location_control.get_text, location_control.set_text)
         self.gui.get_object(browse_button).connect("clicked",
                 self._browse_external_program_location, key)
     # set the icons (in different sizes) for all windows
     gtk.window_set_default_icon_list(*get_icons_pixbuffers())
     # load menu data
     gtk_menu_file = get_ui_file_location(GTKMENU_FILE)
     if gtk_menu_file is None:
         gtk.main_quit()
     uimanager.add_ui_from_file(gtk_menu_file)
     # make the actions defined in the GTKBUILD file available in the menu
     actiongroup = gtk.ActionGroup("menubar")
     for action in [action for action in self.gui.get_objects()
             if isinstance(action, gtk.Action)]:
         actiongroup.add_action(action)
     # the "pos" parameter is optional since 2.12 - we can remove it later
     uimanager.insert_action_group(actiongroup, pos=-1)
     # the "recent files" sub-menu
     if not self.recent_manager is None:
         recent_files_menu = gtk.RecentChooserMenu(self.recent_manager)
         recent_files_menu.set_name("RecentFilesMenu")
         recent_menu_filter = gtk.RecentFilter()
         case_converter = pycam.Utils.get_case_insensitive_file_pattern
         for filter_name, patterns in FILTER_MODEL:
             if not isinstance(patterns, (list, set, tuple)):
                 patterns = [patterns]
             # convert it into a mutable list (instead of set/tuple)
             patterns = list(patterns)
             for index in range(len(patterns)):
                 patterns[index] = case_converter(patterns[index])
             for pattern in patterns:
                 recent_menu_filter.add_pattern(pattern)
         recent_files_menu.add_filter(recent_menu_filter)
         recent_files_menu.set_show_numbers(True)
         # non-local files (without "file://") are not supported. yet
         recent_files_menu.set_local_only(False)
         # most recent files to the top
         recent_files_menu.set_sort_type(gtk.RECENT_SORT_MRU)
         # show only ten files
         recent_files_menu.set_limit(10)
         uimanager.get_widget("/MenuBar/FileMenu/OpenRecentModelMenu")\
                 .set_submenu(recent_files_menu)
         recent_files_menu.connect("item-activated",
                 self.load_recent_model_file)
     else:
         self.gui.get_object("OpenRecentModel").set_visible(False)
     # load the menubar and connect functions to its items
     self.menubar = uimanager.get_widget("/MenuBar")
     # dict of all merge-ids
     menu_merges = {}
     def clear_menu(menu_key):
         for merge in menu_merges.get(menu_key, []):
             uimanager.remove_ui(merge)
     def append_menu_item(menu_key, base_path, widget, name):
         merge_id = uimanager.new_merge_id()
         if widget:
             action_group = widget.props.action_group
             if not action_group in uimanager.get_action_groups():
                 uimanager.insert_action_group(action_group, -1)
             widget_name = widget.get_name()
             item_type = gtk.UI_MANAGER_MENUITEM
         else:
             widget_name = name
             item_type = gtk.UI_MANAGER_SEPARATOR
         uimanager.add_ui(merge_id, base_path, name, widget_name, item_type,
                 False)
         if not menu_key in menu_merges:
             menu_merges[menu_key] = []
         menu_merges[menu_key].append(merge_id)
     def get_menu_funcs(menu_key, base_path):
         append_func = lambda widget, name: \
                 append_menu_item(menu_key, base_path, widget, name)
         clear_func = lambda: clear_menu(menu_key)
         return append_func, clear_func
     for ui_name, base_path in (("view_menu", "/MenuBar/ViewMenu"),
             ("file_menu", "/MenuBar/FileMenu"),
             ("edit_menu", "/MenuBar/EditMenu"),
             ("export_menu", "/MenuBar/FileMenu/ExportMenu")):
         append_func, clear_func = get_menu_funcs(ui_name, base_path)
         self.settings.register_ui_section(ui_name, append_func, clear_func)
     self.settings.register_ui("file_menu", "Quit",
             self.gui.get_object("Quit"), 100)
     self.settings.register_ui("file_menu", "QuitSeparator", None, 95)
     self.settings.register_ui("main_window", "Main", self.menubar, -100)
     # initialize plugins
     self.plugin_manager = pycam.Plugins.PluginManager(core=self.settings)
     self.plugin_manager.import_plugins()
     # some more initialization
     self.reset_preferences()
     # TODO: preferences are not loaded until the new format is stable
     #self.load_preferences()
     #self.load_task_settings()
     self.settings.register_event("notify-file-saved",
             self.add_to_recent_file_list)
     self.settings.register_event("notify-file-opened",
             self.add_to_recent_file_list)
     # fallback - in case of a failure when opening a model file
     model = pycam.Importers.TestModel.get_test_model()
     self.settings.get("models").add_model(model, "Tiny pyramid")
     # Without this "gkt.main_iteration" loop the task settings file
     # control would not be updated in time.
     while gtk.events_pending():
         gtk.main_iteration()
     autoload_task_filename = self.settings.get("default_task_settings_file")
     if autoload_task_filename:
         self.open_task_settings_file(autoload_task_filename)
     self.update_all_controls()
     self.no_dialog = no_dialog
     if not self.no_dialog:
         # register a logging handler for displaying error messages
         pycam.Utils.log.add_gtk_gui(self.window, logging.ERROR)
         self.window.show()