def add_window(self, window): super().add_window(window) common.setup_window(window)
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])
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()
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