예제 #1
0
파일: __init__.py 프로젝트: Devecoop/tryton
def register():
    global MODULES
    paths = [
        os.path.join(get_config_dir(), 'plugins'),
        os.path.dirname(__file__),
        # py2exe
        os.path.join(
            os.path.abspath(os.path.normpath(os.path.dirname(sys.argv[0]))),
            'plugins'),
    ]
    paths = filter(os.path.isdir, paths)

    imported = set()
    for path in paths:
        for plugin in os.listdir(path):
            module = os.path.splitext(plugin)[0]
            if module == '__init__' or module in imported:
                continue
            try:
                module = imp.load_module(module,
                                         *imp.find_module(module, [path]))
                MODULES.append(module)
            except ImportError:
                continue
            else:
                imported.add(module.__name__)
예제 #2
0
파일: __init__.py 프로젝트: tryton/tryton
def register():
    global MODULES
    paths = [
        os.path.join(get_config_dir(), 'plugins'),
        os.path.join(CURRENT_DIR, 'plugins'),
        ]
    paths = list(filter(os.path.isdir, paths))

    imported = set()
    for path in paths:
        finder = importlib.machinery.FileFinder(
            path, (
                importlib.machinery.SourceFileLoader,
                importlib.machinery.SOURCE_SUFFIXES))
        for plugin in os.listdir(path):
            module = os.path.splitext(plugin)[0]
            if (module.startswith('_') or module in imported):
                continue
            module = 'tryton.plugins.%s' % module
            spec = finder.find_spec(module)
            if not spec:
                continue
            module = importlib.util.module_from_spec(spec)
            try:
                spec.loader.exec_module(module)
            except ImportError:
                continue
            else:
                MODULES.append(module)
                imported.add(module.__name__)
