예제 #1
0
 def add_window(self, window):
     super().add_window(window)
     common.setup_window(window)
예제 #2
0
    def __init__(self):
        # Fake windows to avoid warning about Dialog without transient
        self._window = Gtk.Window()
        self.dialog = Gtk.Dialog(title="Tryton - " + _('Login'), modal=True)
        self.dialog.set_transient_for(self._window)
        self.dialog.set_icon(TRYTON_ICON)
        self.dialog.set_position(Gtk.WindowPosition.CENTER_ALWAYS)
        self.dialog.set_resizable(False)
        common.setup_window(self.dialog)

        tooltips = common.Tooltips()
        button_cancel = Gtk.Button(label=_('_Cancel'), use_underline=True)
        tooltips.set_tip(button_cancel,
            _('Cancel connection to the Tryton server'))
        self.dialog.add_action_widget(button_cancel, Gtk.ResponseType.CANCEL)
        self.button_connect = Gtk.Button(
            label=_('C_onnect'), use_underline=True)
        self.button_connect.get_style_context().add_class(
            Gtk.STYLE_CLASS_SUGGESTED_ACTION)
        self.button_connect.set_can_default(True)
        tooltips.set_tip(self.button_connect, _('Connect the Tryton server'))
        self.dialog.add_action_widget(self.button_connect, Gtk.ResponseType.OK)
        self.dialog.set_default_response(Gtk.ResponseType.OK)
        grid = Gtk.Grid(
            column_spacing=3, row_spacing=3, valign=Gtk.Align.START)
        self.dialog.vbox.pack_start(grid, expand=True, fill=True, padding=0)

        image = Gtk.Image()
        image.set_from_file(os.path.join(PIXMAPS_DIR, 'tryton.svg'))
        image.set_valign(Gtk.Align.START)
        overlay = Gtk.Overlay()
        overlay.add(image)
        label = Gtk.Label(
            label='<span color="white">%s</span>' % __version__,
            use_markup=True)
        label.props.halign = Gtk.Align.END
        label.props.valign = Gtk.Align.START
        label.props.margin_right = 10
        label.props.margin_top = 5
        overlay.add_overlay(label)
        grid.attach(overlay, 0, 0, 3, 1)

        self.profile_store = Gtk.ListStore(
            GObject.TYPE_STRING, GObject.TYPE_BOOLEAN)
        self.combo_profile = Gtk.ComboBox(hexpand=True)
        cell = Gtk.CellRendererText()
        self.combo_profile.pack_start(cell, expand=True)
        self.combo_profile.add_attribute(cell, 'text', 0)
        self.combo_profile.add_attribute(cell, 'sensitive', 1)
        self.combo_profile.set_model(self.profile_store)
        self.combo_profile.connect('changed', self.profile_changed)
        self.profile_label = Gtk.Label(
            label=set_underline(_('Profile:')),
            use_underline=True, halign=Gtk.Align.END)
        self.profile_label.set_mnemonic_widget(self.combo_profile)
        self.profile_button = Gtk.Button(
            label=set_underline(_('Manage...')), use_underline=True)
        self.profile_button.connect('clicked', self.profile_manage)
        grid.attach(self.profile_label, 0, 1, 1, 1)
        grid.attach(self.combo_profile, 1, 1, 1, 1)
        grid.attach(self.profile_button, 2, 1, 1, 1)
        self.expander = Gtk.Expander()
        self.expander.set_label(_('Host / Database information'))
        self.expander.connect('notify::expanded', self.expand_hostspec)
        grid.attach(self.expander, 0, 2, 3, 1)
        self.label_host = Gtk.Label(
            label=set_underline(_('Host:')),
            use_underline=True, halign=Gtk.Align.END)
        self.entry_host = Gtk.Entry(hexpand=True)
        self.entry_host.connect_after('focus-out-event',
            self.clear_profile_combo)
        self.entry_host.set_activates_default(True)
        self.label_host.set_mnemonic_widget(self.entry_host)
        grid.attach(self.label_host, 0, 3, 1, 1)
        grid.attach(self.entry_host, 1, 3, 2, 1)
        self.label_database = Gtk.Label(
            label=set_underline(_('Database:')),
            use_underline=True, halign=Gtk.Align.END)
        self.entry_database = Gtk.Entry(hexpand=True)
        self.entry_database.connect_after('focus-out-event',
            self.clear_profile_combo)
        self.entry_database.set_activates_default(True)
        self.label_database.set_mnemonic_widget(self.entry_database)
        grid.attach(self.label_database, 0, 4, 1, 1)
        grid.attach(self.entry_database, 1, 4, 2, 1)
        self.entry_login = Gtk.Entry(hexpand=True)
        self.entry_login.set_activates_default(True)
        grid.attach(self.entry_login, 1, 5, 2, 1)
        label_username = Gtk.Label(
            label=set_underline(_("User name:")),
            use_underline=True, halign=Gtk.Align.END, margin=3)
        label_username.set_mnemonic_widget(self.entry_login)
        grid.attach(label_username, 0, 5, 1, 1)

        # Profile information
        self.profile_cfg = os.path.join(get_config_dir(), 'profiles.cfg')
        self.profiles = configparser.ConfigParser()
        if not os.path.exists(self.profile_cfg):
            short_version = '.'.join(__version__.split('.', 2)[:2])
            name = 'demo%s.tryton.org' % short_version
            self.profiles.add_section(name)
            self.profiles.set(name, 'host', name)
            self.profiles.set(name, 'database', 'demo%s' % short_version)
            self.profiles.set(name, 'username', 'demo')
        else:
            try:
                self.profiles.read(self.profile_cfg)
            except configparser.ParsingError:
                logger.error("Fail to parse profiles.cfg", exc_info=True)
        for section in self.profiles.sections():
            active = all(self.profiles.has_option(section, option)
                for option in ('host', 'database'))
            self.profile_store.append([section, active])
