Factorize main and add some new window

This commit is contained in:
Cédric Krier committed 2008-07-16 16:29:12 +02:00
1 parent efb364bc29
commit 972ba7fc47
6 files changed
+568 -518

No files matched your search

+105
View File
@@ -4,6 +4,7 @@ from gtk import glade
import gobject
import gettext
import os
import re
import logging
from tryton.config import CONFIG
from tryton.config import GLADE, TRYTON_ICON, PIXMAPS_DIR, DATA_DIR
@@ -14,9 +15,113 @@ import md5
import webbrowser
import traceback
import tryton.rpc as rpc
import locale
_ = gettext.gettext
def refresh_dblist(db_widget, host, port, dbtoload=None):
if not dbtoload:
dbtoload = CONFIG['login.db']
index = 0
liststore = db_widget.get_model()
liststore.clear()
result = rpc.db_list(host, port)
from tryton.gui.main import Main
Main.get_main().refresh_ssl()
if result is None:
return None
for db_num, dbname in enumerate(result):
liststore.append([dbname])
if dbname == dbtoload:
index = db_num
db_widget.set_active(index)
return len(liststore)
def refresh_langlist(lang_widget, host, port):
liststore = lang_widget.get_model()
liststore.clear()
lang_list = rpc.db_exec(host, port, 'list_lang')
from tryton.gui.main import Main
Main.get_main().refresh_ssl()
index = -1
i = 0
lang = locale.getdefaultlocale()[0]
for key, val in lang_list:
liststore.insert(i, (val, key))
if key == lang:
index = i
if key == 'en_US' and index < 0 :
index = i
i += 1
lang_widget.set_active(index)
return lang_list
def request_server(server_widget, parent):
result = False
dialog = gtk.Dialog(
title = _('Server'),
parent = parent,
flags = gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT |
gtk.WIN_POS_CENTER_ON_PARENT |
gtk.gdk.WINDOW_TYPE_HINT_DIALOG,)
vbox = gtk.VBox()
label_connect = gtk.Label(_("<b>Connect to a Tryton server</b>"))
label_connect.set_use_markup(True)
label_connect.set_alignment(0, 0.5)
vbox.pack_start(label_connect, False, False, 0)
hseparator = gtk.HSeparator()
vbox.pack_start(hseparator, False, True, 0)
table = gtk.Table(2, 2, False)
table.set_border_width(12)
table.set_row_spacings(6)
vbox.pack_start(table, False, True, 0)
label_server = gtk.Label(_("Server:"))
label_server.set_alignment(1, 0)
label_server.set_padding(3, 0)
table.attach(label_server, 0, 1, 0, 1, yoptions=False,
xoptions=gtk.FILL)
entry_port = gtk.Entry()
entry_port.set_max_length(5)
entry_port.set_text("8069")
entry_port.set_activates_default(True)
entry_port.set_width_chars(16)
table.attach(entry_port, 1, 2, 1, 2, yoptions=False,
xoptions=gtk.FILL)
entry_server = gtk.Entry()
entry_server.set_text("localhost")
entry_server.set_activates_default(True)
entry_server.set_width_chars(16)
table.attach(entry_server, 1, 2, 0, 1,yoptions=False,
xoptions=gtk.FILL | gtk.EXPAND)
label_port = gtk.Label(_("Port:"))
label_port.set_alignment(1, 0.5)
label_port.set_padding(3, 3)
table.attach(label_port, 0, 1, 1, 2, yoptions=False,
xoptions=False)
dialog.add_button("gtk-cancel", gtk.RESPONSE_CANCEL | gtk.CAN_DEFAULT)
dialog.add_button("gtk-ok", gtk.RESPONSE_OK)
dialog.vbox.pack_start(vbox)
dialog.set_icon(TRYTON_ICON)
dialog.show_all()
dialog.set_default_response(gtk.RESPONSE_OK)
url_m = re.match('^([\w.-]+):(\d{1,5})$',
server_widget.get_text())
if url_m:
entry_server.set_text(url_m.group(1))
entry_port.set_text(url_m.group(2))
res = dialog.run()
if res == gtk.RESPONSE_OK:
host = entry_server.get_text()
port = int(entry_port.get_text())
url = '%s:%d' % (host, port)
server_widget.set_text(url)
result = (host, port)
parent.present()
dialog.destroy()
return result
def selection(title, values, parent, alwaysask=False):
if not values or len(values)==0:
+9 -518
View File
@@ -13,526 +13,17 @@ from tryton.action import Action
from tryton.gui.window import Window
from tryton.gui.window.preference import Preference
from tryton.gui.window import FilesActions
from tryton.gui.window.dblogin import DBLogin
from tryton.gui.window.dbcreate import DBCreate
from tryton.gui.window.tips import Tips
from tryton.gui.window.credits import Credits
import re
import base64
import tryton.translate as translate
import tryton.plugin
import locale
_ = gettext.gettext
def _refresh_dblist(db_widget, host, port, dbtoload=None):
if not dbtoload:
dbtoload = CONFIG['login.db']
index = 0
liststore = db_widget.get_model()
liststore.clear()
result = rpc.db_list(host, port)
Main.get_main().refresh_ssl()
if result is None:
return None
for db_num, dbname in enumerate(result):
liststore.append([dbname])
if dbname == dbtoload:
index = db_num
db_widget.set_active(index)
return len(liststore)
def _refresh_langlist(lang_widget, host, port):
liststore = lang_widget.get_model()
liststore.clear()
lang_list = rpc.db_exec(host, port, 'list_lang')
Main.get_main().refresh_ssl()
index = -1
i = 0
lang = locale.getdefaultlocale()[0]
for key, val in lang_list:
liststore.insert(i, (val, key))
if key == lang:
index = i
if key == 'en_US' and index < 0 :
index = i
i += 1
lang_widget.set_active(index)
return lang_list
def _request_server(server_widget, parent):
result = False
dialog = gtk.Dialog(
title = _('Server'),
parent = parent,
flags = gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT |
gtk.WIN_POS_CENTER_ON_PARENT |
gtk.gdk.WINDOW_TYPE_HINT_DIALOG,)
vbox = gtk.VBox()
label_connect = gtk.Label(_("<b>Connect to a Tryton server</b>"))
label_connect.set_use_markup(True)
label_connect.set_alignment(0, 0.5)
vbox.pack_start(label_connect, False, False, 0)
hseparator = gtk.HSeparator()
vbox.pack_start(hseparator, False, True, 0)
table = gtk.Table(2, 2, False)
table.set_border_width(12)
table.set_row_spacings(6)
vbox.pack_start(table, False, True, 0)
label_server = gtk.Label(_("Server:"))
label_server.set_alignment(1, 0)
label_server.set_padding(3, 0)
table.attach(label_server, 0, 1, 0, 1, yoptions=False,
xoptions=gtk.FILL)
entry_port = gtk.Entry()
entry_port.set_max_length(5)
entry_port.set_text("8069")
entry_port.set_activates_default(True)
entry_port.set_width_chars(16)
table.attach(entry_port, 1, 2, 1, 2, yoptions=False,
xoptions=gtk.FILL)
entry_server = gtk.Entry()
entry_server.set_text("localhost")
entry_server.set_activates_default(True)
entry_server.set_width_chars(16)
table.attach(entry_server, 1, 2, 0, 1,yoptions=False,
xoptions=gtk.FILL | gtk.EXPAND)
label_port = gtk.Label(_("Port:"))
label_port.set_alignment(1, 0.5)
label_port.set_padding(3, 3)
table.attach(label_port, 0, 1, 1, 2, yoptions=False,
xoptions=False)
dialog.add_button("gtk-cancel", gtk.RESPONSE_CANCEL | gtk.CAN_DEFAULT)
dialog.add_button("gtk-ok", gtk.RESPONSE_OK)
dialog.vbox.pack_start(vbox)
dialog.set_icon(TRYTON_ICON)
dialog.show_all()
dialog.set_default_response(gtk.RESPONSE_OK)
url_m = re.match('^([\w.-]+):(\d{1,5})$',
server_widget.get_text())
if url_m:
entry_server.set_text(url_m.group(1))
entry_port.set_text(url_m.group(2))
res = dialog.run()
if res == gtk.RESPONSE_OK:
host = entry_server.get_text()
port = int(entry_port.get_text())
url = '%s:%d' % (host, port)
server_widget.set_text(url)
result = (host, port)
parent.present()
dialog.destroy()
return result
class DBLogin(object):
def __init__(self, parent):
self.dialog = gtk.Dialog(title=_('Login'), parent=parent,
flags=gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT)
self.dialog.set_size_request(500, 301)
self.dialog.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
self.dialog.set_has_separator(False)
self.dialog.set_icon(TRYTON_ICON)
self.dialog.add_button(gtk.STOCK_CLOSE, 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)
self.dialog.add_action_widget(self.button_connect, gtk.RESPONSE_OK)
self.dialog.set_default_response(gtk.RESPONSE_OK)
dialog_vbox = gtk.VBox()
vbox_image = gtk.VBox()
image = gtk.Image()
image.set_from_file(os.path.join(PIXMAPS_DIR, 'tryton.png'))
image.set_size_request(500, 129)
vbox_image.pack_start(image)
dialog_vbox.pack_start(vbox_image)
table_main = gtk.Table(4, 3, False)
table_main.set_border_width(10)
table_main.set_row_spacings(3)
table_main.set_col_spacings(3)
vbox_image.pack_start(table_main, True, True, 0)
vbox_combo = gtk.VBox()
self.combo_database = gtk.ComboBox()
self.combo_label = gtk.Label()
self.combo_label.set_use_markup(True)
self.combo_label.set_alignment(0, 1)
vbox_combo.pack_start(self.combo_database, True, True, 0)
vbox_combo.pack_start(self.combo_label, False, False, 0)
table_main.attach(vbox_combo, 1, 3, 1, 2)
self.entry_password = gtk.Entry()
self.entry_password.set_visibility(False)
self.entry_password.set_activates_default(True)
table_main.attach(self.entry_password, 1, 3, 3, 4)
self.entry_login = gtk.Entry()
self.entry_login.set_text("admin")
self.entry_login.set_activates_default(True)
table_main.attach(self.entry_login, 1, 3, 2, 3)
label_server = gtk.Label()
label_server.set_text(_("Server:"))
label_server.set_alignment(1, 0.5)
label_server.set_padding(3, 3)
table_main.attach(label_server, 0, 1, 0, 1, xoptions=gtk.FILL)
label_database = gtk.Label()
label_database.set_text(_("Database:"))
label_database.set_alignment(1, 0.5)
label_database.set_padding(3, 3)
table_main.attach(label_database, 0, 1, 1, 2, xoptions=gtk.FILL)
self.entry_server = gtk.Entry()
table_main.attach(self.entry_server, 1, 2, 0, 1)
self.entry_server.set_sensitive(False)
self.entry_server.unset_flags(gtk.CAN_FOCUS)
self.entry_server.set_editable(False)
self.entry_server.set_text("localhost")
self.entry_server.set_activates_default(True)
self.entry_server.set_width_chars(16)
self.button_server = gtk.Button(label=_("C_hange"), stock=None,
use_underline=True)
table_main.attach(self.button_server, 2, 3, 0, 1, xoptions=gtk.FILL)
label_password = gtk.Label(str = _("Password:"))
label_password.set_justify(gtk.JUSTIFY_RIGHT)
label_password.set_alignment(1, 0.5)
label_password.set_padding(3, 3)
table_main.attach(label_password, 0, 1, 3, 4, xoptions=gtk.FILL)
label_username = gtk.Label(str = _("User name:"))
label_username.set_alignment(1, 0.5)
label_username.set_padding(3, 3)
table_main.attach(label_username, 0, 1, 2, 3, xoptions=gtk.FILL)
self.entry_password.grab_focus()
self.dialog.vbox.pack_start(dialog_vbox)
@staticmethod
def refreshlist(widget, db_widget, label, host, port, butconnect=None):
res = _refresh_dblist(db_widget, host, port)
if res is None:
label.set_label('<b>'+_('Could not connect to server!')+'</b>')
db_widget.hide()
label.show()
if butconnect:
butconnect.set_sensitive(False)
elif res==0:
label.set_label('<b>' + \
_('No database found, you must create one!') + '</b>')
db_widget.hide()
label.show()
if butconnect:
butconnect.set_sensitive(False)
else:
label.hide()
db_widget.show()
if butconnect:
butconnect.set_sensitive(True)
return res
@staticmethod
def refreshlist_ask(widget, server_widget, db_widget, label,
butconnect=False, host=False, port=0, parent=None):
host, port = _request_server(server_widget, parent) or (host, port)
return DBLogin.refreshlist(widget, db_widget, label, host, port,
butconnect)
def run(self, dbname, parent):
self.dialog.show_all()
self.combo_label.hide()
host = CONFIG['login.server']
port = int(CONFIG['login.port'])
url = '%s:%d' % (host, port)
self.entry_server.set_text(url)
self.entry_login.set_text(CONFIG['login.login'])
# construct the list of available db and select the last one used
liststore = gtk.ListStore(str)
self.combo_database.set_model(liststore)
cell = gtk.CellRendererText()
self.combo_database.pack_start(cell, True)
self.combo_database.add_attribute(cell, 'text', 0)
res = self.refreshlist(None, self.combo_database, self.combo_label,
host, port, self.button_connect)
self.button_server.connect_after('clicked', DBLogin.refreshlist_ask,
self.entry_server, self.combo_database, self.combo_label,
self.button_connect, host, port, self.dialog)
if dbname:
i = liststore.get_iter_root()
while i:
if liststore.get_value(i, 0)==dbname:
self.combo_database.set_active_iter(i)
break
i = liststore.iter_next(i)
res = self.dialog.run()
url_m = re.match('^([\w.:\-\d]+):(\d{1,5})$',
self.entry_server.get_text() or '')
if url_m:
CONFIG['login.server'] = url_m.group(1)
CONFIG['login.login'] = self.entry_login.get_text()
CONFIG['login.port'] = url_m.group(2)
CONFIG['login.db'] = self.combo_database.get_active_text()
result = (self.entry_login.get_text(),
self.entry_password.get_text(), url_m.group(1),
int(url_m.group(2)), self.combo_database.get_active_text())
else:
parent.present()
self.dialog.destroy()
raise Exception('QueryCanceled')
if res != gtk.RESPONSE_OK:
parent.present()
self.dialog.destroy()
rpc.logout()
Main.get_main().refresh_ssl()
raise Exception('QueryCanceled')
parent.present()
self.dialog.destroy()
return result
class DBCreate(object):
def set_sensitive(self, sensitive):
if sensitive:
label = self.dialog.get_widget('db_label_info')
label.set_text(_('Do not use special characters!'))
self.dialog.get_widget('button_db_ok').set_sensitive(True)
else:
label = self.dialog.get_widget('db_label_info')
label.set_markup('<b>' + \
_('Can not connect to server!') + '</b>')
self.dialog.get_widget('button_db_ok').set_sensitive(False)
return sensitive
def server_change(self, widget, parent):
host, port = _request_server(self.server_widget, parent)
try:
if self.lang_widget and host and port:
_refresh_langlist(self.lang_widget, host, port)
self.set_sensitive(True)
except:
self.set_sensitive(False)
return False
return url
def __init__(self, sig_login):
self.dialog = glade.XML(GLADE, "win_createdb", gettext.textdomain())
self.sig_login = sig_login
self.lang_widget = self.dialog.get_widget('db_create_combo')
self.db_widget = self.dialog.get_widget('ent_db')
self.server_widget = self.dialog.get_widget('ent_server_new')
def run(self, parent):
win = self.dialog.get_widget('win_createdb')
win.set_default_response(gtk.RESPONSE_OK)
win.set_transient_for(parent)
win.show_all()
pass_widget = self.dialog.get_widget('ent_password_new')
change_button = self.dialog.get_widget('but_server_new')
change_button.connect_after('clicked', self.server_change, win)
host = CONFIG['login.server']
port = int(CONFIG['login.port'])
url = '%s:%d' % (host, port)
self.server_widget.set_text(url)
liststore = gtk.ListStore(str, str)
self.lang_widget.set_model(liststore)
try:
_refresh_langlist(self.lang_widget, host, port)
except:
self.set_sensitive(False)
while True:
res = win.run()
dbname = self.db_widget.get_text()
if (res==gtk.RESPONSE_OK) \
and ((not dbname) \
or (not re.match('^[a-zA-Z][a-zA-Z0-9_]+$', dbname))):
common.warning(_('The database name must contain ' \
'only normal characters or "_".\n' \
'You must avoid all accents, space ' \
'or special characters.'), parent,
_('Bad database name!'))
else:
break
langidx = self.lang_widget.get_active_iter()
langreal = langidx \
and self.lang_widget.get_model().get_value(langidx, 1)
passwd = pass_widget.get_text()
url = self.server_widget.get_text()
url_m = re.match('^([\w.\-]+):(\d{1,5})$',
url or '')
if url_m:
CONFIG['login.server'] = host = url_m.group(1)
CONFIG['login.port'] = port = url_m.group(2)
parent.present()
win.destroy()
if res == gtk.RESPONSE_OK:
try:
if rpc.db_exec(host, int(port), 'db_exist', dbname):
common.warning(_('Try with an other name.'), parent,
_('The Database already exists!'))
return False
users = rpc.db_exec(host, int(port), 'create', passwd, dbname,
langreal)
Main.get_main().refresh_ssl()
except Exception, exception:
common.warning(_('The server crashed during installation.\n' \
'We suggest you to drop this database.\n' \
'Error message:\n') + str(exception[0]), parent,
_("Error during database creation!"))
return False
dialog = glade.XML(GLADE, "dia_dbcreate_ok", gettext.textdomain())
win = dialog.get_widget('dia_dbcreate_ok')
win.set_transient_for(parent)
win.show_all()
buf = dialog.get_widget('dia_tv').get_buffer()
buf.delete(buf.get_start_iter(), buf.get_end_iter())
iter_start = buf.get_start_iter()
pwdlst = '\n'.join([' - %s: %s / %s' % \
(x['name'], x['login'], x['password']) for x in users])
buf.insert(iter_start, _('The following users have been ' \
'installed on your database:') + '\n\n' + pwdlst + \
'\n\n' + _('You can now connect to the database ' \
'as an administrator.'))
res = win.run()
parent.present()
win.destroy()
if res == gtk.RESPONSE_OK:
url_m = re.match('^(http[s]?://|socket://)([\w.]+):(\d{1,5})$',
url)
res = ['admin', 'admin']
if url_m:
res.append(url_m.group(2))
res.append(url_m.group(3))
res.append(url_m.group(1))
res.append(dbname)
self.sig_login(dbname=dbname)
return True
else:
rpc.logout()
Main.get_main().refresh_ssl()
class Tips(object):
def __init__(self, parent):
self.win = gtk.Dialog(_('Tips'), parent,
gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT)
self.win.set_icon(TRYTON_ICON)
self.win.add_button(gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE)
vbox = gtk.VBox()
img = gtk.Image()
img.set_from_file(os.path.join(PIXMAPS_DIR, 'tryton.png'))
vbox.pack_start(img, False, False)
self.label = gtk.Label()
self.label.set_alignment(0, 0)
vbox.pack_start(self.label, True, True)
separator = gtk.HSeparator()
vbox.pack_start(separator, False, False)
hbox = gtk.HBox()
self.check = gtk.CheckButton(_('_Display a new tip next time'), True)
self.check.set_active(True)
hbox.pack_start(self.check)
but_previous = gtk.Button()
hbox_previous = gtk.HBox()
img_previous = gtk.Image()
img_previous.set_from_stock('tryton-go-previous', gtk.ICON_SIZE_BUTTON)
hbox_previous.pack_start(img_previous)
label_previous = gtk.Label(_('Previous'))
hbox_previous.pack_start(label_previous)
but_previous.add(hbox_previous)
but_previous.set_relief(gtk.RELIEF_NONE)
but_previous.connect('clicked', self.tip_previous)
hbox.pack_start(but_previous)
hbox_next = gtk.HBox()
label_next = gtk.Label(_('Next'))
hbox_next.pack_start(label_next)
but_next = gtk.Button()
img_next = gtk.Image()
img_next.set_from_stock('tryton-go-next', gtk.ICON_SIZE_BUTTON)
hbox_next.pack_start(img_next)
but_next.add(hbox_next)
but_next.set_relief(gtk.RELIEF_NONE)
but_next.connect('clicked', self.tip_next)
hbox.pack_start(but_next)
vbox.pack_start(hbox, False, False)
self.win.vbox.pack_start(vbox)
self.win.show_all()
try:
self.number = int(CONFIG['tip.position'])
except:
self.number = 0
self.tip_set()
self.win.run()
CONFIG['tip.autostart'] = self.check.get_active()
CONFIG['tip.position'] = self.number + 1
CONFIG.save()
parent.present()
self.win.destroy()
def tip_set(self):
lang = CONFIG['client.lang']
tip_file = False
if lang:
tip_file = os.path.join(DATA_DIR, 'tipoftheday.'+lang+'.txt')
if not os.path.isfile(tip_file):
tip_file = os.path.join(DATA_DIR, 'tipoftheday.txt')
if not os.path.isfile(tip_file):
return
tips = file(tip_file).read().split('---')
tip = tips[self.number % len(tips)].lstrip()
del tips
self.label.set_text(tip)
self.label.set_use_markup(True)
def tip_next(self, widget):
self.number += 1
self.tip_set()
def tip_previous(self, widget):
self.number -= 1
self.tip_set()
class Credits(object):
def __init__(self, parent):
self.win = gtk.Dialog(_('Credits'), parent,
gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT)
self.win.set_icon(TRYTON_ICON)
self.win.add_button(gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE)
vbox = gtk.VBox()
img = gtk.Image()
img.set_from_file(os.path.join(PIXMAPS_DIR, 'tryton.png'))
vbox.pack_start(img, False, False)
self.label = gtk.Label()
self.label.set_alignment(0.5, 0)
contributors_file = os.path.join(DATA_DIR, 'contributors.txt')
contributors = '\n' + _('<b>Contributors:</b>') + '\n\n'
contributors += file(contributors_file).read()
self.label.set_text(contributors)
self.label.set_use_markup(True)
vbox.pack_start(self.label, True, True)
self.win.vbox.pack_start(vbox)
self.win.show_all()
self.win.run()
parent.present()
self.win.destroy()
_MAIN = []
@@ -1204,7 +695,7 @@ class Main(object):
new_pass2_widget = dialog.get_widget('new_passwd2')
change_button = dialog.get_widget('but_server_change')
change_button.connect_after('clicked', \
lambda a,b: _request_server(b, win), server_widget)
lambda a,b: common.request_server(b, win), server_widget)
host = CONFIG['login.server']
port = int(CONFIG['login.port'])
@@ -1272,7 +763,7 @@ class Main(object):
def _choose_db_select(self, title=_("Backup a database")):
def refreshlist(widget, db_widget, label, host, port):
res = _refresh_dblist(db_widget, host, port)
res = common.refresh_dblist(db_widget, host, port)
if res == -1:
label.set_label('<b>' + \
_('Could not connect to server !') + '</b>')
@@ -1290,7 +781,7 @@ class Main(object):
def refreshlist_ask(widget, server_widget, db_widget, label,
parent=None):
host, port = _request_server(server_widget, parent)
host, port = common.request_server(server_widget, parent)
if not url:
return None
refreshlist(widget, db_widget, label, host, port)
@@ -1358,8 +849,8 @@ class Main(object):
widget_url.set_text(url)
change_button = dialog.get_widget('but_server_change')
change_button.connect_after('clicked', lambda a, b: _request_server(b, win),
widget_url)
change_button.connect_after('clicked',
lambda a, b: common.request_server(b, win), widget_url)
res = win.run()
+36
View File
@@ -0,0 +1,36 @@
#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 gtk
import gettext
import os
from tryton.config import TRYTON_ICON, PIXMAPS_DIR, DATA_DIR
_ = gettext.gettext
class Credits(object):
def __init__(self, parent):
self.win = gtk.Dialog(_('Credits'), parent,
gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT)
self.win.set_icon(TRYTON_ICON)
self.win.add_button(gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE)
vbox = gtk.VBox()
img = gtk.Image()
img.set_from_file(os.path.join(PIXMAPS_DIR, 'tryton.png'))
vbox.pack_start(img, False, False)
self.label = gtk.Label()
self.label.set_alignment(0.5, 0)
contributors_file = os.path.join(DATA_DIR, 'contributors.txt')
contributors = '\n' + _('<b>Contributors:</b>') + '\n\n'
contributors += file(contributors_file).read()
self.label.set_text(contributors)
self.label.set_use_markup(True)
vbox.pack_start(self.label, True, True)
self.win.vbox.pack_start(vbox)
self.win.show_all()
self.win.run()
parent.present()
self.win.destroy()
+145
View File
@@ -0,0 +1,145 @@
#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 gtk
from gtk import glade
import gettext
import re
import tryton.common as common
from tryton.config import CONFIG, GLADE, TRYTON_ICON, PIXMAPS_DIR
import tryton.rpc as rpc
_ = gettext.gettext
class DBCreate(object):
def set_sensitive(self, sensitive):
if sensitive:
label = self.dialog.get_widget('db_label_info')
label.set_text(_('Do not use special characters!'))
self.dialog.get_widget('button_db_ok').set_sensitive(True)
else:
label = self.dialog.get_widget('db_label_info')
label.set_markup('<b>' + \
_('Can not connect to server!') + '</b>')
self.dialog.get_widget('button_db_ok').set_sensitive(False)
return sensitive
def server_change(self, widget, parent):
host, port = common.request_server(self.server_widget, parent)
try:
if self.lang_widget and host and port:
common.refresh_langlist(self.lang_widget, host, port)
self.set_sensitive(True)
except:
self.set_sensitive(False)
return False
return url
def __init__(self, sig_login):
self.dialog = glade.XML(GLADE, "win_createdb", gettext.textdomain())
self.sig_login = sig_login
self.lang_widget = self.dialog.get_widget('db_create_combo')
self.db_widget = self.dialog.get_widget('ent_db')
self.server_widget = self.dialog.get_widget('ent_server_new')
def run(self, parent):
win = self.dialog.get_widget('win_createdb')
win.set_default_response(gtk.RESPONSE_OK)
win.set_transient_for(parent)
win.show_all()
pass_widget = self.dialog.get_widget('ent_password_new')
change_button = self.dialog.get_widget('but_server_new')
change_button.connect_after('clicked', self.server_change, win)
host = CONFIG['login.server']
port = int(CONFIG['login.port'])
url = '%s:%d' % (host, port)
self.server_widget.set_text(url)
liststore = gtk.ListStore(str, str)
self.lang_widget.set_model(liststore)
try:
common.refresh_langlist(self.lang_widget, host, port)
except:
self.set_sensitive(False)
while True:
res = win.run()
dbname = self.db_widget.get_text()
if (res==gtk.RESPONSE_OK) \
and ((not dbname) \
or (not re.match('^[a-zA-Z][a-zA-Z0-9_]+$', dbname))):
common.warning(_('The database name must contain ' \
'only normal characters or "_".\n' \
'You must avoid all accents, space ' \
'or special characters.'), parent,
_('Bad database name!'))
else:
break
langidx = self.lang_widget.get_active_iter()
langreal = langidx \
and self.lang_widget.get_model().get_value(langidx, 1)
passwd = pass_widget.get_text()
url = self.server_widget.get_text()
url_m = re.match('^([\w.\-]+):(\d{1,5})$',
url or '')
if url_m:
CONFIG['login.server'] = host = url_m.group(1)
CONFIG['login.port'] = port = url_m.group(2)
parent.present()
win.destroy()
if res == gtk.RESPONSE_OK:
try:
if rpc.db_exec(host, int(port), 'db_exist', dbname):
common.warning(_('Try with an other name.'), parent,
_('The Database already exists!'))
return False
users = rpc.db_exec(host, int(port), 'create', passwd, dbname,
langreal)
from tryton.gui.main import Main
Main.get_main().refresh_ssl()
except Exception, exception:
common.warning(_('The server crashed during installation.\n' \
'We suggest you to drop this database.\n' \
'Error message:\n') + str(exception[0]), parent,
_("Error during database creation!"))
return False
dialog = glade.XML(GLADE, "dia_dbcreate_ok", gettext.textdomain())
win = dialog.get_widget('dia_dbcreate_ok')
win.set_transient_for(parent)
win.show_all()
buf = dialog.get_widget('dia_tv').get_buffer()
buf.delete(buf.get_start_iter(), buf.get_end_iter())
iter_start = buf.get_start_iter()
pwdlst = '\n'.join([' - %s: %s / %s' % \
(x['name'], x['login'], x['password']) for x in users])
buf.insert(iter_start, _('The following users have been ' \
'installed on your database:') + '\n\n' + pwdlst + \
'\n\n' + _('You can now connect to the database ' \
'as an administrator.'))
res = win.run()
parent.present()
win.destroy()
if res == gtk.RESPONSE_OK:
url_m = re.match('^(http[s]?://|socket://)([\w.]+):(\d{1,5})$',
url)
res = ['admin', 'admin']
if url_m:
res.append(url_m.group(2))
res.append(url_m.group(3))
res.append(url_m.group(1))
res.append(dbname)
self.sig_login(dbname=dbname)
return True
else:
rpc.logout()
from tryton.gui.main import Main
Main.get_main().refresh_ssl()
+177
View File
@@ -0,0 +1,177 @@
#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 gtk
import os
import re
import gettext
import tryton.common as common
from tryton.config import CONFIG, TRYTON_ICON, PIXMAPS_DIR
import tryton.rpc as rpc
_ = gettext.gettext
class DBLogin(object):
def __init__(self, parent):
self.dialog = gtk.Dialog(title=_('Login'), parent=parent,
flags=gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT)
self.dialog.set_size_request(500, 301)
self.dialog.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
self.dialog.set_has_separator(False)
self.dialog.set_icon(TRYTON_ICON)
self.dialog.add_button(gtk.STOCK_CLOSE, 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)
self.dialog.add_action_widget(self.button_connect, gtk.RESPONSE_OK)
self.dialog.set_default_response(gtk.RESPONSE_OK)
dialog_vbox = gtk.VBox()
vbox_image = gtk.VBox()
image = gtk.Image()
image.set_from_file(os.path.join(PIXMAPS_DIR, 'tryton.png'))
image.set_size_request(500, 129)
vbox_image.pack_start(image)
dialog_vbox.pack_start(vbox_image)
table_main = gtk.Table(4, 3, False)
table_main.set_border_width(10)
table_main.set_row_spacings(3)
table_main.set_col_spacings(3)
vbox_image.pack_start(table_main, True, True, 0)
vbox_combo = gtk.VBox()
self.combo_database = gtk.ComboBox()
self.combo_label = gtk.Label()
self.combo_label.set_use_markup(True)
self.combo_label.set_alignment(0, 1)
vbox_combo.pack_start(self.combo_database, True, True, 0)
vbox_combo.pack_start(self.combo_label, False, False, 0)
table_main.attach(vbox_combo, 1, 3, 1, 2)
self.entry_password = gtk.Entry()
self.entry_password.set_visibility(False)
self.entry_password.set_activates_default(True)
table_main.attach(self.entry_password, 1, 3, 3, 4)
self.entry_login = gtk.Entry()
self.entry_login.set_text("admin")
self.entry_login.set_activates_default(True)
table_main.attach(self.entry_login, 1, 3, 2, 3)
label_server = gtk.Label()
label_server.set_text(_("Server:"))
label_server.set_alignment(1, 0.5)
label_server.set_padding(3, 3)
table_main.attach(label_server, 0, 1, 0, 1, xoptions=gtk.FILL)
label_database = gtk.Label()
label_database.set_text(_("Database:"))
label_database.set_alignment(1, 0.5)
label_database.set_padding(3, 3)
table_main.attach(label_database, 0, 1, 1, 2, xoptions=gtk.FILL)
self.entry_server = gtk.Entry()
table_main.attach(self.entry_server, 1, 2, 0, 1)
self.entry_server.set_sensitive(False)
self.entry_server.unset_flags(gtk.CAN_FOCUS)
self.entry_server.set_editable(False)
self.entry_server.set_text("localhost")
self.entry_server.set_activates_default(True)
self.entry_server.set_width_chars(16)
self.button_server = gtk.Button(label=_("C_hange"), stock=None,
use_underline=True)
table_main.attach(self.button_server, 2, 3, 0, 1, xoptions=gtk.FILL)
label_password = gtk.Label(str = _("Password:"))
label_password.set_justify(gtk.JUSTIFY_RIGHT)
label_password.set_alignment(1, 0.5)
label_password.set_padding(3, 3)
table_main.attach(label_password, 0, 1, 3, 4, xoptions=gtk.FILL)
label_username = gtk.Label(str = _("User name:"))
label_username.set_alignment(1, 0.5)
label_username.set_padding(3, 3)
table_main.attach(label_username, 0, 1, 2, 3, xoptions=gtk.FILL)
self.entry_password.grab_focus()
self.dialog.vbox.pack_start(dialog_vbox)
@staticmethod
def refreshlist(widget, db_widget, label, host, port, butconnect=None):
res = common.refresh_dblist(db_widget, host, port)
if res is None:
label.set_label('<b>'+_('Could not connect to server!')+'</b>')
db_widget.hide()
label.show()
if butconnect:
butconnect.set_sensitive(False)
elif res==0:
label.set_label('<b>' + \
_('No database found, you must create one!') + '</b>')
db_widget.hide()
label.show()
if butconnect:
butconnect.set_sensitive(False)
else:
label.hide()
db_widget.show()
if butconnect:
butconnect.set_sensitive(True)
return res
@staticmethod
def refreshlist_ask(widget, server_widget, db_widget, label,
butconnect=False, host=False, port=0, parent=None):
host, port = common.request_server(server_widget, parent) or (host, port)
return DBLogin.refreshlist(widget, db_widget, label, host, port,
butconnect)
def run(self, dbname, parent):
self.dialog.show_all()
self.combo_label.hide()
host = CONFIG['login.server']
port = int(CONFIG['login.port'])
url = '%s:%d' % (host, port)
self.entry_server.set_text(url)
self.entry_login.set_text(CONFIG['login.login'])
# construct the list of available db and select the last one used
liststore = gtk.ListStore(str)
self.combo_database.set_model(liststore)
cell = gtk.CellRendererText()
self.combo_database.pack_start(cell, True)
self.combo_database.add_attribute(cell, 'text', 0)
res = self.refreshlist(None, self.combo_database, self.combo_label,
host, port, self.button_connect)
self.button_server.connect_after('clicked', DBLogin.refreshlist_ask,
self.entry_server, self.combo_database, self.combo_label,
self.button_connect, host, port, self.dialog)
if dbname:
i = liststore.get_iter_root()
while i:
if liststore.get_value(i, 0)==dbname:
self.combo_database.set_active_iter(i)
break
i = liststore.iter_next(i)
res = self.dialog.run()
url_m = re.match('^([\w.:\-\d]+):(\d{1,5})$',
self.entry_server.get_text() or '')
if url_m:
CONFIG['login.server'] = url_m.group(1)
CONFIG['login.login'] = self.entry_login.get_text()
CONFIG['login.port'] = url_m.group(2)
CONFIG['login.db'] = self.combo_database.get_active_text()
result = (self.entry_login.get_text(),
self.entry_password.get_text(), url_m.group(1),
int(url_m.group(2)), self.combo_database.get_active_text())
else:
parent.present()
self.dialog.destroy()
raise Exception('QueryCanceled')
if res != gtk.RESPONSE_OK:
parent.present()
self.dialog.destroy()
rpc.logout()
from tryton.gui.main import Main
Main.get_main().refresh_ssl()
raise Exception('QueryCanceled')
parent.present()
self.dialog.destroy()
return result
+96
View File
@@ -0,0 +1,96 @@
#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 gtk
import gettext
import os
from tryton.config import CONFIG, TRYTON_ICON, PIXMAPS_DIR, DATA_DIR
_ = gettext.gettext
class Tips(object):
def __init__(self, parent):
self.win = gtk.Dialog(_('Tips'), parent,
gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT)
self.win.set_icon(TRYTON_ICON)
self.win.add_button(gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE)
vbox = gtk.VBox()
img = gtk.Image()
img.set_from_file(os.path.join(PIXMAPS_DIR, 'tryton.png'))
vbox.pack_start(img, False, False)
self.label = gtk.Label()
self.label.set_alignment(0, 0)
vbox.pack_start(self.label, True, True)
separator = gtk.HSeparator()
vbox.pack_start(separator, False, False)
hbox = gtk.HBox()
self.check = gtk.CheckButton(_('_Display a new tip next time'), True)
self.check.set_active(True)
hbox.pack_start(self.check)
but_previous = gtk.Button()
hbox_previous = gtk.HBox()
img_previous = gtk.Image()
img_previous.set_from_stock('tryton-go-previous', gtk.ICON_SIZE_BUTTON)
hbox_previous.pack_start(img_previous)
label_previous = gtk.Label(_('Previous'))
hbox_previous.pack_start(label_previous)
but_previous.add(hbox_previous)
but_previous.set_relief(gtk.RELIEF_NONE)
but_previous.connect('clicked', self.tip_previous)
hbox.pack_start(but_previous)
hbox_next = gtk.HBox()
label_next = gtk.Label(_('Next'))
hbox_next.pack_start(label_next)
but_next = gtk.Button()
img_next = gtk.Image()
img_next.set_from_stock('tryton-go-next', gtk.ICON_SIZE_BUTTON)
hbox_next.pack_start(img_next)
but_next.add(hbox_next)
but_next.set_relief(gtk.RELIEF_NONE)
but_next.connect('clicked', self.tip_next)
hbox.pack_start(but_next)
vbox.pack_start(hbox, False, False)
self.win.vbox.pack_start(vbox)
self.win.show_all()
try:
self.number = int(CONFIG['tip.position'])
except:
self.number = 0
self.tip_set()
self.win.run()
CONFIG['tip.autostart'] = self.check.get_active()
CONFIG['tip.position'] = self.number + 1
CONFIG.save()
parent.present()
self.win.destroy()
def tip_set(self):
lang = CONFIG['client.lang']
tip_file = False
if lang:
tip_file = os.path.join(DATA_DIR, 'tipoftheday.'+lang+'.txt')
if not os.path.isfile(tip_file):
tip_file = os.path.join(DATA_DIR, 'tipoftheday.txt')
if not os.path.isfile(tip_file):
return
tips = file(tip_file).read().split('---')
tip = tips[self.number % len(tips)].lstrip()
del tips
self.label.set_text(tip)
self.label.set_use_markup(True)
def tip_next(self, widget):
self.number += 1
self.tip_set()
def tip_previous(self, widget):
self.number -= 1
self.tip_set()