예제 #3
0
def main():
    CSS = b"""
    .readonly entry {
        background-color: @insensitive_bg_color;
    }
    .required entry {
        border-color: darker(@unfocused_borders);
    }
    .invalid entry, entry.invalid {
        border-color: @error_color;
    }
    """

    screen = Gdk.Screen.get_default()
    style_context = Gtk.StyleContext()
    provider = Gtk.CssProvider()
    provider.load_from_data(CSS)
    style_context.add_provider_for_screen(
        screen, provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
    theme_path = os.path.join(get_config_dir(), 'theme.css')
    if os.path.exists(theme_path):
        provider = Gtk.CssProvider()
        provider.load_from_path(theme_path)
        style_context.add_provider_for_screen(screen, provider,
                                              Gtk.STYLE_PROVIDER_PRIORITY_USER)

    def excepthook(type_, value, traceback_):
        common.error(str(value), ''.join(traceback.format_tb(traceback_)))

    sys.excepthook = excepthook

    CONFIG.parse()
    if CONFIG.arguments:
        url = CONFIG.arguments[0]
        urlp = urlparse(url)
        if urlp.scheme == 'tryton':
            urlp = urlparse('http' + url[6:])
            database, _ = (urlp.path[1:].split('/', 1) + [None])[:2]
            CONFIG['login.host'] = urlp.netloc
            CONFIG['login.db'] = database
            CONFIG['login.expanded'] = True
        else:
            CONFIG.arguments = []
    translate.set_language_direction(CONFIG['client.language_direction'])
    translate.setlang(CONFIG['client.lang'])
    common.ICONFACTORY.load_client_icons()
    if CONFIG.arguments or DBLogin().run():
        server = '%(hostname)s:%(port)s/%(database)s' % {
            'hostname': common.get_hostname(CONFIG['login.host']),
            'port': common.get_port(CONFIG['login.host']),
            'database': CONFIG['login.db'],
        }
        server = hashlib.md5(server.encode('utf-8')).hexdigest()
        application_id = 'org.tryton._' + server
        app = gui.Main(application_id=application_id,
                       flags=Gio.ApplicationFlags.HANDLES_COMMAND_LINE)
        app.run([sys.argv[0]] + CONFIG.arguments)
예제 #4
0
파일: ipc.py 프로젝트: webmavilchez/tryton
 def __init__(self, hostname, port, database):
     if Server.instance:
         Server.instance.stop()
     self.hostname = hostname
     self.port = port
     self.database = database
     self.config = os.path.join(get_config_dir(), '%s@%s@%s' %
             (self.hostname, self.port, self.database))
     self.tmpdir = tempfile.mkdtemp(prefix='.tryton')
     Server.instance = self
예제 #5
0
파일: ipc.py 프로젝트: xt0ph/tryton
 def __init__(self, hostname, port, database):
     from tryton.common import slugify
     if Server.instance:
         Server.instance.stop()
     self.hostname = slugify(hostname).lower()
     self.port = port
     self.database = slugify(database)
     self.config = os.path.join(get_config_dir(), '%s@%s@%s' %
             (self.hostname, self.port, self.database))
     self.tmpdir = tempfile.mkdtemp(prefix='.tryton')
     Server.instance = self
예제 #6
0
    def run(self):
        main = gui.Main(self)

        signal.signal(signal.SIGINT, lambda signum, frame: main.sig_quit())
        signal.signal(signal.SIGTERM, lambda signum, frame: main.sig_quit())
        if hasattr(signal, 'SIGQUIT'):
            signal.signal(signal.SIGQUIT,
                          lambda signum, frame: main.sig_quit())

        def excepthook(exctyp, exception, tb):
            import common
            import traceback
            from tryton.exceptions import TrytonServerError
            if (CONFIG['sentry.dsn']
                    and not isinstance(exception, TrytonServerError)):
                log = logging.getLogger(__name__)
                log.error(''.join(
                    traceback.format_exception(exctyp, exception, tb)) + '\n' +
                          str(exception))
                sentry = Client(CONFIG['sentry.dsn'])
                sentry_id = sentry.captureException((exctyp, exception, tb))
            else:
                sentry_id = None
            tb = ''.join(traceback.format_exception(exctyp, exception, tb))
            common.process_exception(exception, tb=tb, sentry_id=sentry_id)

        sys.excepthook = excepthook

        if CONFIG['tip.autostart']:
            main.sig_tips()
        main.sig_login()

        if sys.platform == 'win32':
            # http://faq.pygtk.org/index.py?req=show&file=faq21.003.htp
            def sleeper():
                time.sleep(.001)
                return 1

            gobject.timeout_add(400, sleeper)

        try:
            if sys.platform == 'win32':
                while not self.quit_client.isSet():
                    with gtk.gdk.lock:
                        gtk.main_iteration(True)
            else:
                gtk.main()
        except KeyboardInterrupt:
            CONFIG.save()
            gtk.accel_map_save(os.path.join(get_config_dir(), 'accel.map'))
예제 #7
0
파일: client.py 프로젝트: coopengo/tryton
    def run(self):
        main = gui.Main(self)

        signal.signal(signal.SIGINT, lambda signum, frame: main.sig_quit())
        signal.signal(signal.SIGTERM, lambda signum, frame: main.sig_quit())
        if hasattr(signal, "SIGQUIT"):
            signal.signal(signal.SIGQUIT, lambda signum, frame: main.sig_quit())

        def excepthook(exctyp, exception, tb):
            import common
            import traceback
            from tryton.exceptions import TrytonServerError

            if CONFIG["sentry.dsn"] and not isinstance(exception, TrytonServerError):
                log = logging.getLogger(__name__)
                log.error("".join(traceback.format_exception(exctyp, exception, tb)) + "\n" + str(exception))
                sentry = Client(CONFIG["sentry.dsn"])
                sentry_id = sentry.captureException((exctyp, exception, tb))
            else:
                sentry_id = None
            tb = "".join(traceback.format_exception(exctyp, exception, tb))
            common.process_exception(exception, tb=tb, sentry_id=sentry_id)

        sys.excepthook = excepthook

        if CONFIG["tip.autostart"]:
            main.sig_tips()
        main.sig_login()

        if sys.platform == "win32":
            # http://faq.pygtk.org/index.py?req=show&file=faq21.003.htp
            def sleeper():
                time.sleep(0.001)
                return 1

            gobject.timeout_add(400, sleeper)

        try:
            if sys.platform == "win32":
                while not self.quit_client.isSet():
                    with gtk.gdk.lock:
                        gtk.main_iteration(True)
            else:
                gtk.main()
        except KeyboardInterrupt:
            CONFIG.save()
            gtk.accel_map_save(os.path.join(get_config_dir(), "accel.map"))
예제 #8
0
    def run(self):
        main = gui.Main(self)

        signal.signal(signal.SIGINT, lambda signum, frame: main.sig_quit())
        signal.signal(signal.SIGTERM, lambda signum, frame: main.sig_quit())
        if hasattr(signal, 'SIGQUIT'):
            signal.signal(signal.SIGQUIT,
                lambda signum, frame: main.sig_quit())

        def excepthook(exctyp, exception, tb):
            import common
            import traceback
            tb = '\n'.join(traceback.format_tb(tb))
            common.process_exception(exception, tb=tb)

        sys.excepthook = excepthook

        if CONFIG['tip.autostart']:
            main.sig_tips()
        main.sig_login()

        #XXX psyco breaks report printing
        #try:
        #    import psyco
        #    psyco.full()
        #except ImportError:
        #    pass

        if sys.platform == 'win32':
            # http://faq.pygtk.org/index.py?req=show&file=faq21.003.htp
            def sleeper():
                time.sleep(.001)
                return 1
            gobject.timeout_add(400, sleeper)

        try:
            if sys.platform == 'win32':
                while not self.quit_client.isSet():
                    with gtk.gdk.lock:
                            gtk.main_iteration(True)
            else:
                gtk.main()
        except KeyboardInterrupt:
            CONFIG.save()
            if hasattr(gtk, 'accel_map_save'):
                gtk.accel_map_save(os.path.join(get_config_dir(), 'accel.map'))
예제 #9
0
    def run(self):
        main = gui.Main(self)

        signal.signal(signal.SIGINT, lambda signum, frame: main.sig_quit())
        signal.signal(signal.SIGTERM, lambda signum, frame: main.sig_quit())
        if hasattr(signal, 'SIGQUIT'):
            signal.signal(signal.SIGQUIT,
                          lambda signum, frame: main.sig_quit())

        def excepthook(*args):
            import common
            import traceback
            detail = ''.join(traceback.format_exception(*args))
            common.error(str(args[1]), detail)

        sys.excepthook = excepthook

        #       Remove Tips
        #        if CONFIG['tip.autostart']:
        #            main.sig_tips()

        main.sig_login()

        if sys.platform == 'win32':
            # http://faq.pygtk.org/index.py?req=show&file=faq21.003.htp
            def sleeper():
                time.sleep(.001)
                return 1

            gobject.timeout_add(400, sleeper)

        try:
            if sys.platform == 'win32':
                while not self.quit_client.isSet():
                    with gtk.gdk.lock:
                        gtk.main_iteration()
            else:
                gtk.main()
        except KeyboardInterrupt:
            CONFIG.save()
            gtk.accel_map_save(os.path.join(get_config_dir(), 'accel.map'))
예제 #10
0
파일: __init__.py 프로젝트: coopengo/tryton
def register():
    global MODULES
    paths = [
        os.path.join(get_config_dir(), 'plugins'),
        os.path.join(CURRENT_DIR, 'plugins'),
        ]
    paths = filter(os.path.isdir, paths)

    imported = set()
    for path in paths:
        for plugin in os.listdir(path):
            module = os.path.splitext(plugin)[0]
            if module == '__init__' or module in imported:
                continue
            try:
                module = imp.load_module(module, *imp.find_module(module,
                        [path]))
                MODULES.append(module)
            except ImportError:
                continue
            else:
                imported.add(module.__name__)
예제 #11
0
def register():
    global MODULES
    paths = [
        os.path.join(get_config_dir(), 'plugins'),
        os.path.join(CURRENT_DIR, 'plugins'),
        ]
    paths = list(filter(os.path.isdir, paths))

    imported = set()
    for path in paths:
        for plugin in os.listdir(path):
            module = os.path.splitext(plugin)[0]
            if module == '__init__' or module in imported:
                continue
            try:
                module = imp.load_module(module, *imp.find_module(module,
                        [path]))
                MODULES.append(module)
            except ImportError:
                continue
            else:
                imported.add(module.__name__)
예제 #12
0
def register():
    global MODULES
    paths = [
        os.path.join(get_config_dir(), 'plugins'),
        os.path.join(CURRENT_DIR, 'plugins'),
    ]
    paths = list(filter(os.path.isdir, paths))

    imported = set()
    for path in paths:
        for plugin in os.listdir(path):
            module = os.path.splitext(plugin)[0]
            if (module.startswith('_') or module in imported):
                continue
            module = 'tryton.plugins.%s' % module
            try:
                module = importlib.import_module(module)
                MODULES.append(module)
            except ImportError:
                continue
            else:
                imported.add(module.__name__)
예제 #13
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)

        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)
        alignment = Gtk.Alignment(yalign=0, yscale=0, xscale=1)
        grid = Gtk.Grid(column_spacing=3, row_spacing=3)
        alignment.add(grid)
        self.dialog.vbox.pack_start(alignment,
                                    expand=True,
                                    fill=True,
                                    padding=0)

        image = Gtk.Image()
        image.set_from_file(os.path.join(PIXMAPS_DIR, 'tryton.png'))
        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)

        # Date stuff
        if CONFIG['login.date']:
            self.label_date = Gtk.Label(label=set_underline(_("Date:")),
                                        use_underline=True,
                                        halign=Gtk.Align.END)
            grid.attach(self.label_date, 0, 6, 1, 1)
            self.entry_date = Date()
            self.entry_date.props.format = '%d/%m/%Y'
            self.entry_date.props.value = datetime.date.today()
            grid.attach(self.entry_date, 1, 6, 2, 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])