예제 #3
0
    def do_activate(self):
        if self.window:
            self.window.present()
            return

        self.window = Gtk.ApplicationWindow(application=self, title="Tryton")
        self.window.set_default_size(960, 720)
        self.window.maximize()
        self.window.set_position(Gtk.WindowPosition.CENTER)
        self.window.set_resizable(True)
        self.window.set_icon(TRYTON_ICON)
        self.window.connect("destroy", self.on_quit)
        self.window.connect("delete_event", self.on_quit)
        common.setup_window(self.window)

        self.header = Gtk.HeaderBar.new()
        self.header.set_show_close_button(True)
        self.window.set_titlebar(self.header)
        self.set_title()

        self.primary_menu = Gtk.MenuButton.new()
        self.primary_menu.set_menu_model(self._get_primary_menu())
        self.header.pack_end(self.primary_menu)

        menu = Gtk.Button.new()
        menu.set_relief(Gtk.ReliefStyle.NONE)
        menu.set_image(
            common.IconFactory.get_image('tryton-menu', Gtk.IconSize.BUTTON))
        menu.connect('clicked', self.menu_toggle)
        self.header.pack_start(menu)

        favorite = Gtk.MenuButton.new()
        favorite.set_relief(Gtk.ReliefStyle.NONE)
        favorite.set_image(
            common.IconFactory.get_image('tryton-bookmarks',
                                         Gtk.IconSize.BUTTON))
        self.menu_favorite = Gtk.Menu.new()
        favorite.set_popup(self.menu_favorite)
        favorite.connect('button-press-event', self.favorite_set)
        self.header.pack_start(favorite)

        self.set_global_search()
        self.header.pack_start(self.global_search_entry)

        self.accel_group = Gtk.AccelGroup()
        self.window.add_accel_group(self.accel_group)

        Gtk.AccelMap.add_entry('<tryton>/Form/New', Gdk.KEY_N,
                               Gdk.ModifierType.CONTROL_MASK)
        Gtk.AccelMap.add_entry('<tryton>/Form/Save', Gdk.KEY_S,
                               Gdk.ModifierType.CONTROL_MASK)
        Gtk.AccelMap.add_entry(
            '<tryton>/Form/Duplicate', Gdk.KEY_D,
            Gdk.ModifierType.CONTROL_MASK | Gdk.ModifierType.SHIFT_MASK)
        Gtk.AccelMap.add_entry('<tryton>/Form/Delete', Gdk.KEY_D,
                               Gdk.ModifierType.CONTROL_MASK)
        Gtk.AccelMap.add_entry('<tryton>/Form/Next', Gdk.KEY_Page_Down, 0)
        Gtk.AccelMap.add_entry('<tryton>/Form/Previous', Gdk.KEY_Page_Up, 0)
        Gtk.AccelMap.add_entry('<tryton>/Form/Switch View', Gdk.KEY_L,
                               Gdk.ModifierType.CONTROL_MASK)
        Gtk.AccelMap.add_entry('<tryton>/Form/Close', Gdk.KEY_W,
                               Gdk.ModifierType.CONTROL_MASK)
        Gtk.AccelMap.add_entry('<tryton>/Form/Reload', Gdk.KEY_R,
                               Gdk.ModifierType.CONTROL_MASK)
        Gtk.AccelMap.add_entry(
            '<tryton>/Form/Attachments', Gdk.KEY_T,
            Gdk.ModifierType.CONTROL_MASK | Gdk.ModifierType.SHIFT_MASK)
        Gtk.AccelMap.add_entry(
            '<tryton>/Form/Notes', Gdk.KEY_O,
            Gdk.ModifierType.CONTROL_MASK | Gdk.ModifierType.SHIFT_MASK)
        Gtk.AccelMap.add_entry(
            '<tryton>/Form/Relate', Gdk.KEY_R,
            Gdk.ModifierType.CONTROL_MASK | Gdk.ModifierType.SHIFT_MASK)
        Gtk.AccelMap.add_entry('<tryton>/Form/Actions', Gdk.KEY_E,
                               Gdk.ModifierType.CONTROL_MASK)
        Gtk.AccelMap.add_entry('<tryton>/Form/Report', Gdk.KEY_P,
                               Gdk.ModifierType.CONTROL_MASK)
        Gtk.AccelMap.add_entry(
            '<tryton>/Form/Email', Gdk.KEY_E,
            Gdk.ModifierType.CONTROL_MASK | Gdk.ModifierType.SHIFT_MASK)
        Gtk.AccelMap.add_entry(
            '<tryton>/Form/Search', Gdk.KEY_F,
            Gdk.ModifierType.CONTROL_MASK | Gdk.ModifierType.SHIFT_MASK)

        Gtk.AccelMap.load(os.path.join(get_config_dir(), 'accel.map'))

        self.tooltips = common.Tooltips()

        self.vbox = Gtk.VBox()
        self.window.add(self.vbox)

        self.buttons = {}

        self.info = Gtk.VBox()
        self.vbox.pack_start(self.info, expand=False, fill=True, padding=0)
        if CONFIG['client.check_version']:
            common.check_version(self.info)
            GLib.timeout_add_seconds(int(CONFIG['download.frequency']),
                                     common.check_version, self.info)

        self.pane = Gtk.HPaned()
        self.vbox.pack_start(self.pane, expand=True, fill=True, padding=0)
        self.pane.set_position(int(CONFIG['menu.pane']))

        self.menu_screen = None
        self.menu = Gtk.VBox()
        self.menu.set_vexpand(True)
        self.pane.add1(self.menu)

        self.notebook = Gtk.Notebook()
        self.notebook.popup_enable()
        self.notebook.set_scrollable(True)
        self.notebook.connect_after('switch-page', self._sig_page_changt)
        self.pane.add2(self.notebook)

        self.window.show_all()

        self.pages = []
        self.previous_pages = {}
        self.current_page = 0
        self.last_page = 0
        self.dialogs = []

        # Register plugins
        tryton.plugins.register()

        self.set_title()  # Adds username/profile while password is asked
        try:
            common.Login()
        except Exception as exception:
            if (not isinstance(exception, TrytonError)
                    or exception.faultCode != 'QueryCanceled'):
                common.error(exception, traceback.format_exc())
            return self.quit()
        self.get_preferences()