예제 #14
0
파일: ipc.py 프로젝트: xt0ph/tryton
 def __init__(self, hostname, port, database):
     self.hostname = hostname
     self.port = port
     self.database = database
     self.filename = os.path.join(get_config_dir(),
             '%s@%s@%s' % (hostname, port, database))
예제 #15
0
 def do_shutdown(self):
     Gtk.Application.do_shutdown(self)
     common.Logout()
     CONFIG.save()
     Gtk.AccelMap.save(os.path.join(get_config_dir(), 'accel.map'))
예제 #16
0
def main():
    CSS = b"""
    .readonly entry, .readonly text {
        background-color: @insensitive_bg_color;
    }
    .required entry, .required text {
        border-color: darker(@unfocused_borders);
    }
    .invalid entry, entry.invalid, .invalid text, text.invalid {
        border-color: @error_color;
    }
    label.required {
        font-weight: bold;
    }
    label.editable {
        font-style: italic;
    }
    .window-title, .wizard-title {
        background-color: white;
        font-size: large;
        font-weight: bold;
    }
    .window-title .status {
        font-size: medium;
        font-weight: normal;
    }
    """

    screen = Gdk.Screen.get_default()
    style_context = Gtk.StyleContext()
    provider = Gtk.CssProvider()
    # the line below injects CSS with higher priority than the custom theme
    # -> it overrides Coog theme behavior
    # provider.load_from_data(CSS)
    style_context.add_provider_for_screen(screen, provider,
                                          Gtk.STYLE_PROVIDER_PRIORITY_USER)
    theme_path = os.path.join(get_config_dir(), 'theme.css')
    if os.path.exists(theme_path):
        provider = Gtk.CssProvider()
        provider.load_from_path(theme_path)
        style_context.add_provider_for_screen(screen, provider,
                                              Gtk.STYLE_PROVIDER_PRIORITY_USER)

    def excepthook(type_, value, traceback_):
        common.error(value, ''.join(traceback.format_tb(traceback_)))

    sys.excepthook = excepthook

    CONFIG.parse()
    if CONFIG.arguments:
        url = CONFIG.arguments[0]
        urlp = urlparse(url)
        if urlp.scheme == 'tryton':
            urlp = urlparse('http' + url[6:])
            database, _ = (urlp.path[1:].split('/', 1) + [None])[:2]
            CONFIG['login.host'] = urlp.netloc
            CONFIG['login.db'] = database
            CONFIG['login.expanded'] = True
        else:
            CONFIG.arguments = []
    translate.set_language_direction(CONFIG['client.language_direction'])
    translate.setlang(CONFIG['client.lang'])
    if CONFIG.arguments or DBLogin().run():
        server = '%(hostname)s:%(port)s/%(database)s' % {
            'hostname': common.get_hostname(CONFIG['login.host']),
            'port': common.get_port(CONFIG['login.host']),
            'database': CONFIG['login.db'],
        }
        server = hashlib.md5(server.encode('utf-8')).hexdigest()
        application_id = 'org.tryton._' + server
        app = gui.Main(application_id=application_id,
                       flags=Gio.ApplicationFlags.HANDLES_COMMAND_LINE)
        app.run([sys.argv[0]] + CONFIG.arguments)
예제 #17
0
from tryton.config import get_config_dir
from tryton.exceptions import TrytonServerError, TrytonServerUnavailable
from tryton.config import CONFIG

CONNECTION = None
_USER = None
_USERNAME = ''
_HOST = ''
_PORT = None
_CLIENT_DATE = None
_DATABASE = ''
CONTEXT = {}
_VIEW_CACHE = {}
_TOOLBAR_CACHE = {}
_KEYWORD_CACHE = {}
_CA_CERTS = os.path.join(get_config_dir(), 'ca_certs')
if not os.path.isfile(_CA_CERTS):
    _CA_CERTS = None
_FINGERPRINTS = Fingerprints()

ServerProxy = partial(ServerProxy,
                      fingerprints=_FINGERPRINTS,
                      ca_certs=_CA_CERTS)
ServerPool = partial(ServerPool,
                     fingerprints=_FINGERPRINTS,
                     ca_certs=_CA_CERTS)


def context_reset():
    CONTEXT.clear()
    CONTEXT['client'] = bus.ID
예제 #18
0
# This file is part of Tryton.  The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
import os
import json
import logging
from threading import Lock

from tryton.config import get_config_dir, CONFIG

logger = logging.getLogger(__name__)
COOKIES_PATH = os.path.join(get_config_dir(), 'device_cookies')

_lock = Lock()