예제 #4
0
    def __init__(self, parent, profile_store, profiles, callback):
        self.profiles = profiles
        self.current_database = None
        self.old_profile, self.current_profile = None, None
        self.db_cache = None
        self.updating_db = False

        # GTK Stuffs
        self.parent = parent
        self.dialog = Gtk.Dialog(
            title=_('Profile Editor'), transient_for=parent,
            modal=True, destroy_with_parent=True)
        self.ok_button = self.dialog.add_button(
            set_underline(_("Close")), Gtk.ResponseType.CLOSE)
        self.dialog.set_position(Gtk.WindowPosition.CENTER_ON_PARENT)
        self.dialog.set_icon(TRYTON_ICON)
        common.setup_window(self.dialog)

        tooltips = common.Tooltips()

        hpaned = Gtk.HPaned()
        vbox_profiles = Gtk.VBox(homogeneous=False, spacing=6)
        self.cell = Gtk.CellRendererText()
        self.cell.set_property('editable', True)
        self.cell.connect('editing-started', self.edit_started)
        self.profile_tree = Gtk.TreeView()
        self.profile_tree.set_model(profile_store)
        self.profile_tree.insert_column_with_attributes(-1, _('Profile'),
            self.cell, text=0)
        self.profile_tree.connect('cursor-changed', self.profile_selected)
        scroll = Gtk.ScrolledWindow()
        scroll.set_policy(
            Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
        scroll.add(self.profile_tree)
        self.add_button = Gtk.Button()
        self.add_button.set_image(common.IconFactory.get_image(
                'tryton-add', Gtk.IconSize.BUTTON))
        tooltips.set_tip(self.add_button, _("Add new profile"))
        self.add_button.connect('clicked', self.profile_create)
        self.remove_button = Gtk.Button()
        self.remove_button.set_image(common.IconFactory.get_image(
                'tryton-remove', Gtk.IconSize.BUTTON))
        tooltips.set_tip(self.remove_button, _("Remove selected profile"))
        self.remove_button.get_style_context().add_class(
            Gtk.STYLE_CLASS_DESTRUCTIVE_ACTION)
        self.remove_button.connect('clicked', self.profile_delete)
        bbox = Gtk.ButtonBox()
        bbox.pack_start(self.remove_button, expand=True, fill=True, padding=0)
        bbox.pack_start(self.add_button, expand=True, fill=True, padding=0)
        vbox_profiles.pack_start(scroll, expand=True, fill=True, padding=0)
        vbox_profiles.pack_start(bbox, expand=False, fill=True, padding=0)
        hpaned.add1(vbox_profiles)

        grid = Gtk.Grid(column_spacing=3, row_spacing=3)
        host = Gtk.Label(
            label=set_underline(_('Host:')),
            use_underline=True, halign=Gtk.Align.END)
        self.host_entry = Gtk.Entry(hexpand=True)
        self.host_entry.connect('focus-out-event', self.display_dbwidget)
        self.host_entry.connect('changed', self.update_profiles, 'host')
        self.host_entry.set_activates_default(True)
        host.set_mnemonic_widget(self.host_entry)
        grid.attach(host, 0, 1, 1, 1)
        grid.attach(self.host_entry, 1, 1, 1, 1)
        database = Gtk.Label(
            label=set_underline(_('Database:')),
            use_underline=True, halign=Gtk.Align.END)
        self.database_entry = Gtk.Entry()
        self.database_entry.connect('changed', self.dbentry_changed)
        self.database_entry.connect('changed', self.update_profiles,
            'database')
        self.database_entry.set_activates_default(True)
        self.database_label = Gtk.Label(valign=Gtk.Align.START)
        self.database_label.set_use_markup(True)
        self.database_combo = Gtk.ComboBoxText()
        self.database_combo.connect('changed', self.dbcombo_changed)
        self.database_progressbar = Gtk.ProgressBar()
        self.database_progressbar.set_text(_('Fetching databases list'))
        db_box = Gtk.VBox(homogeneous=True, hexpand=True)
        db_box.pack_start(
            self.database_entry, expand=True, fill=True, padding=0)
        db_box.pack_start(
            self.database_combo, expand=True, fill=True, padding=0)
        db_box.pack_start(
            self.database_label, expand=True, fill=True, padding=0)
        db_box.pack_start(
            self.database_progressbar, expand=True, fill=True, padding=0)
        # Compute size_request of box in order to prevent "form jumping"
        width, height = 0, 0
        for child in db_box.get_children():
            request = child.get_preferred_size()[0]
            width = max(width, request.width)
            height = max(height, request.height)
        db_box.set_size_request(width, height)
        grid.attach(database, 0, 2, 1, 1)
        grid.attach(db_box, 1, 2, 1, 1)
        username = Gtk.Label(
            label=set_underline(_('Username:'******'changed', self.update_profiles,
            'username')
        username.set_mnemonic_widget(self.username_entry)
        self.username_entry.set_activates_default(True)
        grid.attach(username, 0, 3, 1, 1)
        grid.attach(self.username_entry, 1, 3, 1, 1)
        hpaned.add2(grid)
        hpaned.set_position(250)

        self.dialog.vbox.pack_start(hpaned, expand=True, fill=True, padding=0)
        self.dialog.set_default_size(640, 350)
        self.dialog.set_default_response(Gtk.ResponseType.CLOSE)

        self.dialog.connect('close', lambda *a: False)
        self.dialog.connect('response', self.response)
        self.callback = callback