def renew():
    from tryton.common import common

    def set_cookie(new_cookie):
        try:
            new_cookie = new_cookie()
        except Exception:
            logger.error("Cannot renew device cookie", exc_info=True)
        else:
            _set(new_cookie)

    current_cookie = get()
    common.RPCExecute('model',
                      'res.user.device',
                      'renew',
                      current_cookie,
예제 #19
0
from tryton.config import CONFIG

CONNECTION = None
_USER = None
_USERNAME = ''
_SESSION = ''
_HOST = ''
_PORT = None
_DATABASE = ''
CONTEXT = {}
_VIEW_CACHE = {}
_TOOLBAR_CACHE = {}
_KEYWORD_CACHE = {}
TIMEZONE = 'utc'
_SEMAPHORE = Semaphore()
_CA_CERTS = os.path.join(get_config_dir(), 'ca_certs')
if not os.path.isfile(_CA_CERTS):
    _CA_CERTS = None
_FINGERPRINTS = Fingerprints()

ServerProxy = partial(ServerProxy, fingerprints=_FINGERPRINTS,
    ca_certs=_CA_CERTS)


def db_list(host, port):
    try:
        connection = ServerProxy(host, port)
        logging.getLogger(__name__).info('common.db.list(None, None)')
        result = connection.common.db.list(None, None)
        logging.getLogger(__name__).debug(repr(result))
        return result
예제 #20
0
파일: dblogin.py 프로젝트: coopengo/tryton
    def __init__(self):
        # GTK Stuffs
        self.parent = common.get_toplevel_window()
        self.dialog = gtk.Dialog(title=_('Login'), parent=self.parent,
            flags=gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT)
        self.dialog.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
        self.dialog.set_has_separator(True)
        self.dialog.set_icon(TRYTON_ICON)

        tooltips = common.Tooltips()
        button_cancel = gtk.Button(_('_Cancel'))
        img_cancel = gtk.Image()
        img_cancel.set_from_stock('gtk-cancel', gtk.ICON_SIZE_BUTTON)
        button_cancel.set_image(img_cancel)
        tooltips.set_tip(button_cancel,
            _('Cancel connection to the Tryton server'))
        self.dialog.add_action_widget(button_cancel, gtk.RESPONSE_CANCEL)
        self.button_connect = gtk.Button(_('C_onnect'))
        img_connect = gtk.Image()
        img_connect.set_from_stock('tryton-connect', gtk.ICON_SIZE_BUTTON)
        self.button_connect.set_image(img_connect)
        self.button_connect.set_flags(gtk.CAN_DEFAULT)
        tooltips.set_tip(self.button_connect, _('Connect the Tryton server'))
        self.dialog.add_action_widget(self.button_connect, gtk.RESPONSE_OK)
        self.dialog.set_default_response(gtk.RESPONSE_OK)
        alignment = gtk.Alignment(yalign=0, yscale=0, xscale=1)
        self.table_main = gtk.Table(3, 3, False)
        self.table_main.set_border_width(0)
        self.table_main.set_row_spacings(3)
        self.table_main.set_col_spacings(3)
        alignment.add(self.table_main)
        self.dialog.vbox.pack_start(alignment, True, True, 0)

        image = gtk.Image()
        image.set_from_file(os.path.join(PIXMAPS_DIR, 'tryton.png'))
        image.set_alignment(0.5, 1)
        ebox = gtk.EventBox()
        ebox.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse("#1b2019"))
        ebox.add(image)
        self.table_main.attach(ebox, 0, 3, 0, 1, ypadding=2)

        self.profile_store = gtk.ListStore(gobject.TYPE_STRING,
            gobject.TYPE_BOOLEAN)
        self.combo_profile = gtk.ComboBox()
        cell = gtk.CellRendererText()
        self.combo_profile.pack_start(cell, 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(_(u'Profile:'))
        self.profile_label.set_justify(gtk.JUSTIFY_RIGHT)
        self.profile_label.set_alignment(1, 0.5)
        self.profile_label.set_padding(3, 3)
        self.profile_button = gtk.Button(_('_Manage profiles'))
        self.profile_button.connect('clicked', self.profile_manage)
        self.table_main.attach(self.profile_label, 0, 1, 1, 2,
            xoptions=gtk.FILL)
        self.table_main.attach(self.combo_profile, 1, 2, 1, 2)
        self.table_main.attach(self.profile_button, 2, 3, 1, 2,
            xoptions=gtk.FILL)
        image = gtk.Image()
        image.set_from_stock('gtk-edit', gtk.ICON_SIZE_BUTTON)
        self.profile_button.set_image(image)
        self.expander = gtk.Expander(_('Host / Database information'))
        self.expander.connect('notify::expanded', self.expand_hostspec)
        self.table_main.attach(self.expander, 0, 3, 3, 4)
        self.label_host = gtk.Label(_('Host:'))
        self.label_host.set_justify(gtk.JUSTIFY_RIGHT)
        self.label_host.set_alignment(1, 0.5)
        self.label_host.set_padding(3, 3)
        self.entry_host = gtk.Entry()
        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)
        self.table_main.attach(self.label_host, 0, 1, 4, 5, xoptions=gtk.FILL)
        self.table_main.attach(self.entry_host, 1, 3, 4, 5)
        self.label_database = gtk.Label(_('Database:'))
        self.label_database.set_justify(gtk.JUSTIFY_RIGHT)
        self.label_database.set_alignment(1, 0.5)
        self.label_database.set_padding(3, 3)
        self.entry_database = gtk.Entry()
        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)
        self.table_main.attach(self.label_database, 0, 1, 5, 6,
            xoptions=gtk.FILL)
        self.table_main.attach(self.entry_database, 1, 3, 5, 6)
        self.entry_password = gtk.Entry()
        self.entry_password.set_visibility(False)
        self.entry_password.set_activates_default(True)
        self.table_main.attach(self.entry_password, 1, 3, 7, 8)
        self.entry_login = gtk.Entry()
        self.entry_login.set_activates_default(True)
        self.table_main.attach(self.entry_login, 1, 3, 6, 7)
        label_password = gtk.Label(str=_("Password:"******"User name:"))
        label_username.set_alignment(1, 0.5)
        label_username.set_padding(3, 3)
        label_username.set_mnemonic_widget(self.entry_login)
        self.table_main.attach(label_username, 0, 1, 6, 7, xoptions=gtk.FILL)

        # Date stuff
        if CONFIG['login.date']:
            self.label_date = gtk.Label(str=_('Date:'))
            self.label_date.set_justify(gtk.JUSTIFY_RIGHT)
            self.label_date.set_alignment(1, .5)
            self.label_date.set_padding(3, 3)
            self.table_main.attach(self.label_date, 0, 1, 8, 9,
                xoptions=gtk.FILL)
            self.date_entry = Date()
            self.date_entry.props.format = '%d/%m/%Y'
            self.date_entry.props.value = datetime.date.today()
            self.table_main.attach(self.date_entry, 1, 3, 8, 9)

        # Profile informations
        self.profile_cfg = os.path.join(get_config_dir(), 'profiles.cfg')
        self.profiles = ConfigParser.SafeConfigParser({'port': '8000'})
        if not os.path.exists(self.profile_cfg) and False:
            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, 'port', '8000')
            self.profiles.set(name, 'database', 'demo%s' % short_version)
            self.profiles.set(name, 'username', 'demo')
        else:
            self.profiles.read(self.profile_cfg)
        for section in self.profiles.sections():
            active = all(self.profiles.has_option(section, option)
                for option in ('host', 'port', 'database'))
            self.profile_store.append([section, active])
예제 #21
0
}
.required entry {
    border-color: darker(@unfocused_borders);
}
.invalid entry {
    border-color: @error_color;
}
"""

screen = Gdk.Screen.get_default()
style_context = Gtk.StyleContext()
provider = Gtk.CssProvider()
provider.load_from_data(CSS)
style_context.add_provider_for_screen(screen, provider,
                                      Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
theme_path = os.path.join(get_config_dir(), 'theme.css')
if os.path.exists(theme_path):
    provider = Gtk.CssProvider()
    provider.load_from_path(theme_path)
    style_context.add_provider_for_screen(screen, provider,
                                          Gtk.STYLE_PROVIDER_PRIORITY_USER)


class TrytonClient(object):
    "Tryton client"

    def __init__(self):
        CONFIG.parse()
        if CONFIG.arguments:
            url, = CONFIG.arguments
            urlp = urlparse(url)
예제 #22
0
    def __init__(self):
        # GTK Stuffs
        self.parent = common.get_toplevel_window()
        self.dialog = gtk.Dialog(title=_('Login'), parent=self.parent,
            flags=gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT)
        self.dialog.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
        self.dialog.set_icon(GNUHEALTH_ICON)

        tooltips = common.Tooltips()
        button_cancel = gtk.Button(_('_Cancel'), use_underline=True)
        img_cancel = gtk.Image()
        img_cancel.set_from_stock('gtk-cancel', gtk.ICON_SIZE_BUTTON)
        button_cancel.set_image(img_cancel)
        tooltips.set_tip(button_cancel,
            _('Cancel connection to the GNU Health server'))
        self.dialog.add_action_widget(button_cancel, gtk.RESPONSE_CANCEL)
        self.button_connect = gtk.Button(_('C_onnect'), use_underline=True)
        img_connect = gtk.Image()
        img_connect.set_from_stock('tryton-connect', gtk.ICON_SIZE_BUTTON)
        self.button_connect.set_image(img_connect)
        self.button_connect.set_can_default(True)
        tooltips.set_tip(self.button_connect, _('Connect the GNU Health server'))
        self.dialog.add_action_widget(self.button_connect, gtk.RESPONSE_OK)
        self.dialog.set_default_response(gtk.RESPONSE_OK)
        alignment = gtk.Alignment(yalign=0, yscale=0, xscale=1)
        self.table_main = gtk.Table(3, 3, False)
        self.table_main.set_border_width(0)
        self.table_main.set_row_spacings(3)
        self.table_main.set_col_spacings(3)
        alignment.add(self.table_main)
        self.dialog.vbox.pack_start(alignment, True, True, 0)

        image = gtk.Image()
        # Use custom banner if set in the custom_banner param
        if (CONFIG['client.banner']):
            image.set_from_file(CONFIG['client.banner'])
        else:
            image.set_from_file(os.path.join(PIXMAPS_DIR, BANNER))
        image.set_alignment(0.5, 1)
        ebox = gtk.EventBox()
        ebox.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse("#1b2019"))
        ebox.add(image)
        self.table_main.attach(ebox, 0, 3, 0, 1, ypadding=2)

        self.profile_store = gtk.ListStore(gobject.TYPE_STRING,
            gobject.TYPE_BOOLEAN)
        self.combo_profile = gtk.ComboBox()
        cell = gtk.CellRendererText()
        self.combo_profile.pack_start(cell, 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(_(u'Profile:'))
        self.profile_label.set_justify(gtk.JUSTIFY_RIGHT)
        self.profile_label.set_alignment(1, 0.5)
        self.profile_label.set_padding(3, 3)
        self.profile_button = gtk.Button(_('_Manage profiles'),
            use_underline=True)
        self.profile_button.connect('clicked', self.profile_manage)
        self.table_main.attach(self.profile_label, 0, 1, 1, 2,
            xoptions=gtk.FILL)
        self.table_main.attach(self.combo_profile, 1, 2, 1, 2)
        self.table_main.attach(self.profile_button, 2, 3, 1, 2,
            xoptions=gtk.FILL)
        image = gtk.Image()
        image.set_from_stock('gtk-edit', gtk.ICON_SIZE_BUTTON)
        self.profile_button.set_image(image)
        self.expander = gtk.Expander()
        self.expander.set_label(_('Host / Database information'))
        self.expander.connect('notify::expanded', self.expand_hostspec)
        self.table_main.attach(self.expander, 0, 3, 3, 4)
        self.label_host = gtk.Label(_('Host:'))
        self.label_host.set_justify(gtk.JUSTIFY_RIGHT)
        self.label_host.set_alignment(1, 0.5)
        self.label_host.set_padding(3, 3)
        self.entry_host = gtk.Entry()
        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)
        self.table_main.attach(self.label_host, 0, 1, 4, 5, xoptions=gtk.FILL)
        self.table_main.attach(self.entry_host, 1, 3, 4, 5)
        self.label_database = gtk.Label(_('Database:'))
        self.label_database.set_justify(gtk.JUSTIFY_RIGHT)
        self.label_database.set_alignment(1, 0.5)
        self.label_database.set_padding(3, 3)
        self.entry_database = gtk.Entry()
        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)
        self.table_main.attach(self.label_database, 0, 1, 5, 6,
            xoptions=gtk.FILL)
        self.table_main.attach(self.entry_database, 1, 3, 5, 6)
        self.entry_login = gtk.Entry()
        self.entry_login.set_activates_default(True)
        self.table_main.attach(self.entry_login, 1, 3, 6, 7)
        label_username = gtk.Label(_("User name:"))
        label_username.set_alignment(1, 0.5)
        label_username.set_padding(3, 3)
        label_username.set_mnemonic_widget(self.entry_login)
        self.table_main.attach(label_username, 0, 1, 6, 7, xoptions=gtk.FILL)

        # Profile informations
        self.profile_cfg = os.path.join(get_config_dir(), 'profiles.cfg')
        self.profiles = ConfigParser.SafeConfigParser({'port': '8000'})
        if not os.path.exists(self.profile_cfg):
            short_version = '.'.join(__version__.split('.', 2)[:2])
            name = 'health.gnusolidario.org'
            self.profiles.add_section(name)
            self.profiles.set(name, 'host', name)
            self.profiles.set(name, 'port', '8000')
            self.profiles.set(name, 'database', 'health32')
            self.profiles.set(name, 'username', 'admin')
        else:
            self.profiles.read(self.profile_cfg)
        for section in self.profiles.sections():
            active = all(self.profiles.has_option(section, option)
                for option in ('host', 'port', 'database'))
            self.profile_store.append([section, active])
예제 #23
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()
예제 #24
0
    def __init__(self):
        # Fake windows to avoid warning about Dialog without transient
        self._window = gtk.Window()
        self.dialog = gtk.Dialog(title=_('Login'), flags=gtk.DIALOG_MODAL)
        self.dialog.set_transient_for(self._window)
        self.dialog.set_icon(TRYTON_ICON)
        self.dialog.set_position(gtk.WIN_POS_CENTER_ALWAYS)

        tooltips = common.Tooltips()
        button_cancel = gtk.Button(_('_Cancel'), use_underline=True)
        tooltips.set_tip(button_cancel,
            _('Cancel connection to the Tryton server'))
        self.dialog.add_action_widget(button_cancel, gtk.RESPONSE_CANCEL)
        self.button_connect = gtk.Button(_('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.RESPONSE_OK)
        self.dialog.set_default_response(gtk.RESPONSE_OK)
        alignment = gtk.Alignment(yalign=0, yscale=0, xscale=1)
        self.table_main = gtk.Table(3, 3, False)
        self.table_main.set_border_width(0)
        self.table_main.set_row_spacings(3)
        self.table_main.set_col_spacings(3)
        alignment.add(self.table_main)
        self.dialog.vbox.pack_start(alignment, True, True, 0)

        image = gtk.Image()
        image.set_from_file(os.path.join(PIXMAPS_DIR, 'tryton.png'))
        image.set_alignment(0.5, 1)
        ebox = gtk.EventBox()
        ebox.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse("#1b2019"))
        ebox.add(image)
        self.table_main.attach(ebox, 0, 3, 0, 1, ypadding=2)

        self.profile_store = gtk.ListStore(gobject.TYPE_STRING,
            gobject.TYPE_BOOLEAN)
        self.combo_profile = gtk.ComboBox()
        cell = gtk.CellRendererText()
        self.combo_profile.pack_start(cell, 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(set_underline(_('Profile:')))
        self.profile_label.set_use_underline(True)
        self.profile_label.set_justify(gtk.JUSTIFY_RIGHT)
        self.profile_label.set_alignment(1, 0.5)
        self.profile_label.set_padding(3, 3)
        self.profile_label.set_mnemonic_widget(self.combo_profile)
        self.profile_button = gtk.Button(set_underline(_('Manage...')),
            use_underline=True)
        self.profile_button.connect('clicked', self.profile_manage)
        self.table_main.attach(self.profile_label, 0, 1, 1, 2,
            xoptions=gtk.FILL)
        self.table_main.attach(self.combo_profile, 1, 2, 1, 2)
        self.table_main.attach(self.profile_button, 2, 3, 1, 2,
            xoptions=gtk.FILL)
        self.expander = gtk.Expander()
        self.expander.set_label(_('Host / Database information'))
        self.expander.connect('notify::expanded', self.expand_hostspec)
        self.table_main.attach(self.expander, 0, 3, 3, 4)
        self.label_host = gtk.Label(set_underline(_('Host:')))
        self.label_host.set_use_underline(True)
        self.label_host.set_justify(gtk.JUSTIFY_RIGHT)
        self.label_host.set_alignment(1, 0.5)
        self.label_host.set_padding(3, 3)
        self.entry_host = gtk.Entry()
        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)
        self.table_main.attach(self.label_host, 0, 1, 4, 5, xoptions=gtk.FILL)
        self.table_main.attach(self.entry_host, 1, 3, 4, 5)
        self.label_database = gtk.Label(set_underline(_('Database:')))
        self.label_database.set_use_underline(True)
        self.label_database.set_justify(gtk.JUSTIFY_RIGHT)
        self.label_database.set_alignment(1, 0.5)
        self.label_database.set_padding(3, 3)
        self.entry_database = gtk.Entry()
        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)
        self.table_main.attach(self.label_database, 0, 1, 5, 6,
            xoptions=gtk.FILL)
        self.table_main.attach(self.entry_database, 1, 3, 5, 6)
        self.entry_login = gtk.Entry()
        self.entry_login.set_activates_default(True)
        self.table_main.attach(self.entry_login, 1, 3, 6, 7)
        label_username = gtk.Label(set_underline(_("User name:")))
        label_username.set_use_underline(True)
        label_username.set_alignment(1, 0.5)
        label_username.set_padding(3, 3)
        label_username.set_mnemonic_widget(self.entry_login)
        self.table_main.attach(label_username, 0, 1, 6, 7, xoptions=gtk.FILL)

        # Date stuff
        if CONFIG['login.date']:
            self.label_date = gtk.Label()
            self.label_date.set_text('Date:')
            self.label_date.set_justify(gtk.JUSTIFY_RIGHT)
            self.label_date.set_alignment(1, .5)
            self.label_date.set_padding(3, 3)
            self.table_main.attach(self.label_date, 0, 1, 8, 9,
                xoptions=gtk.FILL)
            self.entry_date = Date()
            self.entry_date.props.format = '%d/%m/%Y'
            self.entry_date.props.value = datetime.date.today()
            self.table_main.attach(self.entry_date, 1, 3, 8, 9)

        # Profile informations
        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])
예제 #25
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.WIN_POS_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)

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

        menu = Gtk.Button.new()
        menu.set_relief(Gtk.ReliefStyle.NONE)
        icon = Gtk.Image.new()
        icon.set_from_stock('gtk-home', Gtk.IconSize.BUTTON)
        menu.set_image(icon)
        menu.connect('clicked', self.menu_toggle)
        self.header.pack_start(menu)

        favorite = Gtk.MenuButton.new()
        favorite.set_relief(Gtk.ReliefStyle.NONE)
        icon = Gtk.Image.new()
        icon.set_from_stock('tryton-bookmark', Gtk.IconSize.BUTTON)
        favorite.set_image(icon)
        self.menu_favorite = Gtk.Menu.new()
        favorite.set_popup(self.menu_favorite)
        favorite.connect('clicked', 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.accel_map_add_entry('<tryton>/Form/New', gtk.keysyms.I,
                                gtk.gdk.CONTROL_MASK)
        gtk.accel_map_add_entry('<tryton>/Form/Save', gtk.keysyms.S,
                                gtk.gdk.CONTROL_MASK)
        gtk.accel_map_add_entry('<tryton>/Form/Duplicate', gtk.keysyms.D,
                                gtk.gdk.CONTROL_MASK | gtk.gdk.SHIFT_MASK)
        gtk.accel_map_add_entry('<tryton>/Form/Delete', gtk.keysyms.D,
                                gtk.gdk.CONTROL_MASK)
        gtk.accel_map_add_entry('<tryton>/Form/Next', gtk.keysyms.Page_Down, 0)
        gtk.accel_map_add_entry('<tryton>/Form/Previous', gtk.keysyms.Page_Up,
                                0)
        gtk.accel_map_add_entry('<tryton>/Form/Switch View', gtk.keysyms.L,
                                gtk.gdk.CONTROL_MASK)
        gtk.accel_map_add_entry('<tryton>/Form/Close', gtk.keysyms.W,
                                gtk.gdk.CONTROL_MASK | gtk.gdk.SHIFT_MASK)
        gtk.accel_map_add_entry('<tryton>/Form/Reload', gtk.keysyms.R,
                                gtk.gdk.CONTROL_MASK)
        gtk.accel_map_add_entry('<tryton>/Form/Attachments', gtk.keysyms.T,
                                gtk.gdk.CONTROL_MASK | gtk.gdk.SHIFT_MASK)
        gtk.accel_map_add_entry('<tryton>/Form/Notes', gtk.keysyms.O,
                                gtk.gdk.CONTROL_MASK | gtk.gdk.SHIFT_MASK)
        gtk.accel_map_add_entry('<tryton>/Form/Relate', gtk.keysyms.R,
                                gtk.gdk.CONTROL_MASK | gtk.gdk.SHIFT_MASK)
        gtk.accel_map_add_entry('<tryton>/Form/Actions', gtk.keysyms.E,
                                gtk.gdk.CONTROL_MASK)
        gtk.accel_map_add_entry('<tryton>/Form/Report', gtk.keysyms.P,
                                gtk.gdk.CONTROL_MASK)
        gtk.accel_map_add_entry('<tryton>/Form/Search', gtk.keysyms.F,
                                gtk.gdk.CONTROL_MASK)

        gtk.accel_map_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)
        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, True, True)
        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(str(exception), traceback.format_exc())
            return self.quit()
        self.get_preferences()
예제 #26
0
# This file is part of Tryton.  The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
import os
from tryton.config import get_config_dir

KNOWN_HOSTS_PATH = os.path.join(get_config_dir(), 'known_hosts')


class Fingerprints(dict):

    def __init__(self):
        super(Fingerprints, self).__init__()
        self.load()

    def load(self):
        if not os.path.isfile(KNOWN_HOSTS_PATH):
            return
        with open(KNOWN_HOSTS_PATH) as known_hosts:
            for line in known_hosts:
                line = line.strip()
                try:
                    host, sha1 = line.split(' ')
                except ValueError:
                    host, sha1 = line, ''
                self[host] = sha1

    def save(self):
        with open(KNOWN_HOSTS_PATH, 'w') as known_hosts:
            known_hosts.writelines('%s %s' % (host, sha1)
                    + os.linesep for host, sha1 in self.iteritems())
예제 #27
0
 def __init__(self, hostname, port, database):
     self.hostname = hostname
     self.port = port
     self.database = database
     self.filename = os.path.join(get_config_dir(),
             '%s@%s@%s' % (hostname, port, database))