Remove pygtkcompat and clean most deprecation warnings

issue8139
review47841002
This commit is contained in:
Cédric Krier committed 2019-03-05 13:23:45 +01:00
1 parent b660ae55b6
commit c356bb7641
73 files changed
+2207 -2254

No files matched your search

+7
View File
@@ -1,3 +1,10 @@
* Rename email and calendar file
* Use markup for styling
* Replace ImageMenuItem by MenuItem
* Replace ComboBoxEntry by ComboBox or ComboBoxText
* Replace GObject.idle_add by GLibe.idle_add
* Remove positional arguments for PyGObject
* Remove pygtkcompat
* Implement Reference cell with Selection and Many2One cells
* Replace CellRendererBinary with clickable pixbuf cells
* Allow cell to have multiple renderers
+2 -1
View File
@@ -5,8 +5,9 @@ Prerequisites
-------------
* Python 3.4 or later (http://www.python.org/)
* gtk+ 3.20 or later and py-gobject3 (http://www.gtk.org/)
* gtk+ 3.20 or later and py-gobject3 3.20 or later (http://www.gtk.org/)
* librsvg (http://librsvg.sourceforge.net/)
* pycairo (https://pycairo.readthedocs.io/)
* python-dateutil (http://labix.org/python-dateutil)
* Optional: GooCalendar 0.4 or later (https://pypi.python.org/pypi/GooCalendar)
+2 -1
View File
@@ -110,10 +110,11 @@ dist = setup(name=name,
python_requires='>=3.4',
install_requires=[
# "py-gobject3",
'pycairo',
"python-dateutil",
],
extras_require={
'calendar': ['GooCalendar>=0.4'],
'calendar': ['GooCalendar>=0.5'],
},
zip_safe=False,
**args
+3 -183
View File
@@ -1,198 +1,18 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
__version__ = "5.1.0"
import sys
import gi
import pygtkcompat
pygtkcompat.enable()
pygtkcompat.enable_gtk(version='3.0')
try:
pygtkcompat.enable_goocanvas()
except ValueError:
pass
gi.require_version('Gtk', '3.0')
gi.require_version('Gdk', '3.0')
gi.require_foreign('cairo')
try:
gi.require_version('GtkSpell', '3.0')
except ValueError:
pass
from gi.repository import GdkPixbuf
_unset = object()
Gdk = sys.modules['gtk.gdk']
# XXX this prevents isinstance test
Gdk.PixbufLoader = GdkPixbuf.PixbufLoader.new
Gtk = sys.modules['gtk']
Gtk.widget_set_default_direction = Gtk.Widget.set_default_direction
Gtk.accel_map_add_entry = Gtk.AccelMap.add_entry
Gtk.accel_map_load = Gtk.AccelMap.load
Gtk.accel_map_save = Gtk.AccelMap.save
Gtk.PROGRESS_LEFT_TO_RIGHT = (Gtk.Orientation.HORIZONTAL, False)
Gtk.PROGRESS_RIGHT_TO_LEFT = (Gtk.Orientation.HORIZONTAL, True)
Gtk.PROGRESS_BOTTOM_TO_TOP = (Gtk.Orientation.VERTICAL, True)
Gtk.PROGRESS_TOP_TO_BOTTOM = (Gtk.Orientation.VERTICAL, False)
Gtk.CLIPBOARD_PRIMARY = Gdk.Atom.intern('PRIMARY', True)
Gtk.CLIPBOARD_CLIPBOARD = Gdk.Atom.intern('CLIPBOARD', True)
orig_tree_view_column_set_cell_data_func = (
Gtk.TreeViewColumn.set_cell_data_func)
def set_cell_data_func(self, cell, func, user_data=_unset):
def callback(*args):
if args[-1] == _unset:
args = args[:-1]
return func(*args)
orig_tree_view_column_set_cell_data_func(
self, cell, callback, user_data)
Gtk.TreeViewColumn.set_cell_data_func = set_cell_data_func
Gtk.TreeViewColumn.get_cell_renderers = Gtk.TreeViewColumn.get_cells
orig_set_orientation = Gtk.ProgressBar.set_orientation
def set_orientation(self, orientation):
orientation, inverted = orientation
orig_set_orientation(self, orientation)
self.set_inverted(inverted)
Gtk.ProgressBar.set_orientation = set_orientation
orig_set_orientation = Gtk.CellRendererProgress.set_orientation
def set_orientation(self, orientation):
orientation, inverted = orientation
orig_set_orientation(self, orientation)
self.set_property('inverted', inverted)
Gtk.CellRendererProgress.set_orientation = set_orientation
orig_popup = Gtk.Menu.popup
def popup(self, parent_menu_shell, parent_menu_item, func, button,
activate_time, data=None):
if func:
def position_func(menu, x, y, user_data=None):
return func(menu, user_data)
else:
position_func = None
orig_popup(self, parent_menu_shell, parent_menu_item,
position_func, data, button, activate_time)
Gtk.Menu.popup = popup
def get_active_text(self):
active = self.get_active()
if active < 0:
return None
else:
model = self.get_model()
index = self.get_property('entry-text-column')
return model[active][index]
Gtk.ComboBox.get_active_text = get_active_text
from gi.repository import Pango
def make_attr_constructor(method):
def constructor(value, start_index, end_index):
attr = getattr(Pango, method)(value)
attr.start_index = start_index
if end_index >= 0:
attr.end_index = end_index
return attr
return constructor
def make_attr_2_constructor(method):
def constructor(one, two, start_index, end_index):
attr = getattr(Pango, method)(one, two)
attr.start_index = start_index
if end_index >= 0:
attr.end_index = end_index
return attr
return constructor
def make_attr_3_constructor(method):
def constructor(one, two, three, start_index, end_index):
attr = getattr(Pango, method)(one, two, three)
attr.start_index = start_index
if end_index >= 0:
attr.end_index = end_index
return attr
return constructor
for method, name, constructor in [
('attr_language_new', 'AttrLanguage', make_attr_constructor),
('attr_family_new', 'AttrFamily', make_attr_constructor),
('attr_foreground_new', 'AttrForeground', make_attr_3_constructor),
('attr_background_new', 'AttrBackground', make_attr_3_constructor),
('attr_size_new', 'AttrSize', make_attr_constructor),
('attr_size_new_absolute', 'AttrSizeAbsolute',
make_attr_constructor),
('attr_style_new', 'AttrStyle', make_attr_constructor),
('attr_weight_new', 'AttrWeight', make_attr_constructor),
('attr_variant_new', 'AttrVariant', make_attr_constructor),
('attr_stretch_new', 'AttrStretch', make_attr_constructor),
('attr_font_desc_new', 'AttrFontDesc', make_attr_constructor),
('attr_underline_new', 'AttrUnderline', make_attr_constructor),
('attr_underline_color_new', 'AttrUnderlineColor',
make_attr_3_constructor),
('attr_strikethrough_new', 'AttrStrikethrough',
make_attr_constructor),
('attr_strikethrough_color_new', 'AttrStrikethroughColor',
make_attr_3_constructor),
('attr_rise_new', 'AttrRise', make_attr_constructor),
('attr_scale_new', 'AttrScale', make_attr_constructor),
('attr_fallback_new', 'AttrFallback', make_attr_constructor),
('attr_letter_spacing_new', 'AttrLetterSpacing',
make_attr_constructor),
('attr_shape_new', 'AttrShape', make_attr_2_constructor),
]:
if hasattr(Pango, method):
setattr(Pango, name, constructor(method))
import gtk
if not hasattr(gtk, 'TreePath'):
gtk.TreePath = tuple
if not hasattr(gtk, 'TargetEntry'):
gtk.TargetEntry = lambda *a: a
gtk.TargetEntry.new = lambda *a: a
if not hasattr(gtk, 'CLIPBOARD_PRIMARY'):
gtk.CLIPBOARD_PRIMARY = 'PRIMARY'
gtk.CLIPBOARD_CLIPBOARD = 'CLIPBOARD'
import gobject
try:
# Import earlier otherwise there is a segmentation fault on MSYS2
import goocalendar
except ImportError:
pass
gobject.threads_init()
if not hasattr(gtk.gdk, 'lock'):
class _Lock(object):
__enter__ = gtk.gdk.threads_enter
def __exit__(*ignored):
gtk.gdk.threads_leave()
gtk.gdk.lock = _Lock()
if sys.platform == 'win32':
class Dialog(gtk.Dialog):
def run(self):
with gtk.gdk.lock:
return super(Dialog, self).run()
gtk.Dialog = Dialog
+2 -2
View File
@@ -10,7 +10,7 @@ import uuid
from urllib.request import Request, urlopen
from urllib.error import HTTPError
from gi.repository import GObject
from gi.repository import GLib
from tryton.jsonrpc import object_hook
from tryton.config import CONFIG
@@ -85,7 +85,7 @@ def _listen(connection):
data = json.loads(response.read(), object_hook=object_hook)
if data['message']:
last_message = data['message']['message_id']
GObject.idle_add(handle, data['message'])
GLib.idle_add(handle, data['message'])
def handle(message):
+9
View File
@@ -32,6 +32,15 @@ def main():
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()
-2
View File
@@ -23,8 +23,6 @@ class Button(Gtk.Button):
image = self.get_image()
if not image and not stock:
return
elif image and image.get_stock()[0] == stock:
return
if not stock:
self.set_image(None)
return
+3 -3
View File
@@ -132,9 +132,9 @@ class CellRendererBinary(Gtk.CellRenderer):
if lwidth < 0:
lwidth = 0
layout.set_width(lwidth * Pango.SCALE)
layout.set_ellipsize(Pango.ELLIPSIZE_END)
layout.set_wrap(Pango.WRAP_CHAR)
layout.set_alignment(Pango.ALIGN_RIGHT)
layout.set_ellipsize(Pango.EllipsizeMode.END)
layout.set_wrap(Pango.WrapMode.CHAR)
layout.set_alignment(Pango.Alignment.RIGHT)
if lwidth > 0:
lw, lh = layout.get_size() # Can not use get_pixel_extents
+3 -4
View File
@@ -1,16 +1,15 @@
# 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 gobject
from gi.repository import GObject, Gtk
from tryton.common.selection import selection_shortcuts
class CellRendererCombo(gtk.CellRendererCombo):
class CellRendererCombo(Gtk.CellRendererCombo):
def on_editing_started(self, editable, path):
super().on_editing_started(editable, path)
selection_shortcuts(editable)
gobject.type_register(CellRendererCombo)
GObject.type_register(CellRendererCombo)
+8 -7
View File
@@ -1,8 +1,9 @@
# 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 gobject
import locale
from gi.repository import Gdk, GObject
from .cellrendererinteger import CellRendererInteger
@@ -18,8 +19,8 @@ class CellRendererFloat(CellRendererInteger):
def key_press_event(self, widget, event):
for name in ('KP_Decimal', 'KP_Separator'):
if event.keyval == gtk.gdk.keyval_from_name(name):
event.keyval = int(gtk.gdk.unicode_to_keyval(
if event.keyval == Gdk.keyval_from_name(name):
event.keyval = int(Gdk.unicode_to_keyval(
ord(locale.localeconv()['decimal_point'])))
def sig_insert_text(self, entry, new_text, new_text_length, position):
@@ -34,11 +35,11 @@ class CellRendererFloat(CellRendererInteger):
try:
value = locale.atof(new_value)
except ValueError:
entry.stop_emission('insert-text')
entry.stop_emission_by_name('insert-text')
return
if self.digits and not (round(value, self.digits[1]) == float(value)):
entry.stop_emission('insert-text')
entry.stop_emission_by_name('insert-text')
gobject.type_register(CellRendererFloat)
GObject.type_register(CellRendererFloat)
+6 -4
View File
@@ -1,9 +1,11 @@
# 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 gobject
from .cellrenderertext import CellRendererText
import locale
from gi.repository import GObject
from .cellrenderertext import CellRendererText
class CellRendererInteger(CellRendererText):
@@ -21,7 +23,7 @@ class CellRendererInteger(CellRendererText):
try:
locale.atoi(new_value)
except ValueError:
entry.stop_emission('insert-text')
entry.stop_emission_by_name('insert-text')
gobject.type_register(CellRendererInteger)
GObject.type_register(CellRendererInteger)
+4 -5
View File
@@ -1,10 +1,9 @@
# 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 gobject
from gi.repository import Gtk, GObject
class CellRendererText(gtk.CellRendererText):
class CellRendererText(Gtk.CellRendererText):
def __init__(self):
super(CellRendererText, self).__init__()
@@ -25,5 +24,5 @@ class CellRendererTextCompletion(CellRendererText):
self.set_completion(editable, path)
gobject.type_register(CellRendererText)
gobject.type_register(CellRendererTextCompletion)
GObject.type_register(CellRendererText)
GObject.type_register(CellRendererTextCompletion)
+3 -4
View File
@@ -1,11 +1,10 @@
# 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 gobject
from gi.repository import GObject, Gtk
class CellRendererToggle(gtk.CellRendererToggle):
class CellRendererToggle(Gtk.CellRendererToggle):
pass
gobject.type_register(CellRendererToggle)
GObject.type_register(CellRendererToggle)
+169 -152
View File
@@ -1,10 +1,6 @@
# 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 gobject
import glib
import pango
import gettext
import os
import subprocess
@@ -48,7 +44,7 @@ except ImportError:
from threading import Lock
import dateutil.tz
from gi.repository import Gtk, GLib
from gi.repository import Gdk, GdkPixbuf, GLib, GObject, Gtk
from tryton import __version__
from tryton.exceptions import TrytonServerError, TrytonError
@@ -307,32 +303,35 @@ def selection(title, values, alwaysask=False):
return (key, values[key])
parent = get_toplevel_window()
dialog = gtk.Dialog(_('Selection'), parent,
gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT)
dialog.add_button(set_underline(_("Cancel")), gtk.RESPONSE_CANCEL)
dialog.add_button(set_underline(_("OK")), gtk.RESPONSE_OK)
dialog = Gtk.Dialog(
title=_('Selection'), transient_for=parent,
modal=True, destroy_with_parent=True)
dialog.add_button(set_underline(_("Cancel")), Gtk.ResponseType.CANCEL)
dialog.add_button(set_underline(_("OK")), Gtk.ResponseType.OK)
dialog.set_icon(TRYTON_ICON)
dialog.set_default_response(gtk.RESPONSE_OK)
dialog.set_default_response(Gtk.ResponseType.OK)
dialog.set_default_size(400, 400)
label = gtk.Label(title or _('Your selection:'))
dialog.vbox.pack_start(label, False, False)
dialog.vbox.pack_start(gtk.HSeparator(), False, True)
label = Gtk.Label(title or _('Your selection:'))
dialog.vbox.pack_start(label, expand=False, fill=False, padding=0)
dialog.vbox.pack_start(
Gtk.HSeparator(), expand=False, fill=True, padding=0)
scrolledwindow = gtk.ScrolledWindow()
scrolledwindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
treeview = gtk.TreeView()
scrolledwindow = Gtk.ScrolledWindow()
scrolledwindow.set_policy(
Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
treeview = Gtk.TreeView()
treeview.set_headers_visible(False)
scrolledwindow.add(treeview)
dialog.vbox.pack_start(scrolledwindow, True, True)
dialog.vbox.pack_start(scrolledwindow, expand=True, fill=True, padding=0)
treeview.get_selection().set_mode(gtk.SELECTION_SINGLE)
cell = gtk.CellRendererText()
column = gtk.TreeViewColumn("Widget", cell, text=0)
treeview.get_selection().set_mode(Gtk.SelectionMode.SINGLE)
cell = Gtk.CellRendererText()
column = Gtk.TreeViewColumn("Widget", cell, text=0)
treeview.append_column(column)
treeview.set_search_column(0)
model = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_INT)
model = Gtk.ListStore(GObject.TYPE_STRING, GObject.TYPE_INT)
keys = list(values.keys())
keys.sort()
i = 0
@@ -342,12 +341,12 @@ def selection(title, values, alwaysask=False):
treeview.set_model(model)
treeview.connect('row-activated',
lambda x, y, z: dialog.response(gtk.RESPONSE_OK) or True)
lambda x, y, z: dialog.response(Gtk.ResponseType.OK) or True)
dialog.show_all()
response = dialog.run()
res = None
if response == gtk.RESPONSE_OK:
if response == Gtk.ResponseType.OK:
sel = treeview.get_selection().get_selected()
if sel:
(model, i) = sel
@@ -361,28 +360,29 @@ def selection(title, values, alwaysask=False):
def file_selection(title, filename='',
action=gtk.FILE_CHOOSER_ACTION_OPEN, preview=True, multi=False,
action=Gtk.FileChooserAction.OPEN, preview=True, multi=False,
filters=None):
parent = get_toplevel_window()
if action == gtk.FILE_CHOOSER_ACTION_OPEN:
buttons = (set_underline(_("Cancel")), gtk.RESPONSE_CANCEL,
set_underline(_("Select")), gtk.RESPONSE_OK)
if action == Gtk.FileChooserAction.OPEN:
buttons = (set_underline(_("Cancel")), Gtk.ResponseType.CANCEL,
set_underline(_("Select")), Gtk.ResponseType.OK)
else:
buttons = (set_underline(_("Cancel")), gtk.RESPONSE_CANCEL,
set_underline(_("Save")), gtk.RESPONSE_OK)
win = gtk.FileChooserDialog(title, None, action, buttons)
win.set_transient_for(parent)
buttons = (set_underline(_("Cancel")), Gtk.ResponseType.CANCEL,
set_underline(_("Save")), Gtk.ResponseType.OK)
win = Gtk.FileChooserDialog(
title=title, transient_for=parent, action=action)
win.add_buttons(*buttons)
win.set_icon(TRYTON_ICON)
if filename:
if action in (gtk.FILE_CHOOSER_ACTION_SAVE,
gtk.FILE_CHOOSER_ACTION_CREATE_FOLDER):
if action in (Gtk.FileChooserAction.SAVE,
Gtk.FileChooserAction.CREATE_FOLDER):
win.set_current_name(filename)
else:
win.set_filename(filename)
if hasattr(win, 'set_do_overwrite_confirmation'):
win.set_do_overwrite_confirmation(True)
win.set_select_multiple(multi)
win.set_default_response(gtk.RESPONSE_OK)
win.set_default_response(Gtk.ResponseType.OK)
if filters is not None:
for filt in filters:
win.add_filter(filt)
@@ -392,22 +392,22 @@ def file_selection(title, filename='',
filename = win.get_preview_filename()
if filename:
try:
pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(
pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size(
filename, 128, 128)
img.set_from_pixbuf(pixbuf)
have_preview = True
except (IOError, glib.GError):
except (IOError, GLib.GError):
pass
win.set_preview_widget_active(have_preview)
return
if preview:
img_preview = gtk.Image()
img_preview = Gtk.Image()
win.set_preview_widget(img_preview)
win.connect('update-preview', update_preview_cb, img_preview)
button = win.run()
if button != gtk.RESPONSE_OK:
if button != Gtk.ResponseType.OK:
result = None
elif not multi:
result = win.get_filename()
@@ -448,7 +448,7 @@ def file_write(filename, data):
def file_open(filename, type=None, print_p=False):
def save():
save_name = file_selection(_('Save As...'),
action=gtk.FILE_CHOOSER_ACTION_SAVE)
action=Gtk.FileChooserAction.SAVE)
if save_name:
file_p = open(filename, 'rb')
save_p = open(save_name, 'wb+')
@@ -555,11 +555,11 @@ class UniqueDialog(object):
class MessageDialog(UniqueDialog):
def build_dialog(self, parent, message, msg_type=gtk.MESSAGE_INFO,
buttons=gtk.BUTTONS_OK, secondary=None):
dialog = gtk.MessageDialog(parent,
gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, msg_type,
buttons, message)
def build_dialog(self, parent, message, msg_type=Gtk.MessageType.INFO,
buttons=Gtk.ButtonsType.OK, secondary=None):
dialog = Gtk.MessageDialog(
transient_for=parent, modal=True, destroy_with_parent=True,
message_type=msg_type, buttons=buttons, text=message)
if secondary:
dialog.format_secondary_text(secondary)
return dialog
@@ -573,9 +573,9 @@ message = MessageDialog()
class WarningDialog(MessageDialog):
def __call__(self, message, title, buttons=gtk.BUTTONS_OK, **kwargs):
def __call__(self, message, title, buttons=Gtk.ButtonsType.OK, **kwargs):
return super().__call__(
title, gtk.MESSAGE_WARNING, buttons, message, **kwargs)
title, Gtk.MessageType.WARNING, buttons, message, **kwargs)
warning = WarningDialog()
@@ -592,25 +592,25 @@ class UserWarningDialog(WarningDialog):
def build_dialog(self, *args, **kwargs):
dialog = super().build_dialog(*args, **kwargs)
check = gtk.CheckButton(_('Always ignore this warning.'))
check = Gtk.CheckButton(label=_('Always ignore this warning.'))
check.connect_after('toggled', self._set_always)
alignment = gtk.Alignment(0, 0.5)
alignment = Gtk.Alignment(xalign=0, yalign=0.5)
alignment.add(check)
dialog.vbox.pack_start(alignment, True, False)
label = gtk.Label(_('Do you want to proceed?'))
label.set_alignment(1, 0.5)
dialog.vbox.pack_start(label, True, True)
dialog.vbox.pack_start(alignment, expand=True, fill=False, padding=0)
label = Gtk.Label(
label=_('Do you want to proceed?'), halign=Gtk.Align.END)
dialog.vbox.pack_start(label, expand=True, fill=True, padding=0)
return dialog
def process_response(self, response):
if response == gtk.RESPONSE_YES:
if response == Gtk.ResponseType.YES:
if self.always:
return 'always'
return 'ok'
return 'cancel'
def __call__(self, message, title):
return super().__call__(message, title, gtk.BUTTONS_YES_NO)
return super().__call__(message, title, Gtk.ButtonsType.YES_NO)
userwarning = UserWarningDialog()
@@ -619,14 +619,15 @@ userwarning = UserWarningDialog()
class ConfirmationDialog(MessageDialog):
def __call__(self, message, *args, **kwargs):
return super().__call__(message, gtk.MESSAGE_QUESTION, *args, **kwargs)
return super().__call__(
message, Gtk.MessageType.QUESTION, *args, **kwargs)
class SurDialog(ConfirmationDialog):
def __call__(self, message):
response = super().__call__(message, buttons=gtk.BUTTONS_YES_NO)
return response == gtk.RESPONSE_YES
response = super().__call__(message, buttons=Gtk.ButtonsType.YES_NO)
return response == Gtk.ResponseType.YES
sur = SurDialog()
@@ -635,21 +636,21 @@ sur = SurDialog()
class Sur3BDialog(ConfirmationDialog):
response_mapping = {
gtk.RESPONSE_YES: 'ok',
gtk.RESPONSE_NO: 'ko',
gtk.RESPONSE_CANCEL: 'cancel'
Gtk.ResponseType.YES: 'ok',
Gtk.ResponseType.NO: 'ko',
Gtk.ResponseType.CANCEL: 'cancel'
}
def build_dialog(self, *args, **kwargs):
dialog = super().build_dialog(*args, **kwargs)
dialog.add_button(set_underline(_("Cancel")), gtk.RESPONSE_CANCEL)
dialog.add_button(set_underline(_("No")), gtk.RESPONSE_NO)
dialog.add_button(set_underline(_("Yes")), gtk.RESPONSE_YES)
dialog.set_default_response(gtk.RESPONSE_YES)
dialog.add_button(set_underline(_("Cancel")), Gtk.ResponseType.CANCEL)
dialog.add_button(set_underline(_("No")), Gtk.ResponseType.NO)
dialog.add_button(set_underline(_("Yes")), Gtk.ResponseType.YES)
dialog.set_default_response(Gtk.ResponseType.YES)
return dialog
def __call__(self, message):
response = super().__call__(message, buttons=gtk.BUTTONS_NONE)
response = super().__call__(message, buttons=Gtk.ButtonsType.NONE)
return self.response_mapping.get(response, 'cancel')
@@ -661,22 +662,22 @@ class AskDialog(MessageDialog):
def build_dialog(self, *args, **kwargs):
visibility = kwargs.pop('visibility')
dialog = super().build_dialog(*args, **kwargs)
dialog.set_default_response(gtk.RESPONSE_OK)
dialog.set_default_response(Gtk.ResponseType.OK)
box = dialog.get_message_area()
self.entry = gtk.Entry()
self.entry = Gtk.Entry()
self.entry.set_activates_default(True)
self.entry.set_visibility(visibility)
box.pack_start(self.entry)
box.pack_start(self.entry, False, False, 0)
return dialog
def process_response(self, response):
if response == gtk.RESPONSE_OK:
if response == Gtk.ResponseType.OK:
return self.entry.get_text()
def __call__(self, question, visibility=True):
return super().__call__(
question, gtk.MESSAGE_QUESTION, buttons=gtk.BUTTONS_OK_CANCEL,
visibility=visibility)
question, Gtk.MessageType.QUESTION,
buttons=Gtk.ButtonsType.OK_CANCEL, visibility=visibility)
ask = AskDialog()
@@ -686,31 +687,31 @@ class ConcurrencyDialog(UniqueDialog):
def build_dialog(self, parent, resource, obj_id, context):
tooltips = Tooltips()
dialog = gtk.MessageDialog(parent,
gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
gtk.MESSAGE_QUESTION, gtk.BUTTONS_NONE,
_('Concurrency Exception'))
dialog = Gtk.MessageDialog(
transient_for=parent, modal=True, destroy_with_parent=True,
message_type=Gtk.MessageType.QUESTION,
buttons=Gtk.ButtonsType.NONE, text=_('Concurrency Exception'))
dialog.format_secondary_text(
_('This record has been modified while you were editing it.'))
cancel_button = dialog.add_button(
set_underline(_("Cancel")), gtk.RESPONSE_CANCEL)
set_underline(_("Cancel")), Gtk.ResponseType.CANCEL)
tooltips.set_tip(cancel_button, _('Cancel saving'))
compare_button = dialog.add_button(
set_underline(_("Compare")), gtk.RESPONSE_APPLY)
set_underline(_("Compare")), Gtk.ResponseType.APPLY)
tooltips.set_tip(compare_button, _('See the modified version'))
write_button = dialog.add_button(
set_underline(_("Write Anyway")), gtk.RESPONSE_OK)
set_underline(_("Write Anyway")), Gtk.ResponseType.OK)
tooltips.set_tip(write_button, _('Save your current version'))
dialog.set_default_response(gtk.RESPONSE_CANCEL)
dialog.set_default_response(Gtk.ResponseType.CANCEL)
return dialog
def __call__(self, resource, obj_id, context):
res = super(ConcurrencyDialog, self).__call__(resource, obj_id,
context)
if res == gtk.RESPONSE_OK:
if res == Gtk.ResponseType.OK:
return True
if res == gtk.RESPONSE_APPLY:
if res == Gtk.ResponseType.APPLY:
from tryton.gui.window import Window
Window.create(resource,
res_id=obj_id,
@@ -726,54 +727,48 @@ concurrency = ConcurrencyDialog()
class ErrorDialog(UniqueDialog):
def build_dialog(self, parent, title, details):
dialog = gtk.MessageDialog(parent,
gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
gtk.MESSAGE_ERROR, gtk.BUTTONS_NONE,
_('Application Error'))
dialog = Gtk.MessageDialog(
transient_for=parent, modal=True, destroy_with_parent=True,
message_type=Gtk.MessageType.ERROR, buttons=Gtk.ButtonsType.NONE)
dialog.set_default_size(600, 400)
dialog.set_position(Gtk.WindowPosition.CENTER)
dialog.add_button(set_underline(_("Report Bug")), gtk.RESPONSE_OK)
dialog.add_button(set_underline(_("Close")), gtk.RESPONSE_CANCEL)
dialog.set_default_response(gtk.RESPONSE_CANCEL)
dialog.add_button(set_underline(_("Report Bug")), Gtk.ResponseType.OK)
dialog.add_button(set_underline(_("Close")), Gtk.ResponseType.CANCEL)
dialog.set_default_response(Gtk.ResponseType.CANCEL)
vbox = dialog.vbox
dialog.set_markup(
'<b>%s</b>' % GLib.markup_escape_text(_('Application Error')))
dialog.format_secondary_markup(
'<b>%s</b>' % _('Error: %s') % GLib.markup_escape_text(title))
scrolledwindow = gtk.ScrolledWindow()
scrolledwindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
scrolledwindow.set_shadow_type(gtk.SHADOW_NONE)
scrolledwindow = Gtk.ScrolledWindow()
scrolledwindow.set_policy(
Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
scrolledwindow.set_shadow_type(Gtk.ShadowType.NONE)
viewport = gtk.Viewport()
viewport.set_shadow_type(gtk.SHADOW_NONE)
viewport = Gtk.Viewport()
viewport.set_shadow_type(Gtk.ShadowType.NONE)
box = gtk.VBox()
label_error = gtk.Label()
label_error.set_markup('')
label_error.set_alignment(0, 0.5)
label_error.set_padding(-1, 14)
label_error.modify_font(pango.FontDescription("monospace"))
label_error.set_markup('<b>' + _('Error: ') + '</b>' + to_xml(title))
box.pack_start(label_error, False, False)
textview = gtk.TextView()
buf = gtk.TextBuffer()
textview = Gtk.TextView(editable=False, sensitive=True, monospace=True)
buf = Gtk.TextBuffer()
buf.set_text(details)
textview.set_buffer(buf)
textview.set_editable(False)
textview.set_sensitive(True)
textview.modify_font(pango.FontDescription("monospace"))
box.pack_start(textview, True, True)
viewport.add(box)
viewport.add(textview)
scrolledwindow.add(viewport)
vbox.pack_start(scrolledwindow, expand=True, fill=True)
dialog.vbox.pack_start(
scrolledwindow, expand=True, fill=True, padding=0)
button_roundup = Gtk.LinkButton.new_with_label(
CONFIG['roundup.url'],
_('To report bugs you must have an account on %s') %
CONFIG['roundup.url'])
button_roundup.set_alignment(0, 0.5)
button_roundup.get_child().set_halign(Gtk.Align.START)
button_roundup.connect('activate-link',
lambda widget: webbrowser.open(CONFIG['roundup.url'], new=2))
vbox.pack_start(button_roundup, False, False)
dialog.vbox.pack_start(
button_roundup, expand=False, fill=False, padding=0)
return dialog
@@ -784,7 +779,7 @@ class ErrorDialog(UniqueDialog):
log.error(details + '\n' + title)
response = super(ErrorDialog, self).__call__(title, details)
if response == gtk.RESPONSE_OK:
if response == Gtk.ResponseType.OK:
send_bugtracker(title, details)
@@ -794,43 +789,48 @@ error = ErrorDialog()
def send_bugtracker(title, msg):
from tryton import rpc
parent = get_toplevel_window()
win = gtk.Dialog(_('Bug Tracker'), parent,
gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT)
win.add_button(set_underline(_("Cancel")), gtk.RESPONSE_CANCEL)
win.add_button(set_underline(_("OK")), gtk.RESPONSE_OK)
win = Gtk.Dialog(
title=_('Bug Tracker'), transient_for=parent, modal=True,
destroy_with_parent=True)
win.add_button(set_underline(_("Cancel")), Gtk.ResponseType.CANCEL)
win.add_button(set_underline(_("OK")), Gtk.ResponseType.OK)
win.set_icon(TRYTON_ICON)
win.set_default_response(gtk.RESPONSE_OK)
win.set_default_response(Gtk.ResponseType.OK)
hbox = gtk.HBox()
hbox = Gtk.HBox()
hbox.pack_start(
IconFactory.get_image(
'tryton-info', gtk.ICON_SIZE_DIALOG),
False, False)
'tryton-info', Gtk.IconSize.DIALOG),
expand=False, fill=False, padding=0)
table = gtk.Table(2, 2)
table = Gtk.Table(n_rows=2, n_columns=2)
table.set_col_spacings(3)
table.set_row_spacings(3)
table.set_border_width(1)
label_user = gtk.Label(_('User:'))
label_user.set_alignment(1.0, 0.5)
table.attach(label_user, 0, 1, 0, 1, yoptions=False,
xoptions=gtk.FILL)
entry_user = gtk.Entry()
label_user = Gtk.Label(
label=_('User:'), halign=Gtk.Align.END)
table.attach(
label_user, 0, 1, 0, 1, yoptions=False,
xoptions=Gtk.AttachOptions.FILL)
entry_user = Gtk.Entry()
entry_user.set_activates_default(True)
table.attach(entry_user, 1, 2, 0, 1, yoptions=False,
xoptions=gtk.FILL)
label_password = gtk.Label(_('Password:'))
label_password.set_alignment(1.0, 0.5)
table.attach(label_password, 0, 1, 1, 2, yoptions=False,
xoptions=gtk.FILL)
entry_password = gtk.Entry()
table.attach(
entry_user, 1, 2, 0, 1, yoptions=False,
xoptions=Gtk.AttachOptions.FILL)
label_password = Gtk.Label(
label=_('Password:'), halign=Gtk.Align.END)
table.attach(
label_password, 0, 1, 1, 2, yoptions=False,
xoptions=Gtk.AttachOptions.FILL)
entry_password = Gtk.Entry()
entry_password.set_activates_default(True)
entry_password.set_visibility(False)
table.attach(entry_password, 1, 2, 1, 2, yoptions=False,
xoptions=gtk.FILL)
hbox.pack_start(table)
table.attach(
entry_password, 1, 2, 1, 2, yoptions=False,
xoptions=Gtk.AttachOptions.FILL)
hbox.pack_start(table, expand=True, fill=True, padding=0)
win.vbox.pack_start(hbox)
win.vbox.pack_start(hbox, expand=True, fill=True, padding=0)
win.show_all()
if rpc._USERNAME:
entry_user.set_text(rpc._USERNAME)
@@ -843,7 +843,7 @@ def send_bugtracker(title, msg):
user = entry_user.get_text()
password = entry_password.get_text()
win.destroy()
if response == gtk.RESPONSE_OK:
if response == Gtk.ResponseType.OK:
try:
msg = msg.encode('ascii', 'replace')
title = title.encode('ascii', 'replace')
@@ -899,7 +899,8 @@ def send_bugtracker(title, msg):
tb_s = reduce(lambda x, y: x + y,
traceback.format_exception(sys.exc_info()[0],
sys.exc_info()[1], sys.exc_info()[2]))
message(_('Exception:') + '\n' + tb_s, msg_type=gtk.MESSAGE_ERROR)
message(
_('Exception:') + '\n' + tb_s, msg_type=Gtk.MessageType.ERROR)
def check_version(box, version=__version__):
@@ -940,11 +941,12 @@ def check_version(box, version=__version__):
if check_version(box, version):
info_bar = Gtk.InfoBar()
info_bar.get_content_area().pack_start(
gtk.Label(_("A new version is available!")))
Gtk.Label(label=_("A new version is available!")),
expand=True, fill=True, padding=0)
info_bar.set_show_close_button(True)
info_bar.add_button(_("Download"), Gtk.ResponseType.ACCEPT)
info_bar.connect('response', info_bar_response, box, url)
box.pack_start(info_bar)
box.pack_start(info_bar, expand=True, fill=True, padding=0)
info_bar.show_all()
return False
@@ -983,7 +985,8 @@ def process_exception(exception, *args, **kwargs):
del args[5]['_timestamp']
return rpc_execute(*args)
else:
message(_('Concurrency Exception'), msg_type=gtk.MESSAGE_ERROR)
message(
_('Concurrency Exception'), msg_type=Gtk.MessageType.ERROR)
elif exception.faultCode == str(int(HTTPStatus.UNAUTHORIZED)):
from tryton.gui.main import Main
if PLOCK.acquire(False):
@@ -1119,7 +1122,7 @@ class RPCProgress(object):
self.error = True
if self.callback:
# Post to GTK queue to be run by the main thread
gobject.idle_add(self.process)
GLib.idle_add(self.process)
return True
def run(self, process_exception_p=True, callback=None):
@@ -1130,9 +1133,12 @@ class RPCProgress(object):
# Parent is only useful if it is asynchronous
# otherwise the cursor is not updated.
self.parent = get_toplevel_window()
if self.parent.get_window():
watch = gtk.gdk.Cursor(gtk.gdk.WATCH)
self.parent.get_window().set_cursor(watch)
window = self.parent.get_window()
if window:
display = window.get_display()
watch = Gdk.Cursor.new_for_display(
display, Gdk.CursorType.WATCH)
window.set_cursor(watch)
_thread.start_new_thread(self.start, ())
return
else:
@@ -1196,7 +1202,7 @@ class Tooltips(object):
if hasattr(widget, 'set_tooltip_text'):
return widget.set_tooltip_text(tip_text)
if not self._tooltips:
self._tooltips = gtk.Tooltips()
self._tooltips = Gtk.Tooltips()
return self._tooltips.set_tip(widget, tip_text)
def enable(self):
@@ -1290,12 +1296,12 @@ def resize_pixbuf(pixbuf, width, height):
width = float(img_width) / float(img_height) * float(height)
else:
height = float(img_height) / float(img_width) * float(width)
return pixbuf.scale_simple(int(width), int(height),
gtk.gdk.INTERP_BILINEAR)
return pixbuf.scale_simple(
int(width), int(height), GdkPixbuf.InterpType.BILINEAR)
def _data2pixbuf(data, width=None, height=None):
loader = gtk.gdk.PixbufLoader()
loader = GdkPixbuf.PixbufLoader()
if width and height:
loader.set_size(width, height)
loader.write(data)
@@ -1307,7 +1313,7 @@ def data2pixbuf(data, width=None, height=None):
if data:
try:
return _data2pixbuf(data, width, height)
except glib.GError:
except GLib.GError:
pass
@@ -1327,6 +1333,17 @@ def ellipsize(string, length):
return string[:length - len(ellipsis)] + ellipsis
def get_align(float_):
"Convert float align into Gtk.Align"
value = float(float_)
if value < 0.5:
return Gtk.Align.START
elif value == 0.5:
return Gtk.Align.FILL
else:
return Gtk.Align.END
def date_format(format_):
return format_ or rpc.CONTEXT.get('locale', {}).get('date', '%x')
+4 -5
View File
@@ -3,8 +3,7 @@
import logging
import gettext
import gtk
import gobject
from gi.repository import GLib, Gtk
from tryton.config import CONFIG
from tryton.common import RPCExecute
@@ -16,9 +15,9 @@ logger = logging.getLogger(__name__)
def get_completion(search=True, create=True):
"Return a EntryCompletion"
completion = gtk.EntryCompletion()
completion = Gtk.EntryCompletion()
completion.set_match_func(lambda *a: True)
completion.set_model(gtk.ListStore(str, int))
completion.set_model(Gtk.ListStore(str, int))
completion.set_text_column(0)
completion.props.popup_set_width = False
if search:
@@ -71,4 +70,4 @@ def update_completion(entry, record, field, model, domain=None):
exc_info=True)
return False
search_text = entry.get_text()
gobject.timeout_add(300, update, search_text, domain)
GLib.timeout_add(300, update, search_text, domain)
+98 -98
View File
@@ -3,8 +3,7 @@
import gettext
import datetime
import gobject
import gtk
from gi.repository import Gdk, GObject, Gtk
from dateutil.relativedelta import relativedelta
from dateutil.parser import parse
@@ -24,30 +23,30 @@ def date_parse(text, format_='%x'):
return parse(text, dayfirst=dayfirst, yearfirst=yearfirst, ignoretz=True)
class Date(gtk.Entry):
class Date(Gtk.Entry):
__gtype_name__ = 'Date'
__gproperties__ = {
'value': (gobject.TYPE_PYOBJECT,
'value': (GObject.TYPE_PYOBJECT,
_('Value'),
_('Displayed value'),
gobject.ParamFlags.READABLE | gobject.ParamFlags.WRITABLE),
'format': (gobject.TYPE_STRING,
GObject.ParamFlags.READABLE | GObject.ParamFlags.WRITABLE),
'format': (GObject.TYPE_STRING,
'%x',
_('Format'),
_('Display format'),
gobject.ParamFlags.READABLE | gobject.ParamFlags.WRITABLE),
GObject.ParamFlags.READABLE | GObject.ParamFlags.WRITABLE),
}
__gsignals__ = {
'date-changed': (
gobject.SignalFlags.RUN_LAST | gobject.SignalFlags.ACTION,
gobject.TYPE_NONE, ()),
GObject.SignalFlags.RUN_LAST | GObject.SignalFlags.ACTION,
GObject.TYPE_NONE, ()),
}
def __init__(self):
self.__date = None
self.__format = '%x'
gtk.Entry.__init__(self)
Gtk.Entry.__init__(self)
self.set_width_chars(20)
@@ -56,23 +55,26 @@ class Date(gtk.Entry):
# Calendar Popup
self.set_icon_from_pixbuf(
gtk.ENTRY_ICON_PRIMARY,
IconFactory.get_pixbuf('tryton-date', gtk.ICON_SIZE_MENU))
self.set_icon_tooltip_text(gtk.ENTRY_ICON_PRIMARY,
Gtk.EntryIconPosition.PRIMARY,
IconFactory.get_pixbuf('tryton-date', Gtk.IconSize.MENU))
self.set_icon_tooltip_text(
Gtk.EntryIconPosition.PRIMARY,
_('Open the calendar'))
self.connect('icon-press', self.icon_press)
self.__cal_popup = gtk.Window(gtk.WINDOW_POPUP)
self.__cal_popup = Gtk.Window(type=Gtk.WindowType.POPUP)
self.__cal_popup.set_events(
self.__cal_popup.get_events() | gtk.gdk.KEY_PRESS_MASK)
self.__cal_popup.get_events() | Gdk.EventMask.KEY_PRESS_MASK)
self.__cal_popup.set_resizable(False)
self.__cal_popup.connect('delete-event', self.cal_popup_closed)
self.__cal_popup.connect('key-press-event', self.cal_popup_key_pressed)
self.__cal_popup.connect('button-press-event',
self.cal_popup_button_pressed)
self.__calendar = gtk.Calendar()
cal_options = gtk.CALENDAR_SHOW_DAY_NAMES | gtk.CALENDAR_SHOW_HEADING
self.__calendar = Gtk.Calendar()
cal_options = (
Gtk.CalendarDisplayOptions.SHOW_DAY_NAMES |
Gtk.CalendarDisplayOptions.SHOW_HEADING)
self.__calendar.set_display_options(cal_options)
self.__cal_popup.add(self.__calendar)
self.__calendar.connect('day-selected', self.cal_popup_changed)
@@ -99,7 +101,7 @@ class Date(gtk.Entry):
def icon_press(self, entry, icon_pos, event):
self.grab_focus()
if icon_pos == gtk.ENTRY_ICON_PRIMARY:
if icon_pos == Gtk.EntryIconPosition.PRIMARY:
self.cal_popup_open()
def cal_popup_open(self):
@@ -124,18 +126,19 @@ class Date(gtk.Entry):
self.cal_popup_hide()
def cal_popup_key_pressed(self, calendar, event):
if event.keyval != gtk.keysyms.Escape:
if event.keyval != Gdk.KEY_Escape:
return False
self.stop_emission('key-press-event')
self.stop_emission_by_name('key-press-event')
self.cal_popup_hide()
return True
def cal_popup_button_pressed(self, calendar, event):
child = event.window
if child != calendar.window:
window = calendar.get_window()
if child != window:
while child:
if child == calendar.window:
if child == window:
return False
child = child.get_parent()
self.cal_popup_hide()
@@ -188,16 +191,16 @@ class Date(gtk.Entry):
return self.__format
gobject.type_register(Date)
GObject.type_register(Date)
class CellRendererDate(gtk.CellRendererText):
class CellRendererDate(Gtk.CellRendererText):
__gproperties__ = {
'format': (gobject.TYPE_STRING,
'format': (GObject.TYPE_STRING,
_('Format'),
_('Display format'),
'%x',
gobject.ParamFlags.READABLE | gobject.ParamFlags.WRITABLE),
GObject.ParamFlags.READABLE | GObject.ParamFlags.WRITABLE),
}
def __init__(self):
@@ -205,18 +208,18 @@ class CellRendererDate(gtk.CellRendererText):
self.__entry = None
self.__focus_out_id = 0
gtk.CellRendererText.__init__(self)
Gtk.CellRendererText.__init__(self)
def do_set_property(self, prop, value):
if prop.name == 'format':
self.__format = value
return
gtk.CellRendererText.set_property(self, prop, value)
Gtk.CellRendererText.set_property(self, prop, value)
def do_get_property(self, prop):
if prop.name == 'format':
return self.__format
return gtk.CellRendererText.get_property(self, prop)
return Gtk.CellRendererText.get_property(self, prop)
def do_start_editing(
self, event, widget, path, background_area, cell_area, flags):
@@ -250,33 +253,33 @@ class CellRendererDate(gtk.CellRendererText):
return False
gobject.type_register(CellRendererDate)
GObject.type_register(CellRendererDate)
class Time(gtk.ComboBoxEntry):
class Time(Gtk.ComboBox):
__gtype_name__ = 'Time'
__gproperties__ = {
'value': (gobject.TYPE_PYOBJECT,
'value': (GObject.TYPE_PYOBJECT,
_('Value'),
_('Displayed value'),
gobject.ParamFlags.READABLE | gobject.ParamFlags.WRITABLE),
'format': (gobject.TYPE_STRING,
GObject.ParamFlags.READABLE | GObject.ParamFlags.WRITABLE),
'format': (GObject.TYPE_STRING,
_('Format'),
_('Display format'),
'%X',
gobject.ParamFlags.READABLE | gobject.ParamFlags.WRITABLE),
GObject.ParamFlags.READABLE | GObject.ParamFlags.WRITABLE),
}
__gsignals__ = {
'time-changed': (
gobject.SignalFlags.RUN_LAST | gobject.SignalFlags.ACTION,
gobject.TYPE_NONE, ()),
GObject.SignalFlags.RUN_LAST | GObject.SignalFlags.ACTION,
GObject.TYPE_NONE, ()),
}
def __init__(self):
self.__time = None
self.__format = '%X'
gtk.ComboBoxEntry.__init__(self)
Gtk.ComboBox.__init__(self, has_entry=True)
self.__entry = self.get_child()
self.__entry.set_width_chars(10)
@@ -285,11 +288,11 @@ class Time(gtk.ComboBoxEntry):
self.__entry.connect('activate', self.activate)
self.connect('changed', self.changed)
self.__model = gtk.ListStore(
gobject.TYPE_STRING, gobject.TYPE_PYOBJECT)
self.__model = Gtk.ListStore(
GObject.TYPE_STRING, GObject.TYPE_PYOBJECT)
self.update_model()
self.set_model(self.__model)
self.set_text_column(0)
self.set_entry_text_column(0)
def parse(self):
text = self.__entry.get_text()
@@ -360,16 +363,16 @@ class Time(gtk.ComboBoxEntry):
return self.__format
gobject.type_register(Time)
GObject.type_register(Time)
class CellRendererTime(gtk.CellRendererCombo):
class CellRendererTime(Gtk.CellRendererCombo):
__gproperties__ = {
'format': (gobject.TYPE_STRING,
'format': (GObject.TYPE_STRING,
'%X',
_('Format'),
_('Display format'),
gobject.ParamFlags.READABLE | gobject.ParamFlags.WRITABLE),
GObject.ParamFlags.READABLE | GObject.ParamFlags.WRITABLE),
}
def __init__(self):
@@ -377,18 +380,18 @@ class CellRendererTime(gtk.CellRendererCombo):
self.__combo = None
self.__focus_out_id = 0
gtk.CellRendererText.__init__(self)
Gtk.CellRendererText.__init__(self)
def do_set_property(self, prop, value):
if prop.name == 'format':
self.__format = value
return
gtk.CellRendererText.set_property(self, prop, value)
Gtk.CellRendererText.set_property(self, prop, value)
def do_get_property(self, prop):
if prop.name == 'format':
return self.__format
return gtk.CellRendererText.get_property(self, prop)
return Gtk.CellRendererText.get_property(self, prop)
def do_start_editing(
self, event, widget, path, background_area, cell_area, flags):
@@ -418,44 +421,44 @@ class CellRendererTime(gtk.CellRendererCombo):
return False
gobject.type_register(CellRendererTime)
GObject.type_register(CellRendererTime)
class DateTime(gtk.HBox):
class DateTime(Gtk.HBox):
__gtype_name__ = 'DateTime'
__gproperties__ = {
'value': (gobject.TYPE_PYOBJECT,
'value': (GObject.TYPE_PYOBJECT,
_('Value'),
_('Displayed value'),
gobject.ParamFlags.READABLE | gobject.ParamFlags.WRITABLE),
'date-format': (gobject.TYPE_STRING,
GObject.ParamFlags.READABLE | GObject.ParamFlags.WRITABLE),
'date-format': (GObject.TYPE_STRING,
'%x',
_('Date Format'),
_('Displayed date format'),
gobject.ParamFlags.READABLE | gobject.ParamFlags.WRITABLE),
'time-format': (gobject.TYPE_STRING,
GObject.ParamFlags.READABLE | GObject.ParamFlags.WRITABLE),
'time-format': (GObject.TYPE_STRING,
'%X',
_('Date Format'),
_('Displayed date format'),
gobject.ParamFlags.READABLE | gobject.ParamFlags.WRITABLE),
GObject.ParamFlags.READABLE | GObject.ParamFlags.WRITABLE),
}
__gsignals__ = {
'datetime-changed': (
gobject.SignalFlags.RUN_LAST | gobject.SignalFlags.ACTION,
gobject.TYPE_NONE, ()),
GObject.SignalFlags.RUN_LAST | GObject.SignalFlags.ACTION,
GObject.TYPE_NONE, ()),
}
def __init__(self):
gtk.HBox.__init__(self, spacing=4)
Gtk.HBox.__init__(self, spacing=4)
self.__date = Date()
self.pack_start(self.__date, True, True, 0)
self.pack_start(self.__date, expand=True, fill=True, padding=0)
self.__date.show()
self.__date.connect('date-changed',
lambda e: self.emit('datetime-changed'))
self.__time = Time()
self.pack_start(self.__time, True, True, 0)
self.pack_start(self.__time, expand=True, fill=True, padding=0)
self.__time.show()
self.__time.connect('time-changed',
lambda e: self.emit('datetime-changed'))
@@ -499,16 +502,12 @@ class DateTime(gtk.HBox):
self.__time.child.modify_text(state, color)
gobject.type_register(DateTime)
GObject.type_register(DateTime)
def popup_position(widget, popup):
allocation = widget.get_allocation()
if hasattr(widget.window, 'get_root_coords'):
x, y = widget.window.get_root_coords(allocation.x, allocation.y)
else:
x, y = widget.window.get_origin()
width, height = popup.size_request()
x, y = widget.get_window().get_root_coords(allocation.x, allocation.y)
popup.move(x, y + allocation.height)
@@ -517,18 +516,19 @@ def popup_show(popup):
popup.grab_focus()
popup.grab_add()
cursor = gtk.gdk.Cursor(gtk.gdk.ARROW)
gtk.gdk.pointer_grab(popup.window, True,
(gtk.gdk.BUTTON_PRESS_MASK
| gtk.gdk.BUTTON_RELEASE_MASK
| gtk.gdk.POINTER_MOTION_MASK),
None, cursor, 0)
window = popup.get_window()
display = window.get_display()
seat = display.get_default_seat()
seat.grab(window, Gdk.SeatCapabilities.ALL, True, None, None, None, None)
def popup_hide(popup):
popup.hide()
popup.grab_remove()
gtk.gdk.pointer_ungrab(0)
window = popup.get_window()
display = window.get_display()
seat = display.get_default_seat()
seat.ungrab()
def timelist_set_list(model, min_, max_, format_):
@@ -560,7 +560,7 @@ def add_operators(widget):
except TypeError:
return False
return True
elif event.keyval in (gtk.keysyms.KP_Equal, gtk.keysyms.equal):
elif event.keyval in (Gdk.KEY_KP_Equal, Gdk.KEY_equal):
widget.props.value = datetime.datetime.now()
return True
return False
@@ -569,7 +569,7 @@ def add_operators(widget):
for child in widget.get_children():
add_operators(child)
return widget
if isinstance(widget, gtk.ComboBoxEntry):
if isinstance(widget, Gtk.ComboBox):
editable = widget.get_child()
else:
editable = widget
@@ -578,47 +578,47 @@ def add_operators(widget):
OPERATORS = {
gtk.keysyms.S: relativedelta(seconds=-1),
gtk.keysyms.s: relativedelta(seconds=1),
gtk.keysyms.I: relativedelta(minutes=-1),
gtk.keysyms.i: relativedelta(minutes=1),
gtk.keysyms.H: relativedelta(hours=-1),
gtk.keysyms.h: relativedelta(hours=1),
gtk.keysyms.D: relativedelta(days=-1),
gtk.keysyms.d: relativedelta(days=1),
gtk.keysyms.W: relativedelta(weeks=-1),
gtk.keysyms.w: relativedelta(weeks=1),
gtk.keysyms.M: relativedelta(months=-1),
gtk.keysyms.m: relativedelta(months=1),
gtk.keysyms.Y: relativedelta(years=-1),
gtk.keysyms.y: relativedelta(years=1),
Gdk.KEY_S: relativedelta(seconds=-1),
Gdk.KEY_s: relativedelta(seconds=1),
Gdk.KEY_I: relativedelta(minutes=-1),
Gdk.KEY_i: relativedelta(minutes=1),
Gdk.KEY_H: relativedelta(hours=-1),
Gdk.KEY_h: relativedelta(hours=1),
Gdk.KEY_D: relativedelta(days=-1),
Gdk.KEY_d: relativedelta(days=1),
Gdk.KEY_W: relativedelta(weeks=-1),
Gdk.KEY_w: relativedelta(weeks=1),
Gdk.KEY_M: relativedelta(months=-1),
Gdk.KEY_m: relativedelta(months=1),
Gdk.KEY_Y: relativedelta(years=-1),
Gdk.KEY_y: relativedelta(years=1),
}
if __name__ == '__main__':
win = gtk.Window()
win.connect('delete-event', gtk.main_quit)
win = Gtk.Window()
win.connect('delete-event', Gtk.main_quit)
v = gtk.VBox()
v = Gtk.VBox()
v.show()
d = add_operators(Date())
d.show()
v.pack_start(d, False, False)
v.pack_start(d, expand=False, fill=False, padding=0)
t = add_operators(Time())
t.show()
v.pack_start(t, False, False)
v.pack_start(t, expand=False, fill=False, padding=0)
t = add_operators(Time())
t.props.format = '%H:%M'
t.show()
v.pack_start(t, False, False)
v.pack_start(t, expand=False, fill=False, padding=0)
dt = add_operators(DateTime())
dt.show()
v.pack_start(dt, False, False)
v.pack_start(dt, expand=False, fill=False, padding=0)
win.add(v)
win.show()
gtk.main()
Gtk.main()
+3 -3
View File
@@ -2,7 +2,7 @@
# this repository contains the full copyright notices and license terms.
from functools import cmp_to_key
import gtk
from gi.repository import Gtk
def get_invisible_ancestor(widget):
@@ -25,7 +25,7 @@ def find_focused_child(widget):
def tab_compare(a, b):
text_direction = gtk.widget_get_default_direction()
text_direction = Gtk.Widget.get_default_direction()
a_allocation = a.get_allocation()
b_allocation = b.get_allocation()
y1 = a_allocation.y + a_allocation.height // 2
@@ -35,7 +35,7 @@ def tab_compare(a, b):
x1 = a_allocation.x + a_allocation.width // 2
x2 = b_allocation.x + b_allocation.width // 2
if text_direction == gtk.TEXT_DIR_RTL:
if text_direction == Gtk.TextDirection.RTL:
return (x2 > x1) - (x2 < x1)
else:
return (x1 > x2) - (x1 < x2)
+3
View File
@@ -18,6 +18,7 @@ use_serialize_func = False
def _reverse_dict(dct):
return {j: i for i, j in dct.items()}
SIZE2SCALE = {
'1': 1 / (1.2 * 1.2 * 1.2),
'2': 1 / (1.2 * 1.2),
@@ -296,6 +297,8 @@ def deserialize(register, content, iter_, text, create_tags, data):
def setup_tags(text_buffer):
for name, props in reversed(_TAGS):
text_buffer.create_tag(name, **props)
_TAGS = [
('bold', {'weight': Pango.Weight.BOLD}),
('italic', {'style': Pango.Style.ITALIC}),
+19 -26
View File
@@ -1,8 +1,10 @@
# 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
from tryton.common import RPCExecute, RPCException, IconFactory
from gi.repository import Gtk, Gdk
from tryton.common import RPCExecute, RPCException
from tryton.gui.window.view_form.screen import Screen
from tryton.action import Action
from tryton.gui.window import Window
@@ -45,10 +47,10 @@ def populate(menu, model, record, title='', field=None, context=None):
'id': rec.id,
'ids': [rec.id],
}
event = gtk.get_current_event()
event = Gtk.get_current_event()
allow_similar = False
if (event.state & gtk.gdk.CONTROL_MASK
or event.state & gtk.gdk.MOD1_MASK):
if (event.state & Gdk.ModifierType.CONTROL_MASK
or event.state & Gdk.ModifierType.MOD1_MASK):
allow_similar = True
with Window(hide_current=True, allow_similar=allow_similar):
Action._exec_action(action, data, rec.get_context())
@@ -69,32 +71,26 @@ def populate(menu, model, record, title='', field=None, context=None):
if title:
if len(menu):
menu.append(gtk.SeparatorMenuItem())
title_item = gtk.MenuItem(title)
menu.append(Gtk.SeparatorMenuItem())
title_item = Gtk.MenuItem(label=title)
menu.append(title_item)
submenu = gtk.Menu()
submenu = Gtk.Menu()
title_item.set_submenu(submenu)
action_menu = submenu
else:
action_menu = menu
if len(action_menu):
action_menu.append(gtk.SeparatorMenuItem())
action_menu.append(Gtk.SeparatorMenuItem())
if field:
edit_item = gtk.MenuItem(_('Edit...'))
edit_item = Gtk.MenuItem(label=_('Edit...'))
edit_item.connect('activate', edit)
action_menu.append(edit_item)
action_menu.append(gtk.SeparatorMenuItem())
attachment_item = gtk.ImageMenuItem()
attachment_item.set_label(_('Attachments...'))
attachment_item.set_image(IconFactory.get_image(
'tryton-attach', gtk.ICON_SIZE_MENU))
action_menu.append(Gtk.SeparatorMenuItem())
attachment_item = Gtk.MenuItem(label=_('Attachments...'))
action_menu.append(attachment_item)
attachment_item.connect('activate', attachment)
note_item = gtk.ImageMenuItem()
note_item.set_label(_('Notes...'))
note_item.set_image(IconFactory.get_image(
'tryton-note', gtk.ICON_SIZE_MENU))
note_item = Gtk.MenuItem(label=_('Notes...'))
action_menu.append(note_item)
note_item.connect('activate', note)
@@ -111,20 +107,17 @@ def populate(menu, model, record, title='', field=None, context=None):
('print', 'tryton-print', _('Print...'), 'print'),
):
if len(action_menu):
action_menu.append(gtk.SeparatorMenuItem())
title_item = gtk.ImageMenuItem()
title_item.set_label(label)
title_item.set_image(IconFactory.get_image(
icon, gtk.ICON_SIZE_MENU))
action_menu.append(Gtk.SeparatorMenuItem())
title_item = Gtk.MenuItem(label=label)
action_menu.append(title_item)
if not toolbar[atype]:
title_item.set_sensitive(False)
continue
submenu = gtk.Menu()
submenu = Gtk.Menu()
title_item.set_submenu(submenu)
for action in toolbar[atype]:
action = action.copy()
item = gtk.MenuItem(action['name'])
item = Gtk.MenuItem(label=action['name'])
submenu.append(item)
if flavor == 'print':
action['direct_print'] = True
+8 -13
View File
@@ -3,8 +3,7 @@
import operator
import math
import gtk
import gobject
from gi.repository import Gdk, GLib, GObject, Gtk
from tryton.common import RPCExecute, RPCException
from tryton.common import eval_domain
@@ -123,9 +122,9 @@ class SelectionMixin(object):
def selection_shortcuts(entry):
def key_press(widget, event):
if (event.type == gtk.gdk.KEY_PRESS
and event.state & gtk.gdk.CONTROL_MASK
and event.keyval == gtk.keysyms.space):
if (event.type == Gdk.EventType.KEY_PRESS
and event.state & Gdk.ModifierType.CONTROL_MASK
and event.keyval == Gdk.KEY_space):
widget.popup()
entry.connect('key_press_event', key_press)
return entry
@@ -149,12 +148,8 @@ class PopdownMixin(object):
return
model, lengths = self.get_popdown_model(selection)
entry.set_model(model)
# GTK 2.24 and above use a ComboBox instead of a ComboBoxEntry
if hasattr(entry, 'set_text_column'):
entry.set_text_column(0)
else:
entry.set_entry_text_column(0)
completion = gtk.EntryCompletion()
entry.set_entry_text_column(0)
completion = Gtk.EntryCompletion()
completion.set_inline_selection(True)
completion.set_model(model)
child.set_completion(completion)
@@ -173,7 +168,7 @@ class PopdownMixin(object):
completion.connect('match-selected', self.match_selected, entry)
def get_popdown_model(self, selection):
model = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_PYOBJECT)
model = Gtk.ListStore(GObject.TYPE_STRING, GObject.TYPE_PYOBJECT)
lengths = []
for (value, name) in selection:
name = str(name)
@@ -186,7 +181,7 @@ class PopdownMixin(object):
model = entry.get_model()
for i, values in enumerate(model):
if values[1] == value:
gobject.idle_add(entry.set_active, i)
GLib.idle_add(entry.set_active, i)
break
def get_popdown_value(self, entry, index=1):
+1
View File
@@ -108,6 +108,7 @@ def parse(text, converter=None):
seconds *= -1
return datetime.timedelta(seconds=seconds)
_tests = [
(None, ''),
(datetime.timedelta(), '00:00'),
+21 -13
View File
@@ -1,28 +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 gobject
from gi.repository import Gdk, GObject, Gtk
MOVEMENT_KEYS = {gtk.keysyms.Up, gtk.keysyms.Down, gtk.keysyms.space,
gtk.keysyms.Left, gtk.keysyms.KP_Left,
gtk.keysyms.Right, gtk.keysyms.KP_Right,
gtk.keysyms.Home, gtk.keysyms.KP_Home,
gtk.keysyms.End, gtk.keysyms.KP_End}
MOVEMENT_KEYS = {
Gdk.KEY_Up,
Gdk.KEY_Down,
Gdk.KEY_space,
Gdk.KEY_Left,
Gdk.KEY_KP_Left,
Gdk.KEY_Right,
Gdk.KEY_KP_Right,
Gdk.KEY_Home,
Gdk.KEY_KP_Home,
Gdk.KEY_End,
Gdk.KEY_KP_End,
}
__all__ = ['TreeViewControl']
class TreeViewControl(gtk.TreeView):
class TreeViewControl(Gtk.TreeView):
def do_button_press_event(self, event):
self.grab_focus() # grab focus because it doesn't whith CONTROL MASK
if event.button == 1:
event.state ^= gtk.gdk.CONTROL_MASK
return gtk.TreeView.do_button_press_event(self, event)
event.state ^= Gdk.ModifierType.CONTROL_MASK
return Gtk.TreeView.do_button_press_event(self, event)
def do_key_press_event(self, event):
if event.keyval in MOVEMENT_KEYS:
event.state ^= gtk.gdk.CONTROL_MASK
return gtk.TreeView.do_key_press_event(self, event)
event.state ^= Gdk.ModifierType.CONTROL_MASK
return Gtk.TreeView.do_key_press_event(self, event)
gobject.type_register(TreeViewControl)
GObject.type_register(TreeViewControl)
+3 -2
View File
@@ -7,7 +7,8 @@ import gettext
import logging
import sys
import locale
import gtk
from gi.repository import GdkPixbuf
from tryton import __version__
@@ -169,5 +170,5 @@ if not os.path.isdir(PIXMAPS_DIR):
PIXMAPS_DIR = pkg_resources.resource_filename(
'tryton', 'data/pixmaps/tryton')
TRYTON_ICON = gtk.gdk.pixbuf_new_from_file(
TRYTON_ICON = GdkPixbuf.Pixbuf.new_from_file(
os.path.join(PIXMAPS_DIR, 'tryton-icon.png'))
+97 -99
View File
@@ -11,9 +11,7 @@ import traceback
import webbrowser
from urllib.parse import urlparse, parse_qsl, unquote
import gobject
import gtk
from gi.repository import Gtk, GLib, Gio
from gi.repository import Gdk, GdkPixbuf, Gio, GLib, Gtk
import tryton.common as common
import tryton.plugins
@@ -55,12 +53,12 @@ class Main(Gtk.Application):
action.connect(
'activate', lambda *a: self.global_search_entry.grab_focus())
self.add_action(action)
self.add_accelerator('<Primary>k', 'app.menu-search')
self.set_accels_for_action('app.menu-search', ['<Primary>k'])
action = Gio.SimpleAction.new('menu-toggle', None)
action.connect('activate', lambda *a: self.menu_toggle())
self.add_action(action)
self.add_accelerator('<Primary>m', 'app.menu-toggle')
self.set_accels_for_action('app.menu-toggle', ['<Primary>m'])
toolbar_variant = GLib.Variant.new_string(
CONFIG['client.toolbar'] or 'both')
@@ -91,12 +89,12 @@ class Main(Gtk.Application):
action = Gio.SimpleAction.new('tab-previous', None)
action.connect('activate', lambda *a: self.win_prev())
self.add_action(action)
self.add_accelerator('<Primary><Shift>Tab', 'app.tab-previous')
self.set_accels_for_action('app.tab-previous', ['<Primary><Shift>Tab'])
action = Gio.SimpleAction.new('tab-next', None)
action.connect('activate', lambda *a: self.win_next())
self.add_action(action)
self.add_accelerator('<Primary>Tab', 'app.tab-next')
self.set_accels_for_action('app.tab-next', ['<Primary>Tab'])
action = Gio.SimpleAction.new('search-limit', None)
action.connect('activate', lambda *a: self.edit_limit())
@@ -110,7 +108,7 @@ class Main(Gtk.Application):
action = Gio.SimpleAction.new('shortcuts', None)
action.connect('activate', lambda *a: self.shortcuts())
self.add_action(action)
self.add_accelerator('<Primary>F1', 'app.shortcuts')
self.set_accels_for_action('app.shortcuts', ['<Primary>F1'])
action = Gio.SimpleAction.new('about', None)
action.connect('activate', lambda *a: self.about())
@@ -119,7 +117,7 @@ class Main(Gtk.Application):
action = Gio.SimpleAction.new('quit', None)
action.connect('activate', self.on_quit)
self.add_action(action)
self.add_accelerator('<Primary>q', 'app.quit')
self.set_accels_for_action('app.quit', ['<Primary>q'])
menu = Gio.Menu.new()
menu.append(_("Preferences..."), 'app.preferences')
@@ -165,7 +163,7 @@ class Main(Gtk.Application):
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_position(Gtk.WindowPosition.CENTER)
self.window.set_resizable(True)
self.window.set_icon(TRYTON_ICON)
self.window.connect("destroy", self.on_quit)
@@ -198,64 +196,69 @@ class Main(Gtk.Application):
self.accel_group = Gtk.AccelGroup()
self.window.add_accel_group(self.accel_group)
gtk.accel_map_add_entry('<tryton>/Form/New', gtk.keysyms.N,
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.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.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/Search', Gdk.KEY_F, Gdk.ModifierType.CONTROL_MASK)
gtk.accel_map_load(os.path.join(get_config_dir(), 'accel.map'))
Gtk.AccelMap.load(os.path.join(get_config_dir(), 'accel.map'))
self.tooltips = common.Tooltips()
self.vbox = gtk.VBox()
self.vbox = Gtk.VBox()
self.window.add(self.vbox)
self.buttons = {}
self.info = gtk.VBox()
self.vbox.pack_start(self.info, expand=False)
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, True, True)
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 = Gtk.VBox()
self.menu.set_vexpand(True)
self.pane.add1(self.menu)
self.notebook = gtk.Notebook()
self.notebook = Gtk.Notebook()
self.notebook.popup_enable()
self.notebook.set_scrollable(True)
self.notebook.connect_after('switch-page', self._sig_page_changt)
@@ -308,15 +311,15 @@ class Main(Gtk.Application):
def set_global_search(self):
self.global_search_entry = Gtk.Entry.new()
self.global_search_entry.set_width_chars(20)
global_search_completion = gtk.EntryCompletion()
global_search_completion = Gtk.EntryCompletion()
global_search_completion.set_match_func(lambda *a: True)
global_search_completion.set_model(gtk.ListStore(
gtk.gdk.Pixbuf, str, str, int, str))
pixbuf_cell = gtk.CellRendererPixbuf()
global_search_completion.pack_start(pixbuf_cell, False)
global_search_completion.set_model(
Gtk.ListStore(GdkPixbuf.Pixbuf, str, str, int, str))
pixbuf_cell = Gtk.CellRendererPixbuf()
global_search_completion.pack_start(pixbuf_cell, expand=True)
global_search_completion.add_attribute(pixbuf_cell, 'pixbuf', 0)
text_cell = gtk.CellRendererText()
global_search_completion.pack_start(text_cell)
text_cell = Gtk.CellRendererText()
global_search_completion.pack_start(text_cell, expand=True)
global_search_completion.add_attribute(text_cell, "markup", 1)
global_search_completion.props.popup_set_width = True
self.global_search_entry.set_completion(global_search_completion)
@@ -369,7 +372,7 @@ class Main(Gtk.Application):
if icon:
text = common.to_xml(record_name)
pixbuf = common.IconFactory.get_pixbuf(
icon, gtk.ICON_SIZE_BUTTON)
icon, Gtk.IconSize.BUTTON)
else:
text = '<b>%s:</b>\n %s' % (
common.to_xml(model_name),
@@ -388,7 +391,7 @@ class Main(Gtk.Application):
def changed(widget):
search_text = widget.get_text()
gobject.timeout_add(300, update, widget, search_text)
GLib.timeout_add(300, update, widget, search_text)
def activate(widget):
def message():
@@ -433,9 +436,9 @@ class Main(Gtk.Application):
return True
def _action_favorite(widget, id_):
event = gtk.get_current_event()
allow_similar = (event.state & gtk.gdk.MOD1_MASK or
event.state & gtk.gdk.SHIFT_MASK)
event = Gtk.get_current_event()
allow_similar = (event.state & Gdk.ModifierType.MOD1_MASK
or event.state & Gdk.ModifierType.SHIFT_MASK)
with Window(allow_similar=allow_similar):
# ids is not defined to prevent to add suffix
Action.exec_keyword('tree_open', {
@@ -454,16 +457,11 @@ class Main(Gtk.Application):
except Exception:
return False
for id_, name, icon in favorites:
if icon:
menuitem = gtk.ImageMenuItem(name)
menuitem.set_image(
common.IconFactory.get_image(icon, gtk.ICON_SIZE_MENU))
else:
menuitem = gtk.MenuItem(name)
menuitem = Gtk.MenuItem(label=name)
menuitem.connect('activate', _action_favorite, id_)
self.menu_favorite.add(menuitem)
self.menu_favorite.add(gtk.SeparatorMenuItem())
manage_favorites = gtk.MenuItem(_("Manage..."),
self.menu_favorite.add(Gtk.SeparatorMenuItem())
manage_favorites = Gtk.MenuItem(label=_("Manage..."),
use_underline=True)
manage_favorites.connect('activate', _manage_favorites)
self.menu_favorite.add(manage_favorites)
@@ -481,11 +479,11 @@ class Main(Gtk.Application):
if option == 'default':
barstyle = False
elif option == 'both':
barstyle = gtk.TOOLBAR_BOTH
barstyle = Gtk.ToolbarStyle.BOTH
elif option == 'text':
barstyle = gtk.TOOLBAR_TEXT
barstyle = Gtk.ToolbarStyle.TEXT
elif option == 'icons':
barstyle = gtk.TOOLBAR_ICONS
barstyle = Gtk.ToolbarStyle.ICONS
for page_idx in range(self.notebook.get_n_pages()):
page = self.get_page(page_idx)
page.toolbar.set_style(barstyle)
@@ -495,7 +493,7 @@ class Main(Gtk.Application):
Limit().run()
def edit_email(self):
from tryton.gui.window.email import Email
from tryton.gui.window.email_ import Email
Email().run()
def win_next(self):
@@ -745,18 +743,19 @@ class Main(Gtk.Application):
screen.switch_view(view_type=screen.current_view.view_type)
self.menu.pack_start(
screen.screen_container.alternate_viewport, True, True)
screen.screen_container.alternate_viewport,
expand=True, fill=True, padding=0)
treeview = screen.current_view.treeview
treeview.set_headers_visible(False)
# Favorite column
column = gtk.TreeViewColumn()
column = Gtk.TreeViewColumn()
column.name = None
column._type = None
favorite_renderer = CellRendererClickablePixbuf()
column.pack_start(favorite_renderer, expand=False)
def favorite_setter(column, cell, store, iter_):
def favorite_setter(column, cell, store, iter_, user_data=None):
menu = store.get_value(iter_, 0)
favorite = menu.value.get('favorite')
if favorite:
@@ -767,7 +766,7 @@ class Main(Gtk.Application):
icon = None
if icon:
pixbuf = common.IconFactory.get_pixbuf(
icon, gtk.ICON_SIZE_MENU)
icon, Gtk.IconSize.MENU)
else:
pixbuf = None
cell.set_property('pixbuf', pixbuf)
@@ -777,11 +776,11 @@ class Main(Gtk.Application):
if treeview.props.window:
self.toggle_favorite(renderer, path, treeview)
favorite_renderer.connect('clicked',
lambda *a: gobject.idle_add(toggle_favorite, *a), treeview)
lambda *a: GLib.idle_add(toggle_favorite, *a), treeview)
# Unset fixed height mode to add column
treeview.set_fixed_height_mode(False)
treeview.set_property(
'enable-grid-lines', gtk.TREE_VIEW_GRID_LINES_NONE)
'enable-grid-lines', Gtk.TreeViewGridLines.NONE)
treeview.append_column(column)
screen.search_filter()
@@ -828,34 +827,34 @@ class Main(Gtk.Application):
page_id = -1
self.previous_pages[page] = previous_widget
self.pages.append(page)
hbox = gtk.HBox(spacing=3)
hbox = Gtk.HBox(spacing=3)
if page.icon:
hbox.pack_start(
common.IconFactory.get_image(
page.icon, gtk.ICON_SIZE_SMALL_TOOLBAR),
expand=False, fill=False)
page.icon, Gtk.IconSize.SMALL_TOOLBAR),
expand=False, fill=False, padding=0)
name = page.name
label = gtk.Label(common.ellipsize(name, 20))
label = Gtk.Label(
label=common.ellipsize(name, 20),
halign=Gtk.Align.START)
self.tooltips.set_tip(label, page.name)
self.tooltips.enable()
label.set_alignment(0.0, 0.5)
hbox.pack_start(label, expand=True, fill=True)
hbox.pack_start(label, expand=True, fill=True, padding=0)
button = gtk.Button()
button.set_relief(gtk.RELIEF_NONE)
button = Gtk.Button()
button.set_relief(Gtk.ReliefStyle.NONE)
button.set_can_focus(False)
button.add(common.IconFactory.get_image(
'tryton-close', gtk.ICON_SIZE_MENU))
'tryton-close', Gtk.IconSize.MENU))
self.tooltips.set_tip(button, _('Close Tab'))
button.connect('clicked', self._sig_remove_book, page.widget)
hbox.pack_start(button, expand=False, fill=False)
x, y = gtk.icon_size_lookup_for_settings(button.get_settings(),
gtk.ICON_SIZE_MENU)[-2:]
button.set_size_request(x, y)
hbox.pack_start(button, expand=False, fill=False, padding=0)
size = Gtk.IconSize.lookup(Gtk.IconSize.MENU)
button.set_size_request(size.width, size.height)
hbox.show_all()
label_menu = gtk.Label(page.name)
label_menu.set_alignment(0.0, 0.5)
label_menu = Gtk.Label(
label=page.name, halign=Gtk.Align.START)
self.notebook.insert_page_menu(page.widget, hbox, label_menu, page_id)
self.notebook.set_tab_reorderable(page.widget, True)
self.notebook.set_current_page(page_id)
@@ -937,9 +936,9 @@ class Main(Gtk.Application):
def set_cursor():
if self.current_page == self.notebook.get_current_page():
current_form.set_cursor()
# Using idle_add because the gtk.TreeView grabs the focus at the
# Using idle_add because the Gtk.TreeView grabs the focus at the
# end of the event
gobject.idle_add(set_cursor)
GLib.idle_add(set_cursor)
for dialog in current_form.dialogs:
dialog.show()
@@ -1067,10 +1066,9 @@ class Main(Gtk.Application):
def open_url(self, url):
def idle_open_url():
with gtk.gdk.lock:
self._open_url(url)
return False
gobject.idle_add(idle_open_url)
self._open_url(url)
return False
GLib.idle_add(idle_open_url)
def show_notification(self, title, msg, priority=1):
notification = Gio.Notification.new(title)
+117 -123
View File
@@ -2,14 +2,12 @@
# this repository contains the full copyright notices and license terms.
import configparser
import gtk
import gobject
import os
import gettext
import threading
import logging
from gi.repository import Gtk, Gdk
from gi.repository import GLib, GObject, Gtk
from tryton import __version__
import tryton.common as common
@@ -32,112 +30,115 @@ class DBListEditor(object):
# GTK Stuffs
self.parent = parent
self.dialog = gtk.Dialog(title=_('Profile Editor'), parent=parent,
flags=gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT)
self.dialog = Gtk.Dialog(
title=_('Profile Editor'), transient_for=parent,
modal=True, destroy_with_parent=True)
self.ok_button = self.dialog.add_button(
set_underline(_("Close")), gtk.RESPONSE_CLOSE)
self.dialog.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
set_underline(_("Close")), Gtk.ResponseType.CLOSE)
self.dialog.set_position(Gtk.WindowPosition.CENTER_ON_PARENT)
self.dialog.set_icon(TRYTON_ICON)
tooltips = common.Tooltips()
hpaned = gtk.HPaned()
vbox_profiles = gtk.VBox(homogeneous=False, spacing=6)
self.cell = gtk.CellRendererText()
hpaned = Gtk.HPaned()
vbox_profiles = Gtk.VBox(homogeneous=False, spacing=6)
self.cell = Gtk.CellRendererText()
self.cell.set_property('editable', True)
self.cell.connect('editing-started', self.edit_started)
self.profile_tree = gtk.TreeView()
self.profile_tree = Gtk.TreeView()
self.profile_tree.set_model(profile_store)
self.profile_tree.insert_column_with_attributes(-1, _('Profile'),
self.cell, text=0)
self.profile_tree.connect('cursor-changed', self.profile_selected)
scroll = gtk.ScrolledWindow()
scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
scroll = Gtk.ScrolledWindow()
scroll.set_policy(
Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
scroll.add(self.profile_tree)
self.add_button = gtk.Button()
self.add_button = Gtk.Button()
self.add_button.set_image(common.IconFactory.get_image(
'tryton-add', gtk.ICON_SIZE_BUTTON))
'tryton-add', Gtk.IconSize.BUTTON))
tooltips.set_tip(self.add_button, _("Add new profile"))
self.add_button.connect('clicked', self.profile_create)
self.remove_button = gtk.Button()
self.remove_button = Gtk.Button()
self.remove_button.set_image(common.IconFactory.get_image(
'tryton-remove', gtk.ICON_SIZE_BUTTON))
'tryton-remove', Gtk.IconSize.BUTTON))
tooltips.set_tip(self.remove_button, _("Remove selected profile"))
self.remove_button.get_style_context().add_class(
Gtk.STYLE_CLASS_DESTRUCTIVE_ACTION)
self.remove_button.connect('clicked', self.profile_delete)
bbox = Gtk.ButtonBox()
bbox.pack_start(self.remove_button)
bbox.pack_start(self.add_button)
vbox_profiles.pack_start(scroll, expand=True, fill=True)
vbox_profiles.pack_start(bbox, expand=False, fill=True)
bbox.pack_start(self.remove_button, expand=True, fill=True, padding=0)
bbox.pack_start(self.add_button, expand=True, fill=True, padding=0)
vbox_profiles.pack_start(scroll, expand=True, fill=True, padding=0)
vbox_profiles.pack_start(bbox, expand=False, fill=True, padding=0)
hpaned.add1(vbox_profiles)
table = gtk.Table(4, 2, homogeneous=False)
table = Gtk.Table(n_rows=4, n_columns=2, homogeneous=False)
table.set_row_spacings(3)
table.set_col_spacings(3)
host = gtk.Label(set_underline(_('Host:')))
host.set_use_underline(True)
host.set_alignment(1, 0.5)
host.set_padding(3, 3)
self.host_entry = gtk.Entry()
host = Gtk.Label(
label=set_underline(_('Host:')),
use_underline=True, halign=Gtk.Align.END)
self.host_entry = Gtk.Entry()
self.host_entry.connect('focus-out-event', self.display_dbwidget)
self.host_entry.connect('changed', self.update_profiles, 'host')
self.host_entry.set_activates_default(True)
host.set_mnemonic_widget(self.host_entry)
table.attach(host, 0, 1, 1, 2, yoptions=False, xoptions=gtk.FILL)
table.attach(
host, 0, 1, 1, 2, yoptions=False, xoptions=Gtk.AttachOptions.FILL)
table.attach(self.host_entry, 1, 2, 1, 2, yoptions=False)
database = gtk.Label(set_underline(_('Database:')))
database.set_use_underline(True)
database.set_alignment(1, 0.5)
database.set_padding(3, 3)
self.database_entry = gtk.Entry()
database = Gtk.Label(
label=set_underline(_('Database:')),
use_underline=True, halign=Gtk.Align.END)
self.database_entry = Gtk.Entry()
self.database_entry.connect('changed', self.dbentry_changed)
self.database_entry.connect('changed', self.update_profiles,
'database')
self.database_entry.set_activates_default(True)
self.database_label = gtk.Label()
self.database_label = Gtk.Label(valign=Gtk.Align.START)
self.database_label.set_use_markup(True)
self.database_label.set_alignment(0, 0.5)
self.database_combo = gtk.ComboBox()
dbstore = gtk.ListStore(gobject.TYPE_STRING)
cell = gtk.CellRendererText()
self.database_combo.pack_start(cell, True)
self.database_combo.add_attribute(cell, 'text', 0)
self.database_combo.set_model(dbstore)
self.database_combo = Gtk.ComboBoxText()
self.database_combo.connect('changed', self.dbcombo_changed)
self.database_progressbar = gtk.ProgressBar()
self.database_progressbar = Gtk.ProgressBar()
self.database_progressbar.set_text(_('Fetching databases list'))
db_box = gtk.VBox(homogeneous=True)
db_box.pack_start(self.database_entry)
db_box.pack_start(self.database_combo)
db_box.pack_start(self.database_label)
db_box.pack_start(self.database_progressbar)
db_box = Gtk.VBox(homogeneous=True)
db_box.pack_start(
self.database_entry, expand=True, fill=True, padding=0)
db_box.pack_start(
self.database_combo, expand=True, fill=True, padding=0)
db_box.pack_start(
self.database_label, expand=True, fill=True, padding=0)
db_box.pack_start(
self.database_progressbar, expand=True, fill=True, padding=0)
# Compute size_request of box in order to prevent "form jumping"
width, height = 0, 0
for child in db_box.get_children():
cwidth, cheight = child.size_request()
width, height = max(width, cwidth), max(height, cheight)
request = child.get_preferred_size()[0]
width = max(width, request.width)
height = max(height, request.height)
db_box.set_size_request(width, height)
table.attach(database, 0, 1, 2, 3, yoptions=False, xoptions=gtk.FILL)
table.attach(
database, 0, 1, 2, 3,
yoptions=False, xoptions=Gtk.AttachOptions.FILL)
table.attach(db_box, 1, 2, 2, 3, yoptions=False)
username = gtk.Label(set_underline(_('Username:')))
username.set_use_underline(True)
username.set_alignment(1, 0.5)
username.set_padding(3, 3)
self.username_entry = gtk.Entry()
username = Gtk.Label(
label=set_underline(_('Username:')),
use_underline=True, halign=Gtk.Align.END)
self.username_entry = Gtk.Entry()
self.username_entry.connect('changed', self.update_profiles,
'username')
username.set_mnemonic_widget(self.username_entry)
self.username_entry.set_activates_default(True)
table.attach(username, 0, 1, 3, 4, yoptions=False, xoptions=gtk.FILL)
table.attach(
username, 0, 1, 3, 4,
yoptions=False, xoptions=Gtk.AttachOptions.FILL)
table.attach(self.username_entry, 1, 2, 3, 4, yoptions=False)
hpaned.add2(table)
hpaned.set_position(250)
self.dialog.vbox.pack_start(hpaned)
self.dialog.vbox.pack_start(hpaned, expand=True, fill=True, padding=0)
self.dialog.set_default_size(640, 350)
self.dialog.set_default_response(gtk.RESPONSE_CLOSE)
self.dialog.set_default_response(Gtk.ResponseType.CLOSE)
self.dialog.connect('close', lambda *a: False)
self.dialog.connect('response', self.response)
@@ -228,7 +229,7 @@ class DBListEditor(object):
self.display_dbwidget(None, None)
def edit_started(self, renderer, editable, path):
if isinstance(editable, gtk.Entry):
if isinstance(editable, Gtk.Entry):
editable.connect('focus-out-event', self.edit_profilename,
renderer, path)
@@ -291,7 +292,7 @@ class DBListEditor(object):
self.dbs_updated = threading.Event()
threading.Thread(target=self.refresh_databases_start,
args=(host, port)).start()
gobject.timeout_add(100, self.refresh_databases_end, host, port)
GLib.timeout_add(100, self.refresh_databases_end, host, port)
def refresh_databases_start(self, host, port):
dbs = None
@@ -320,11 +321,10 @@ class DBListEditor(object):
self.database_label.set_label('<b>%s</b>' % label)
self.database_label.show()
else:
liststore = self.database_combo.get_model()
liststore.clear()
self.database_combo.remove_all()
index = -1
for db_num, db_name in enumerate(dbs):
liststore.append([db_name])
self.database_combo.append_text(db_name)
if self.current_database and db_name == self.current_database:
index = db_num
if index == -1:
@@ -387,116 +387,112 @@ class DBListEditor(object):
try:
int(new_value)
except ValueError:
entry.stop_emission('insert-text')
entry.stop_emission_by_name('insert-text')
class DBLogin(object):
def __init__(self):
# Fake windows to avoid warning about Dialog without transient
self._window = gtk.Window()
self.dialog = gtk.Dialog(
title="Tryton - " + _('Login'), flags=gtk.DIALOG_MODAL)
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.WIN_POS_CENTER_ALWAYS)
self.dialog.set_position(Gtk.WindowPosition.CENTER_ALWAYS)
self.dialog.set_resizable(False)
tooltips = common.Tooltips()
button_cancel = gtk.Button(_('_Cancel'), use_underline=True)
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.RESPONSE_CANCEL)
self.button_connect = gtk.Button(_('C_onnect'), use_underline=True)
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.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.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)
self.table_main = Gtk.Table(n_rows=3, n_columns=3, homogeneous=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)
self.dialog.vbox.pack_start(
alignment, expand=True, fill=True, padding=0)
image = gtk.Image()
image = Gtk.Image()
image.set_from_file(os.path.join(PIXMAPS_DIR, 'tryton.png'))
image.set_alignment(0.5, 1)
image.set_valign(Gtk.Align.START)
overlay = Gtk.Overlay()
overlay.add(image)
label = Gtk.Label(__version__)
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
label.override_color(
Gtk.StateFlags.NORMAL, Gdk.RGBA(1, 1, 1, 1))
overlay.add_overlay(label)
self.table_main.attach(overlay, 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.profile_store = Gtk.ListStore(
GObject.TYPE_STRING, GObject.TYPE_BOOLEAN)
self.combo_profile = Gtk.ComboBox()
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(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 = 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(set_underline(_('Manage...')),
use_underline=True)
self.profile_button = Gtk.Button(
label=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.profile_label, 0, 1, 1, 2, xoptions=Gtk.AttachOptions.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.table_main.attach(
self.profile_button, 2, 3, 1, 2, xoptions=Gtk.AttachOptions.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.label_host = Gtk.Label(
label=set_underline(_('Host:')),
use_underline=True, halign=Gtk.Align.END)
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.label_host, 0, 1, 4, 5, xoptions=Gtk.AttachOptions.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.label_database = Gtk.Label(
label=set_underline(_('Database:')),
use_underline=True, halign=Gtk.Align.END)
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.label_database, 0, 1, 5, 6, xoptions=Gtk.AttachOptions.FILL)
self.table_main.attach(self.entry_database, 1, 3, 5, 6)
self.entry_login = gtk.Entry()
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 = Gtk.Label(
label=set_underline(_("User name:")),
use_underline=True, halign=Gtk.Align.END, margin=3)
label_username.set_mnemonic_widget(self.entry_login)
self.table_main.attach(label_username, 0, 1, 6, 7, xoptions=gtk.FILL)
self.table_main.attach(
label_username, 0, 1, 6, 7, xoptions=Gtk.AttachOptions.FILL)
# Profile information
self.profile_cfg = os.path.join(get_config_dir(), 'profiles.cfg')
@@ -620,8 +616,6 @@ class DBLogin(object):
self.entry_login.grab_focus()
# Reshow dialog for gtk-quarks
self.dialog.reshow_with_initial_size()
self.expander.set_expanded(CONFIG['login.expanded'])
# The previous action did not called expand_hostspec
self.expand_hostspec(self.expander)
@@ -629,7 +623,7 @@ class DBLogin(object):
response, result = None, ('', '', '', '')
while not all(result):
response = self.dialog.run()
if response != gtk.RESPONSE_OK:
if response != Gtk.ResponseType.OK:
break
self.clear_profile_combo()
active_profile = self.combo_profile.get_active()
@@ -663,4 +657,4 @@ class DBLogin(object):
self.dialog.destroy()
self._window.destroy()
return response == gtk.RESPONSE_OK
return response == Gtk.ResponseType.OK
-109
View File
@@ -1,109 +0,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 gtk
import gettext
from tryton.common import get_toplevel_window, IconFactory
from tryton.common.underline import set_underline
from tryton.config import TRYTON_ICON, CONFIG
from tryton.gui import Main
_ = gettext.gettext
class Email(object):
def __init__(self):
self.parent = get_toplevel_window()
self.win = gtk.Dialog(_('Email'), self.parent,
gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT)
Main().add_window(self.win)
cancel_button = self.win.add_button(
set_underline(_("Cancel")), gtk.RESPONSE_CANCEL)
cancel_button.set_image(IconFactory.get_image(
'tryton-cancel', gtk.ICON_SIZE_BUTTON))
cancel_button.set_always_show_image(True)
ok_button = self.win.add_button(
set_underline(_("OK")), gtk.RESPONSE_OK)
ok_button.set_image(IconFactory.get_image(
'tryton-ok', gtk.ICON_SIZE_BUTTON))
ok_button.set_always_show_image(True)
self.win.set_default_response(gtk.RESPONSE_OK)
self.win.set_icon(TRYTON_ICON)
self.win.vbox.set_spacing(3)
self.win.vbox.pack_start(gtk.Label(
_('Email Program Settings')), expand=False, fill=True)
self.win.vbox.pack_start(gtk.HSeparator())
hbox = gtk.HBox(spacing=3)
label = gtk.Label(_('Command Line:'))
hbox.pack_start(label, expand=True, fill=True)
self.entry = gtk.Entry()
self.entry.set_property('activates_default', True)
self.entry.set_width_chars(50)
self.entry.set_text(CONFIG['client.email'])
label.set_mnemonic_widget(label)
hbox.pack_start(self.entry, expand=True, fill=True)
self.win.vbox.pack_start(hbox, expand=True, fill=True)
label = gtk.Label(_('Legend of Available Placeholders:'))
label.set_alignment(0.0, 0.5)
label.set_padding(0, 10)
self.win.vbox.pack_start(label, expand=False, fill=True)
hbox = gtk.HBox(spacing=3)
vboxl = gtk.VBox(homogeneous=True, spacing=3)
label = gtk.Label(_('To:'))
label.set_alignment(0, 0)
label.set_padding(10, 0)
vboxl.pack_start(label, expand=False, fill=False)
label = gtk.Label(_('CC:'))
label.set_alignment(0, 0)
label.set_padding(10, 0)
vboxl.pack_start(label, expand=False, fill=False)
label = gtk.Label(_('Subject:'))
label.set_alignment(0, 0)
label.set_padding(10, 0)
vboxl.pack_start(label, expand=False, fill=False)
label = gtk.Label(_('Body:'))
label.set_alignment(0, 0)
label.set_padding(10, 0)
vboxl.pack_start(label, expand=False, fill=False)
label = gtk.Label(_('Attachment:'))
label.set_alignment(0, 0)
label.set_padding(10, 0)
vboxl.pack_start(label, expand=False, fill=False)
vboxr = gtk.VBox(homogeneous=True, spacing=3)
label = gtk.Label(' ${to}')
label.set_alignment(0, 0)
vboxr.pack_start(label, expand=False, fill=False)
label = gtk.Label(' ${cc}')
label.set_alignment(0, 0)
vboxr.pack_start(label, expand=False, fill=False)
label = gtk.Label(' ${subject}')
label.set_alignment(0, 0)
vboxr.pack_start(label, expand=False, fill=False)
label = gtk.Label(' ${body}')
label.set_alignment(0, 0)
vboxr.pack_start(label, expand=False, fill=False)
label = gtk.Label(' ${attachment}')
label.set_alignment(0, 0)
vboxr.pack_start(label, expand=False, fill=False)
hbox.pack_start(vboxl, expand=False, fill=False)
hbox.pack_start(vboxr, expand=False, fill=False)
self.win.vbox.pack_start(hbox, expand=True, fill=True)
self.win.show_all()
def run(self):
"Run the window"
res = self.win.run()
if res == gtk.RESPONSE_OK:
CONFIG['client.email'] = self.entry.get_text()
CONFIG.save()
self.parent.present()
self.win.destroy()
return res
+97
View File
@@ -0,0 +1,97 @@
# 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 gettext
from gi.repository import Gtk
from tryton.common import get_toplevel_window, IconFactory
from tryton.common.underline import set_underline
from tryton.config import TRYTON_ICON, CONFIG
from tryton.gui import Main
_ = gettext.gettext
class Email(object):
def __init__(self):
self.parent = get_toplevel_window()
self.win = Gtk.Dialog(
title=_('Email'), transient_for=self.parent, modal=True,
destroy_with_parent=True)
Main().add_window(self.win)
cancel_button = self.win.add_button(
set_underline(_("Cancel")), Gtk.ResponseType.CANCEL)
cancel_button.set_image(
IconFactory.get_image('tryton-cancel', Gtk.IconSize.BUTTON))
cancel_button.set_always_show_image(True)
ok_button = self.win.add_button(
set_underline(_("OK")), Gtk.ResponseType.OK)
ok_button.set_image(
IconFactory.get_image('tryton-ok', Gtk.IconSize.BUTTON))
ok_button.set_always_show_image(True)
self.win.set_default_response(Gtk.ResponseType.OK)
self.win.set_icon(TRYTON_ICON)
self.win.vbox.set_spacing(3)
self.win.vbox.pack_start(Gtk.Label(
_('Email Program Settings')), expand=False, fill=True, padding=0)
self.win.vbox.pack_start(
Gtk.HSeparator(), expand=True, fill=True, padding=0)
hbox = Gtk.HBox(spacing=3)
label = Gtk.Label(label=_('Command Line:'))
hbox.pack_start(label, expand=True, fill=True, padding=0)
self.entry = Gtk.Entry()
self.entry.set_property('activates_default', True)
self.entry.set_width_chars(50)
self.entry.set_text(CONFIG['client.email'])
label.set_mnemonic_widget(label)
hbox.pack_start(self.entry, expand=True, fill=True, padding=0)
self.win.vbox.pack_start(hbox, expand=True, fill=True, padding=0)
label = Gtk.Label(
label=_('Legend of Available Placeholders:'),
halign=Gtk.Align.START, margin_top=10, margin_bottom=5)
self.win.vbox.pack_start(label, expand=False, fill=True, padding=0)
hbox = Gtk.HBox(spacing=3)
vboxl = Gtk.VBox(homogeneous=True, spacing=3)
label = Gtk.Label(label=_('To:'), halign=Gtk.Align.START)
vboxl.pack_start(label, expand=False, fill=False, padding=0)
label = Gtk.Label(label=_('CC:'), halign=Gtk.Align.START)
vboxl.pack_start(label, expand=False, fill=False, padding=0)
label = Gtk.Label(label=_('Subject:'), halign=Gtk.Align.START)
vboxl.pack_start(label, expand=False, fill=False, padding=0)
label = Gtk.Label(label=_('Body:'), halign=Gtk.Align.START)
vboxl.pack_start(label, expand=False, fill=False, padding=0)
label = Gtk.Label(label=_('Attachment:'), halign=Gtk.Align.START)
vboxl.pack_start(label, expand=False, fill=False, padding=0)
vboxr = Gtk.VBox(homogeneous=True, spacing=3)
label = Gtk.Label(label=' ${to}', halign=Gtk.Align.START)
vboxr.pack_start(label, expand=False, fill=False, padding=0)
label = Gtk.Label(label=' ${cc}', halign=Gtk.Align.START)
vboxr.pack_start(label, expand=False, fill=False, padding=0)
label = Gtk.Label(label=' ${subject}', halign=Gtk.Align.START)
vboxr.pack_start(label, expand=False, fill=False, padding=0)
label = Gtk.Label(label=' ${body}', halign=Gtk.Align.START)
vboxr.pack_start(label, expand=False, fill=False, padding=0)
label = Gtk.Label(label=' ${attachment}', halign=Gtk.Align.START)
vboxr.pack_start(label, expand=False, fill=False, padding=0)
hbox.pack_start(vboxl, expand=False, fill=False, padding=0)
hbox.pack_start(vboxr, expand=False, fill=False, padding=0)
self.win.vbox.pack_start(hbox, expand=True, fill=True, padding=0)
self.win.show_all()
def run(self):
"Run the window"
res = self.win.run()
if res == Gtk.ResponseType.OK:
CONFIG['client.email'] = self.entry.get_text()
CONFIG.save()
self.parent.present()
self.win.destroy()
return res
+63 -60
View File
@@ -2,10 +2,8 @@
# this repository contains the full copyright notices and license terms.
"Form"
import gettext
import gtk
import gobject
from gi.repository import Gtk
from gi.repository import Gdk, GLib, Gtk
from tryton.gui.window.view_form.screen import Screen
from tryton.action import Action
@@ -53,7 +51,7 @@ class Form(SignalEvent, TabContent):
self._record_message)
self.screen.signal_connect(self, 'record-modified',
lambda *a: gobject.idle_add(self._record_modified, *a))
lambda *a: GLib.idle_add(self._record_modified, *a))
self.screen.signal_connect(self, 'record-saved', self._record_saved)
self.screen.signal_connect(self, 'attachment-count',
self._attachment_count)
@@ -127,17 +125,14 @@ class Form(SignalEvent, TabContent):
record = self.screen.current_record
menu = button._menu = Gtk.Menu()
for name, callback in Attachment.get_attachments(record):
item = Gtk.MenuItem()
item.set_label(name)
item = Gtk.MenuItem(label=name)
item.connect('activate', activate, callback)
menu.add(item)
menu.add(Gtk.SeparatorMenuItem())
add_item = Gtk.MenuItem()
add_item.set_label(_("Add..."))
add_item = Gtk.MenuItem(label=_("Add..."))
add_item.connect('activate', add_file)
menu.add(add_item)
manage_item = Gtk.MenuItem()
manage_item.set_label(_("Manage..."))
manage_item = Gtk.MenuItem(label=_("Manage..."))
manage_item.connect('activate', window)
menu.add(manage_item)
menu.show_all()
@@ -160,7 +155,7 @@ class Form(SignalEvent, TabContent):
icon = 'tryton-attach'
else:
icon = 'tryton-attach'
image = common.IconFactory.get_image(icon, gtk.ICON_SIZE_LARGE_TOOLBAR)
image = common.IconFactory.get_image(icon, Gtk.IconSize.LARGE_TOOLBAR)
image.show()
self.buttons['attach'].set_icon_widget(image)
record = self.screen.current_record
@@ -186,9 +181,13 @@ class Form(SignalEvent, TabContent):
label = _('Note(%d)') % signal_data
self.buttons['note'].set_label(label)
if signal_data:
self.buttons['note'].set_stock_id('tryton-note-hi')
# FIXME
icon = 'tryton-note'
else:
self.buttons['note'].set_stock_id('tryton-note')
icon = 'tryton-note'
image = common.IconFactory.get_image(icon, Gtk.IconSize.LARGE_TOOLBAR)
image.show()
self.buttons['note'].set_icon_widget(image)
record = self.screen.current_record
if not record or record.id < 0:
sensitive = False
@@ -205,7 +204,7 @@ class Form(SignalEvent, TabContent):
current_record = self.screen.current_record
if not current_record or current_record.id < 0:
self.message_info(
_('You have to select one record.'), gtk.MESSAGE_INFO)
_('You have to select one record.'), Gtk.MessageType.INFO)
return False
fields = [
@@ -281,7 +280,7 @@ class Form(SignalEvent, TabContent):
else:
label = common.ellipsize(self.name, 80)
tooltip = self.name
self.title.set_label(label)
self.title.set_markup(label)
tooltips.set_tip(self.title, tooltip)
self.set_buttons_sensitive(revision)
@@ -315,9 +314,10 @@ class Form(SignalEvent, TabContent):
msg = _('Are you sure to remove those records?')
if sur(msg):
if not self.screen.remove(delete=True, force_remove=True):
self.message_info(_('Records not removed.'), gtk.MESSAGE_ERROR)
self.message_info(
_('Records not removed.'), Gtk.MessageType.ERROR)
else:
self.message_info(_('Records removed.'), gtk.MESSAGE_INFO)
self.message_info(_('Records removed.'), Gtk.MessageType.INFO)
self.screen.count_tab_domain()
def sig_import(self, widget=None):
@@ -355,7 +355,7 @@ class Form(SignalEvent, TabContent):
return
if self.screen.copy():
self.message_info(_('Working now on the duplicated record(s).'),
gtk.MESSAGE_INFO)
Gtk.MessageType.INFO)
self.screen.count_tab_domain()
def sig_save(self, widget=None):
@@ -366,11 +366,12 @@ class Form(SignalEvent, TabContent):
or common.MODELACCESS[self.model]['create']):
return
if self.screen.save_current():
self.message_info(_('Record saved.'), gtk.MESSAGE_INFO)
self.message_info(_('Record saved.'), Gtk.MessageType.INFO)
self.screen.count_tab_domain()
return True
else:
self.message_info(self.screen.invalid_message(), gtk.MESSAGE_ERROR)
self.message_info(
self.screen.invalid_message(), Gtk.MessageType.ERROR)
return False
def sig_previous(self, widget=None):
@@ -447,19 +448,20 @@ class Form(SignalEvent, TabContent):
menu.popdown()
return
def menu_position(menu, data):
def menu_position(menu, x, y, user_data):
widget_allocation = widget.get_allocation()
if hasattr(widget.window, 'get_root_coords'):
x, y = widget.window.get_root_coords(
widget_allocation.x, widget_allocation.y)
else:
x, y = widget.window.get_origin()
x += widget_allocation.x
y += widget_allocation.y
x, y = widget.get_window().get_root_coords(
widget_allocation.x, widget_allocation.y)
return (x, y + widget_allocation.height, False)
menu.show_all()
menu.popup(None, None, menu_position, 0, gtk.get_current_event_time(),
None)
if hasattr(menu, 'popup_at_widget'):
menu.popup_at_widget(
widget, Gdk.Gravity.SOUTH_WEST, Gdk.Gravity.NORTH_WEST,
Gtk.get_current_event())
else:
menu.popup(
None, None, menu_position, None, 0,
Gtk.get_current_event_time())
def _record_message(self, screen, signal_data):
name = '_'
@@ -542,10 +544,12 @@ class Form(SignalEvent, TabContent):
gtktoolbar = super(Form, self).create_toolbar(toolbars)
attach_btn = self.buttons['attach']
attach_btn.drag_dest_set(gtk.DEST_DEFAULT_ALL, [
gtk.TargetEntry.new('text/uri-list', 0, 0),
gtk.TargetEntry.new('text/plain', 0, 0),
], gtk.gdk.ACTION_MOVE | gtk.gdk.ACTION_COPY)
attach_btn.drag_dest_set(
Gtk.DestDefaults.ALL, [
Gtk.TargetEntry.new('text/uri-list', 0, 0),
Gtk.TargetEntry.new('text/plain', 0, 0),
],
Gdk.DragAction.MOVE | Gdk.DragAction.COPY)
attach_btn.connect('drag_data_received',
self.attach_drag_data_received)
@@ -565,10 +569,10 @@ class Form(SignalEvent, TabContent):
('print', 'print', _('Print'), _('Print report')),
):
if action_type is not None:
tbutton = gtk.ToggleToolButton()
tbutton = Gtk.ToggleToolButton()
tbutton.set_icon_widget(common.IconFactory.get_image(
iconstock.get(special_action),
gtk.ICON_SIZE_LARGE_TOOLBAR))
Gtk.IconSize.LARGE_TOOLBAR))
tbutton.set_label(action_name)
tbutton._menu = self._create_popup_menu(tbutton,
action_type, toolbars[action_type], special_action)
@@ -579,21 +583,21 @@ class Form(SignalEvent, TabContent):
tbutton._can_be_sensitive = bool(
tbutton._menu.get_children())
else:
tbutton = gtk.SeparatorToolItem()
tbutton = Gtk.SeparatorToolItem()
gtktoolbar.insert(tbutton, -1)
gtktoolbar.insert(gtk.SeparatorToolItem(), -1)
gtktoolbar.insert(Gtk.SeparatorToolItem(), -1)
url_button = gtk.ToggleToolButton()
url_button = Gtk.ToggleToolButton()
url_button.set_icon_widget(
common.IconFactory.get_image(
'tryton-public', gtk.ICON_SIZE_LARGE_TOOLBAR))
'tryton-public', Gtk.IconSize.LARGE_TOOLBAR))
url_button.set_label(_('_Copy URL'))
url_button.set_use_underline(True)
self.tooltips.set_tip(
url_button, _('Copy URL into clipboard'))
url_button._menu = url_menu = gtk.Menu()
url_menuitem = gtk.MenuItem()
url_button._menu = url_menu = Gtk.Menu()
url_menuitem = Gtk.MenuItem()
url_menuitem.connect('activate', self.url_copy)
url_menu.add(url_menuitem)
url_menu.show_all()
@@ -605,7 +609,7 @@ class Form(SignalEvent, TabContent):
return gtktoolbar
def _create_popup_menu(self, widget, keyword, actions, special_action):
menu = gtk.Menu()
menu = Gtk.Menu()
menu.connect('deactivate', self._popup_menu_hide, widget)
widget.connect('toggled', self._update_popup_menu, menu, keyword)
@@ -615,7 +619,7 @@ class Form(SignalEvent, TabContent):
new_action['direct_print'] = True
elif special_action == 'email':
new_action['email_print'] = True
menuitem = gtk.MenuItem(set_underline(action['name']))
menuitem = Gtk.MenuItem(label=set_underline(action['name']))
menuitem.set_use_underline(True)
menuitem.connect('activate', self._popup_menu_selected, widget,
new_action, keyword)
@@ -623,10 +627,10 @@ class Form(SignalEvent, TabContent):
return menu
def _popup_menu_selected(self, menuitem, togglebutton, action, keyword):
event = gtk.get_current_event()
event = Gtk.get_current_event()
allow_similar = False
if (event.state & gtk.gdk.CONTROL_MASK
or event.state & gtk.gdk.MOD1_MASK):
if (event.state & Gdk.ModifierType.CONTROL_MASK
or event.state & Gdk.ModifierType.MOD1_MASK):
allow_similar = True
with Window(hide_current=True, allow_similar=allow_similar):
self._action(action, keyword)
@@ -638,21 +642,17 @@ class Form(SignalEvent, TabContent):
def _update_popup_menu(self, tbutton, menu, keyword):
for item in menu.get_children():
if (getattr(item, '_update_action', False)
or isinstance(item, gtk.SeparatorMenuItem)):
or isinstance(item, Gtk.SeparatorMenuItem)):
menu.remove(item)
buttons = [b for b in self.screen.get_buttons()
if keyword == b.attrs.get('keyword', 'action')]
if buttons and menu.get_children():
menu.add(gtk.SeparatorMenuItem())
menu.add(Gtk.SeparatorMenuItem())
for button in buttons:
menuitem = gtk.ImageMenuItem()
menuitem.set_label(
set_underline(button.attrs.get('string', _('Unknown'))))
menuitem.set_use_underline(True)
if button.attrs.get('icon'):
menuitem.set_image(common.IconFactory.get_image(
button.attrs['icon'], gtk.ICON_SIZE_MENU))
menuitem = Gtk.MenuItem(
label=set_underline(button.attrs.get('string', _('Unknown'))),
use_underline=True)
menuitem.connect('activate',
lambda m, attrs: self.screen.button(attrs), button.attrs)
menuitem._update_action = True
@@ -671,9 +671,9 @@ class Form(SignalEvent, TabContent):
kw_plugins.append((name, func))
if kw_plugins:
menu.add(gtk.SeparatorMenuItem())
menu.add(Gtk.SeparatorMenuItem())
for name, func in kw_plugins:
menuitem = gtk.MenuItem(set_underline(name))
menuitem = Gtk.MenuItem(label=set_underline(name))
menuitem.set_use_underline(True)
menuitem.connect('activate', lambda m, func: func({
'model': self.model,
@@ -687,8 +687,11 @@ class Form(SignalEvent, TabContent):
def url_copy(self, menuitem):
url = self.screen.get_url(self.name)
for selection in [gtk.CLIPBOARD_PRIMARY, gtk.CLIPBOARD_CLIPBOARD]:
clipboard = gtk.clipboard_get(selection)
for selection in [
Gdk.Atom.intern('PRIMARY', True),
Gdk.Atom.intern('CLIPBOARD', True),
]:
clipboard = Gtk.Clipboard.get(selection)
clipboard.set_text(url, -1)
def url_set(self, button, menuitem):
+1 -1
View File
@@ -11,7 +11,7 @@ class InfoBar(object):
self.info_bar = Gtk.InfoBar()
self.info_bar.get_content_area().pack_start(
self.info_label, False, False)
self.info_label, False, False, 0)
self.info_bar.set_show_close_button(True)
self.info_bar.connect('response', lambda i, r: i.hide())
+26 -20
View File
@@ -1,9 +1,10 @@
# 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 sys
import gtk
import gettext
from gi.repository import Gtk
from tryton.common import get_toplevel_window, IconFactory
from tryton.common.underline import set_underline
from tryton.config import TRYTON_ICON, CONFIG
@@ -17,44 +18,49 @@ class Limit(object):
def __init__(self):
self.parent = get_toplevel_window()
self.win = gtk.Dialog(_('Limit'), self.parent,
gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT)
self.win = Gtk.Dialog(
title=_('Limit'), transient_for=self.parent, modal=True,
destroy_with_parent=True)
Main().add_window(self.win)
cancel_button = self.win.add_button(
set_underline(_("Cancel")), gtk.RESPONSE_CANCEL)
set_underline(_("Cancel")), Gtk.ResponseType.CANCEL)
cancel_button.set_image(IconFactory.get_image(
'tryton-cancel', gtk.ICON_SIZE_BUTTON))
'tryton-cancel', Gtk.IconSize.BUTTON))
cancel_button.set_always_show_image(True)
ok_button = self.win.add_button(
set_underline(_("OK")), gtk.RESPONSE_OK)
set_underline(_("OK")), Gtk.ResponseType.OK)
ok_button.set_image(IconFactory.get_image(
'tryton-ok', gtk.ICON_SIZE_BUTTON))
'tryton-ok', Gtk.IconSize.BUTTON))
ok_button.set_always_show_image(True)
self.win.set_default_response(gtk.RESPONSE_OK)
self.win.set_default_response(Gtk.ResponseType.OK)
self.win.set_icon(TRYTON_ICON)
self.win.vbox.set_spacing(3)
self.win.vbox.pack_start(gtk.Label(
_('Search Limit Settings')), expand=False, fill=True)
self.win.vbox.pack_start(gtk.HSeparator())
hbox = gtk.HBox(spacing=3)
label = gtk.Label(_('Limit:'))
hbox.pack_start(label, expand=True, fill=True)
adjustment = gtk.Adjustment(value=CONFIG['client.limit'],
lower=1, upper=sys.maxsize, step_incr=10, page_incr=100)
self.spin_limit = gtk.SpinButton()
self.win.vbox.pack_start(Gtk.Label(
label=_('Search Limit Settings')),
expand=False, fill=True, padding=0)
self.win.vbox.pack_start(
Gtk.HSeparator(), expand=True, fill=True, padding=0)
hbox = Gtk.HBox(spacing=3)
label = Gtk.Label(label=_('Limit:'))
hbox.pack_start(label, expand=True, fill=True, padding=0)
adjustment = Gtk.Adjustment(
value=CONFIG['client.limit'],
lower=1, upper=sys.maxsize,
step_incr=10, page_incr=100)
self.spin_limit = Gtk.SpinButton()
self.spin_limit.configure(adjustment, climb_rate=1, digits=0)
self.spin_limit.set_numeric(False)
self.spin_limit.set_activates_default(True)
label.set_mnemonic_widget(self.spin_limit)
hbox.pack_start(self.spin_limit, expand=True, fill=True)
self.win.vbox.pack_start(hbox, expand=True, fill=True)
hbox.pack_start(self.spin_limit, expand=True, fill=True, padding=0)
self.win.vbox.pack_start(hbox, expand=True, fill=True, padding=0)
self.win.show_all()
def run(self):
'Run the window'
res = self.win.run()
if res == gtk.RESPONSE_OK:
if res == Gtk.ResponseType.OK:
CONFIG['client.limit'] = self.spin_limit.get_value_as_int()
CONFIG.save()
self.parent.present()
+22 -18
View File
@@ -2,9 +2,10 @@
# this repository contains the full copyright notices and license terms.
"Preference"
import gettext
import gtk
import copy
from gi.repository import Gdk, Gtk
import tryton.rpc as rpc
from tryton.common import RPCExecute, RPCException, IconFactory
from tryton.common.underline import set_underline
@@ -22,29 +23,31 @@ class Preference(NoModal):
def __init__(self, user, callback):
NoModal.__init__(self)
self.callback = callback
self.win = gtk.Dialog(_('Preferences'), self.parent,
gtk.DIALOG_DESTROY_WITH_PARENT)
self.win = Gtk.Dialog(
title=_('Preferences'), transient_for=self.parent,
destroy_with_parent=True)
Main().add_window(self.win)
self.win.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
self.win.set_position(Gtk.WindowPosition.CENTER_ON_PARENT)
self.win.set_icon(TRYTON_ICON)
self.accel_group = gtk.AccelGroup()
self.accel_group = Gtk.AccelGroup()
self.win.add_accel_group(self.accel_group)
self.but_cancel = self.win.add_button(
set_underline(_("Cancel")), gtk.RESPONSE_CANCEL)
self.but_cancel.set_image(IconFactory.get_image(
'tryton-cancel', gtk.ICON_SIZE_BUTTON))
set_underline(_("Cancel")), Gtk.ResponseType.CANCEL)
self.but_cancel.set_image(
IconFactory.get_image('tryton-cancel', Gtk.IconSize.BUTTON))
self.but_cancel.set_always_show_image(True)
self.but_ok = self.win.add_button(
set_underline(_("OK")), gtk.RESPONSE_OK)
self.but_ok.set_image(IconFactory.get_image(
'tryton-ok', gtk.ICON_SIZE_BUTTON))
set_underline(_("OK")), Gtk.ResponseType.OK)
self.but_ok.set_image(
IconFactory.get_image('tryton-ok', Gtk.IconSize.BUTTON))
self.but_ok.set_always_show_image(True)
self.but_ok.add_accelerator('clicked', self.accel_group,
gtk.keysyms.Return, gtk.gdk.CONTROL_MASK, gtk.ACCEL_VISIBLE)
self.but_ok.add_accelerator(
'clicked', self.accel_group, Gdk.KEY_Return,
Gdk.ModifierType.CONTROL_MASK, Gtk.AccelFlags.VISIBLE)
self.win.set_default_response(gtk.RESPONSE_OK)
self.win.set_default_response(Gtk.ResponseType.OK)
self.win.connect('response', self.response)
try:
@@ -55,9 +58,9 @@ class Preference(NoModal):
self.win = None
return
title = gtk.Label(_('Edit User Preferences'))
title = Gtk.Label(label=_('Edit User Preferences'))
title.show()
self.win.vbox.pack_start(title, expand=False, fill=True)
self.win.vbox.pack_start(title, expand=False, fill=True, padding=0)
self.screen = Screen('res.user', mode=[])
# Reset readonly set automaticly by MODELACCESS
self.screen.readonly = False
@@ -81,7 +84,8 @@ class Preference(NoModal):
self.screen.display(set_cursor=True)
self.screen.widget.show()
self.win.vbox.pack_start(self.screen.widget)
self.win.vbox.pack_start(
self.screen.widget, expand=True, fill=True, padding=0)
self.win.set_title(_('Preference'))
self.win.set_default_size(*self.default_size())
@@ -90,7 +94,7 @@ class Preference(NoModal):
self.win.show()
def response(self, win, response_id):
if response_id == gtk.RESPONSE_OK:
if response_id == Gtk.ResponseType.OK:
if self.screen.current_record.validate():
vals = copy.copy(self.screen.get())
try:
+25 -21
View File
@@ -1,8 +1,9 @@
# 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
from gi.repository import Gtk
from tryton.common import get_toplevel_window, IconFactory
from tryton.common.datetime_ import date_parse
from tryton.common.underline import set_underline
@@ -17,31 +18,34 @@ class Revision(object):
def __init__(self, revisions, revision=None, format_='%x %H:%M:%S.%f'):
self.parent = get_toplevel_window()
self.win = gtk.Dialog(_('Revision'), self.parent,
gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT)
self.win = Gtk.Dialog(
title=_('Revision'), transient_for=self.parent, modal=True,
destroy_with_parent=True)
Main().add_window(self.win)
cancel_button = self.win.add_button(
set_underline(_("Cancel")), gtk.RESPONSE_CANCEL)
set_underline(_("Cancel")), Gtk.ResponseType.CANCEL)
cancel_button.set_image(IconFactory.get_image(
'tryton-cancel', gtk.ICON_SIZE_BUTTON))
'tryton-cancel', Gtk.IconSize.BUTTON))
cancel_button.set_always_show_image(True)
ok_button = self.win.add_button(
set_underline(_("OK")), gtk.RESPONSE_OK)
set_underline(_("OK")), Gtk.ResponseType.OK)
ok_button.set_image(IconFactory.get_image(
'tryton-ok', gtk.ICON_SIZE_BUTTON))
'tryton-ok', Gtk.IconSize.BUTTON))
ok_button.set_always_show_image(True)
self.win.set_default_response(gtk.RESPONSE_OK)
self.win.set_default_response(Gtk.ResponseType.OK)
self.win.set_icon(TRYTON_ICON)
self.win.vbox.set_spacing(3)
self.win.vbox.pack_start(gtk.Label(
_('Select a revision')), expand=False, fill=True)
self.win.vbox.pack_start(gtk.HSeparator())
hbox = gtk.HBox(spacing=3)
label = gtk.Label(_('Revision:'))
hbox.pack_start(label, expand=True, fill=True)
list_store = gtk.ListStore(str, str)
self.win.vbox.pack_start(Gtk.Label(
label=_('Select a revision')),
expand=False, fill=True, padding=0)
self.win.vbox.pack_start(
Gtk.HSeparator(), expand=True, fill=True, padding=0)
hbox = Gtk.HBox(spacing=3)
label = Gtk.Label(label=_('Revision:'))
hbox.pack_start(label, expand=True, fill=True, padding=0)
list_store = Gtk.ListStore(str, str)
# Set model on instantiation to get the default cellrenderer as text
combobox = gtk.ComboBoxEntry(model=list_store)
combobox = Gtk.ComboBox(model=list_store, has_entry=True)
self.entry = combobox.get_child()
self.entry.connect('focus-out-event', self.focus_out)
self.entry.connect('activate', self.activate)
@@ -62,12 +66,12 @@ class Revision(object):
if rev == revision:
active = i
combobox.set_active(active)
cell = gtk.CellRendererText()
combobox.pack_start(cell, True)
cell = Gtk.CellRendererText()
combobox.pack_start(cell, expand=True)
combobox.add_attribute(cell, 'text', 1)
hbox.pack_start(combobox, expand=True, fill=True)
hbox.pack_start(combobox, expand=True, fill=True, padding=0)
combobox.set_entry_text_column(0)
self.win.vbox.pack_start(hbox, expand=True, fill=True)
self.win.vbox.pack_start(hbox, expand=True, fill=True, padding=0)
self.win.show_all()
def focus_out(self, entry, event):
@@ -107,7 +111,7 @@ class Revision(object):
def run(self):
response = self.win.run()
revision = None
if response == gtk.RESPONSE_OK:
if response == Gtk.ResponseType.OK:
revision = self._value
self.parent.present()
self.win.destroy()
+49 -56
View File
@@ -2,12 +2,12 @@
# this repository contains the full copyright notices and license terms.
import gettext
import gtk
import pango
from gi.repository import Gtk
from gi.repository import Gtk, Pango
import tryton.common as common
from tryton.config import CONFIG
from tryton.common.widget_style import widget_class
from tryton.gui import Main
from .infobar import InfoBar
@@ -173,7 +173,7 @@ class TabContent(InfoBar):
self.tooltips = common.Tooltips()
self.accel_group = Main().accel_group
self.widget = gtk.VBox(spacing=3)
self.widget = Gtk.VBox(spacing=3)
self.widget.show()
title_box = self.make_title_bar()
@@ -181,34 +181,35 @@ class TabContent(InfoBar):
self.toolbar = self.create_toolbar(self.get_toolbars())
self.toolbar.show_all()
self.widget.pack_start(self.toolbar, False, True)
self.widget.pack_start(
self.toolbar, expand=False, fill=True, padding=0)
viewport = gtk.Viewport()
viewport.set_shadow_type(gtk.SHADOW_NONE)
viewport = Gtk.Viewport()
viewport.set_shadow_type(Gtk.ShadowType.NONE)
viewport.add(self.widget_get())
viewport.show()
self.scrolledwindow = gtk.ScrolledWindow()
self.scrolledwindow.set_shadow_type(gtk.SHADOW_NONE)
self.scrolledwindow.set_policy(gtk.POLICY_AUTOMATIC,
gtk.POLICY_AUTOMATIC)
self.scrolledwindow = Gtk.ScrolledWindow()
self.scrolledwindow.set_shadow_type(Gtk.ShadowType.NONE)
self.scrolledwindow.set_policy(
Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
self.scrolledwindow.add(viewport)
self.scrolledwindow.show()
self.widget.pack_start(self.scrolledwindow)
self.widget.pack_start(
self.scrolledwindow, expand=True, fill=True, padding=0)
self.create_info_bar()
self.widget.pack_start(self.info_bar, False, True)
self.widget.pack_start(
self.info_bar, expand=False, fill=True, padding=0)
def make_title_bar(self):
self.title = title = gtk.Label()
title.modify_font(pango.FontDescription("bold 14"))
title.set_label(common.ellipsize(self.name, 80))
title.set_padding(10, 4)
title.set_alignment(0.0, 0.5)
tooltips = common.Tooltips()
self.title = title = Gtk.Label(
label=common.ellipsize(self.name, 80),
halign=Gtk.Align.START, margin=5,
ellipsize=Pango.EllipsizeMode.END)
tooltips.set_tip(title, self.name)
title.set_size_request(0, -1) # Allow overflow
title.set_max_width_chars(1)
title.set_ellipsize(pango.ELLIPSIZE_END)
title.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse("#000000"))
title.show()
menu = Gtk.MenuButton.new()
@@ -216,34 +217,30 @@ class TabContent(InfoBar):
menu.set_popup(self.set_menu_form())
menu.show()
self.status_label = gtk.Label()
self.status_label.set_padding(5, 4)
self.status_label.set_alignment(0.0, 0.5)
self.status_label = Gtk.Label(
margin=5, halign=Gtk.Align.END)
widget_class(self.status_label, 'status', True)
self.status_label.show()
hbox = gtk.HBox()
hbox.pack_start(title, expand=True, fill=True)
hbox.pack_start(self.status_label, expand=False, fill=True)
hbox = Gtk.HBox()
hbox.pack_start(title, expand=True, fill=True, padding=0)
hbox.pack_start(self.status_label, expand=False, fill=True, padding=0)
hbox.show()
frame = gtk.Frame()
frame.set_shadow_type(gtk.SHADOW_ETCHED_IN)
frame = Gtk.Frame()
frame.set_shadow_type(Gtk.ShadowType.ETCHED_IN)
widget_class(frame, 'window-title', True)
frame.add(hbox)
frame.show()
eb = gtk.EventBox()
eb.add(frame)
eb.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse("#ffffff"))
eb.show()
frame_menu = gtk.Frame()
frame_menu.set_shadow_type(gtk.SHADOW_ETCHED_IN)
frame_menu = Gtk.Frame()
frame_menu.set_shadow_type(Gtk.ShadowType.ETCHED_IN)
frame_menu.add(menu)
frame_menu.show()
title_box = gtk.HBox()
title_box.pack_start(frame_menu, expand=False, fill=True)
title_box.pack_start(eb, expand=True, fill=True)
title_box = Gtk.HBox()
title_box.pack_start(frame_menu, expand=False, fill=True, padding=0)
title_box.pack_start(frame, expand=True, fill=True, padding=0)
title_box.show()
return title_box
@@ -255,27 +252,27 @@ class TabContent(InfoBar):
if not callback:
continue
if item.toggle:
toolitem = gtk.ToggleToolButton()
toolitem = Gtk.ToggleToolButton()
toolitem.connect('toggled', callback)
else:
toolitem = gtk.ToolButton()
toolitem = Gtk.ToolButton()
toolitem.connect('clicked', callback)
toolitem.set_icon_widget(
common.IconFactory.get_image(
item.icon_name, gtk.ICON_SIZE_LARGE_TOOLBAR))
item.icon_name, Gtk.IconSize.LARGE_TOOLBAR))
toolitem.set_label(item.label)
toolitem.set_use_underline(True)
self.tooltips.set_tip(toolitem, item.tooltip)
self.buttons[item.id] = toolitem
elif not item and previous:
toolitem = gtk.SeparatorToolItem()
toolitem = Gtk.SeparatorToolItem()
else:
continue
previous = item
toolbar.insert(toolitem, -1)
def set_menu_form(self):
menu_form = gtk.Menu()
menu_form = Gtk.Menu()
menu_form.set_accel_group(self.accel_group)
menu_form.set_accel_path('<tryton>/Form')
previous = None
@@ -284,19 +281,15 @@ class TabContent(InfoBar):
callback = getattr(self, 'sig_%s' % item.id, None)
if not callback:
continue
menuitem = gtk.ImageMenuItem(item.label, self.accel_group)
menuitem.set_use_underline(True)
menuitem = Gtk.MenuItem(
label=item.label,
use_underline=True)
menuitem.connect('activate', callback)
if item.icon_name:
menuitem.set_image(
common.IconFactory.get_image(
item.icon_name, gtk.ICON_SIZE_MENU))
if item.accel_path:
menuitem.set_accel_path(item.accel_path)
self.menu_buttons[item.id] = menuitem
elif not item and previous:
menuitem = gtk.SeparatorMenuItem()
menuitem = Gtk.SeparatorMenuItem()
else:
continue
previous = item
@@ -306,16 +299,16 @@ class TabContent(InfoBar):
return menu_form
def create_toolbar(self, toolbars):
gtktoolbar = gtk.Toolbar()
gtktoolbar = Gtk.Toolbar()
option = CONFIG['client.toolbar']
if option == 'default':
gtktoolbar.set_style(False)
elif option == 'both':
gtktoolbar.set_style(gtk.TOOLBAR_BOTH)
gtktoolbar.set_style(Gtk.ToolbarStyle.BOTH)
elif option == 'text':
gtktoolbar.set_style(gtk.TOOLBAR_TEXT)
gtktoolbar.set_style(Gtk.ToolbarStyle.TEXT)
elif option == 'icons':
gtktoolbar.set_style(gtk.TOOLBAR_ICONS)
gtktoolbar.set_style(Gtk.ToolbarStyle.ICONS)
self.create_base_toolbar(gtktoolbar)
return gtktoolbar
+10 -8
View File
@@ -1,13 +1,14 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
'Action'
import gtk
import gobject
import gettext
from gi.repository import GLib, Gtk
from tryton.gui.window.view_form.screen import Screen
import tryton.rpc as rpc
import tryton.common as common
from tryton.pyson import PYSONDecoder
import gettext
from tryton.signal_event import SignalEvent
from tryton.gui.window.win_form import WinForm
from tryton.common import RPCExecute, RPCException
@@ -60,13 +61,13 @@ class Action(SignalEvent):
search_value = PYSONDecoder(search_context).decode(
self.action['pyson_search_value'] or '[]')
self.widget = gtk.Frame()
self.widget = Gtk.Frame()
self.widget.set_border_width(0)
vbox = gtk.VBox(homogeneous=False, spacing=3)
vbox = Gtk.VBox(homogeneous=False, spacing=3)
self.widget.add(vbox)
self.title = gtk.Label()
self.title = Gtk.Label()
self.widget.set_label_widget(self.title)
self.widget.set_label_align(0.0, 0.5)
self.widget.show_all()
@@ -75,7 +76,8 @@ class Action(SignalEvent):
mode=self.action['view_mode'], context=self.context,
view_ids=view_ids, domain=self.domain,
search_value=search_value, row_activate=self.row_activate)
vbox.pack_start(self.screen.widget, expand=True, fill=True)
vbox.pack_start(
self.screen.widget, expand=True, fill=True, padding=0)
self.screen.signal_connect(self, 'record-message',
self._active_changed)
@@ -146,4 +148,4 @@ class Action(SignalEvent):
def display():
if self.screen.widget.props.window:
self.display()
gobject.idle_add(display)
GLib.idle_add(display)
+32 -27
View File
@@ -1,11 +1,12 @@
# 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 xml.dom.minidom
from gi.repository import Gtk
from tryton.gui.window.view_form.view.form import Container
from tryton.common import node_attributes, IconFactory
from tryton.common import node_attributes, IconFactory, get_align
from .action import Action
_ = gettext.gettext
@@ -48,26 +49,28 @@ class ViewBoard(object):
def _parse_image(self, node, container, attributes):
container.add(
IconFactory.get_image(attributes['name'], gtk.ICON_SIZE_DIALOG),
IconFactory.get_image(attributes['name'], Gtk.IconSize.DIALOG),
attributes)
def _parse_separator(self, node, container, attributes):
vbox = gtk.VBox()
vbox = Gtk.VBox()
if attributes.get('string'):
label = gtk.Label(attributes['string'])
label.set_alignment(float(attributes.get('xalign', 0.0)),
float(attributes.get('yalign', 0.5)))
vbox.pack_start(label)
vbox.pack_start(gtk.HSeparator())
label = Gtk.Label(label=attributes['string'])
label.set_halign(get_align(attributes.get('xalign', 0.0)))
label.set_valign(get_align(attributes.get('yalign', 0.5)))
vbox.pack_start(
label, expand=True, fill=True, padding=0)
vbox.pack_start(
Gtk.HSeparator(), expand=True, fill=True, padding=0)
container.add(vbox, attributes)
def _parse_label(self, node, container, attributes):
if not attributes.get('string'):
container.add(None, attributes)
return
label = gtk.Label(attributes['string'])
label.set_alignment(float(attributes.get('xalign', 0.0)),
float(attributes.get('yalign', 0.5)))
label = Gtk.Label(label=attributes['string'])
label.set_halign(get_align(attributes.get('xalign', 0.0)))
label.set_halign(get_align(attributes.get('yalign', 0.5)))
label.set_angle(int(attributes.get('angle', 0)))
attributes.setdefault('xexpand', 0)
container.add(label, attributes)
@@ -78,29 +81,31 @@ class ViewBoard(object):
def _parse_notebook(self, node, container, attributes):
attributes.setdefault('yexpand', True)
attributes.setdefault('yfill', True)
notebook = gtk.Notebook()
notebook = Gtk.Notebook()
notebook.set_scrollable(True)
container.add(notebook, attributes)
self.parse(node, notebook)
def _parse_page(self, node, notebook, attributes):
tab_box = gtk.HBox(spacing=3)
tab_box = Gtk.HBox(spacing=3)
if '_' not in attributes['string']:
attributes['string'] = '_' + attributes['string']
label = gtk.Label(attributes['string'])
label = Gtk.Label(label=attributes['string'])
label.set_use_underline(True)
tab_box.pack_start(label)
tab_box.pack_start(label, expand=True, fill=True, padding=0)
if 'icon' in attributes:
tab_box.pack_start(IconFactory.get_image(
attributes['icon'], gtk.ICON_SIZE_SMALL_TOOLBAR))
attributes['icon'], Gtk.IconSize.SMALL_TOOLBAR),
expand=True, fill=True, padding=0)
tab_box.show_all()
viewport = gtk.Viewport()
viewport.set_shadow_type(gtk.SHADOW_NONE)
scrolledwindow = gtk.ScrolledWindow()
scrolledwindow.set_shadow_type(gtk.SHADOW_NONE)
scrolledwindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
viewport = Gtk.Viewport()
viewport.set_shadow_type(Gtk.ShadowType.NONE)
scrolledwindow = Gtk.ScrolledWindow()
scrolledwindow.set_shadow_type(Gtk.ShadowType.NONE)
scrolledwindow.set_policy(
Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
scrolledwindow.add(viewport)
scrolledwindow.show_all()
notebook.append_page(scrolledwindow, tab_box)
@@ -110,10 +115,10 @@ class ViewBoard(object):
def _parse_group(self, node, container, attributes):
group = self.parse(node)
group.table.set_homogeneous(attributes.get('homogeneous', False))
frame = gtk.Frame()
frame = Gtk.Frame()
frame.set_label(attributes.get('string'))
if not attributes.get('string'):
frame.set_shadow_type(gtk.SHADOW_NONE)
frame.set_shadow_type(Gtk.ShadowType.NONE)
frame.set_border_width(0)
frame.add(group.table)
container.add(frame, attributes)
@@ -128,10 +133,10 @@ class ViewBoard(object):
self.parse(node, paned)
def _parse_hpaned(self, node, container, attributes):
self._parse_paned(node, container, attributes, gtk.HPaned)
self._parse_paned(node, container, attributes, Gtk.HPaned)
def _parse_vpaned(self, node, container, attributes):
self._parse_paned(node, container, attributes, gtk.VPaned)
self._parse_paned(node, container, attributes, Gtk.VPaned)
def _parse_child(self, node, paned, attributes):
container = self.parse(node)
+9 -10
View File
@@ -3,7 +3,6 @@
"Screen"
import copy
import functools
import gobject
import datetime
import calendar
import json
@@ -14,7 +13,7 @@ import gettext
import logging
from operator import itemgetter
import gtk
from gi.repository import GLib, Gtk
from tryton.gui.window.view_form.model.group import Group
from tryton.gui.window.view_form.view.screen_container import ScreenContainer
@@ -93,19 +92,19 @@ class Screen(SignalEvent):
yield widget
for widget in reversed(list(walk_descendants(context_widget))):
if isinstance(widget, gtk.Entry):
if isinstance(widget, Gtk.Entry):
widget.connect_after(
'activate', self.screen_container.activate)
elif isinstance(widget, gtk.CheckButton):
elif isinstance(widget, Gtk.CheckButton):
widget.connect_after(
'toggled', self.screen_container.activate)
def remove_bin(widget):
assert isinstance(widget, (gtk.ScrolledWindow, gtk.Viewport))
assert isinstance(widget, (Gtk.ScrolledWindow, Gtk.Viewport))
parent = widget.get_parent()
parent.remove(widget)
child = widget.get_child()
while isinstance(child, (gtk.ScrolledWindow, gtk.Viewport)):
while isinstance(child, (Gtk.ScrolledWindow, Gtk.Viewport)):
child = child.get_child()
child.get_parent().remove(child)
parent.add(child)
@@ -446,8 +445,8 @@ class Screen(SignalEvent):
unread_note = record.unread_note
self.signal('unread-note', unread_note)
# update attachment-count after 1 second
gobject.timeout_add(1000, self.update_attachment, record)
gobject.timeout_add(1000, self.update_note, record)
GLib.timeout_add(1000, self.update_attachment, record)
GLib.timeout_add(1000, self.update_note, record)
return True
current_record = property(__get_current_record, __set_current_record)
@@ -537,7 +536,7 @@ class Screen(SignalEvent):
self.screen_container.set(self.current_view.widget)
self.display()
# Postpone set of the cursor to ensure widgets are allocated
gobject.idle_add(self.set_cursor)
GLib.idle_add(self.set_cursor)
def load_view_to_load(self):
if len(self.view_to_load):
@@ -611,7 +610,7 @@ class Screen(SignalEvent):
self.current_record = record
self.display()
# Postpone set of the cursor to ensure widgets are allocated
gobject.idle_add(self.set_cursor, True)
GLib.idle_add(self.set_cursor, True)
return self.current_record
def new_model_position(self):
@@ -2,10 +2,11 @@
# this repository contains the full copyright notices and license terms.
from functools import wraps
import gtk
import datetime
import gettext
from gi.repository import Gtk
from tryton.common import node_attributes
from . import View
try:
@@ -38,7 +39,7 @@ class ViewCalendar(View):
self.widget = self.parse(xml)
def parse(self, node):
vbox = gtk.VBox()
vbox = Gtk.VBox()
if not Calendar_:
return vbox
fields = []
@@ -59,10 +60,10 @@ class ViewCalendar(View):
goocalendar.connect('day-pressed', self.on_day_pressed)
goocalendar.connect('day-activated', self.on_day_activated)
self.widgets['goocalendar'] = goocalendar
self.scroll = scrolledWindow = gtk.ScrolledWindow()
scrolledWindow.add_with_viewport(goocalendar)
vbox.pack_start(toolbar, False, False)
vbox.pack_start(scrolledWindow, True, True)
self.scroll = scrolledWindow = Gtk.ScrolledWindow()
scrolledWindow.add(goocalendar)
vbox.pack_start(toolbar, expand=False, fill=False, padding=0)
vbox.pack_start(scrolledWindow, expand=True, fill=True, padding=0)
return vbox
def on_page_changed(self, goocalendar, day, toolbar):
@@ -3,7 +3,8 @@
import datetime
import calendar
import gettext
import gtk
from gi.repository import Gdk, Gtk
from tryton.gui import Main
from tryton.common.datetime_ import popup_position, popup_show, popup_hide
@@ -11,23 +12,25 @@ from tryton.common.datetime_ import popup_position, popup_show, popup_hide
_ = gettext.gettext
class Toolbar(gtk.Toolbar):
class Toolbar(Gtk.Toolbar):
def __init__(self, goocalendar):
super(Toolbar, self).__init__()
self.goocalendar = goocalendar
self.accel_group = Main().accel_group
today_button = gtk.ToolButton()
today_button = Gtk.ToolButton()
today_button.set_label(_('Today'))
today_button.set_homogeneous(False)
today_button.connect("clicked", self.on_today_button_clicked)
today_button.add_accelerator("clicked", self.accel_group,
gtk.keysyms.t, gtk.gdk.MODIFIER_MASK, gtk.ACCEL_VISIBLE)
today_button.add_accelerator(
"clicked", self.accel_group, Gdk.KEY_t,
Gdk.ModifierType.MODIFIER_MASK, Gtk.AccelFlags.VISIBLE)
self.insert(today_button, -1)
arrow_left = gtk.Arrow(gtk.ARROW_LEFT, gtk.SHADOW_NONE)
go_back = gtk.ToolButton()
arrow_left = Gtk.Arrow(
arrow_type=Gtk.ArrowType.LEFT, shadow_type=Gtk.ShadowType.NONE)
go_back = Gtk.ToolButton()
go_back.set_icon_widget(arrow_left)
go_back.set_label(_("go back"))
go_back.set_expand(False)
@@ -35,15 +38,15 @@ class Toolbar(gtk.Toolbar):
go_back.connect("clicked", self.on_go_back_clicked)
self.insert(go_back, -1)
self.current_page_label = gtk.Label("")
self.current_page = gtk.ToggleToolButton()
self.current_page_label = Gtk.Label()
self.current_page = Gtk.ToggleToolButton()
self.current_page.set_label_widget(self.current_page_label)
self.current_page.connect("clicked", self.on_current_page_clicked)
self.insert(self.current_page, -1)
self.__cal_popup = gtk.Window(gtk.WINDOW_POPUP)
self.__cal_popup = Gtk.Window(type=Gtk.WindowType.POPUP)
self.__cal_popup.set_events(
self.__cal_popup.get_events() | gtk.gdk.KEY_PRESS_MASK)
self.__cal_popup.get_events() | Gdk.EventMask.KEY_PRESS_MASK)
self.__cal_popup.set_resizable(False)
self.__cal_popup.connect('delete-event', self.on_cal_popup_closed)
self.__cal_popup.connect(
@@ -51,15 +54,15 @@ class Toolbar(gtk.Toolbar):
self.__cal_popup.connect(
'button-press-event', self.on_cal_popup_button_pressed)
gtkcal = gtk.Calendar()
gtkcal = Gtk.Calendar()
gtkcal.connect('day-selected', self.on_gtkcal_day_selected)
gtkcal.connect(
'day-selected-double-click',
self.on_gtkcal_day_selected_double_click)
gtkcal.set_display_options(
gtk.CALENDAR_SHOW_HEADING |
gtk.CALENDAR_SHOW_WEEK_NUMBERS |
gtk.CALENDAR_SHOW_DAY_NAMES)
Gtk.CalendarDisplayOptions.SHOW_HEADING |
Gtk.CalendarDisplayOptions.SHOW_WEEK_NUMBERS |
Gtk.CalendarDisplayOptions.SHOW_DAY_NAMES)
gtkcal.set_no_show_all(True)
self.__cal_popup.add(gtkcal)
gtkcal.show()
@@ -67,8 +70,9 @@ class Toolbar(gtk.Toolbar):
self.goocalendar.connect('day-selected',
self.on_goocalendar_day_selected)
arrow_right = gtk.Arrow(gtk.ARROW_RIGHT, gtk.SHADOW_NONE)
go_forward = gtk.ToolButton()
arrow_right = Gtk.Arrow(
arrow_type=Gtk.ArrowType.RIGHT, shadow_type=Gtk.ShadowType.NONE)
go_forward = Gtk.ToolButton()
go_forward.set_icon_widget(arrow_right)
go_forward.set_label(_("go forward"))
go_forward.set_expand(False)
@@ -76,8 +80,9 @@ class Toolbar(gtk.Toolbar):
go_forward.connect("clicked", self.on_go_forward_clicked)
self.insert(go_forward, -1)
arrow_left = gtk.Arrow(gtk.ARROW_LEFT, gtk.SHADOW_NONE)
previous_year = gtk.ToolButton()
arrow_left = Gtk.Arrow(
arrow_type=Gtk.ArrowType.LEFT, shadow_type=Gtk.ShadowType.NONE)
previous_year = Gtk.ToolButton()
previous_year.set_icon_widget(arrow_left)
previous_year.set_label(_("previous year"))
previous_year.set_expand(False)
@@ -85,13 +90,14 @@ class Toolbar(gtk.Toolbar):
previous_year.connect("clicked", self.on_previous_year_clicked)
self.insert(previous_year, -1)
self.current_year_label = gtk.Label("")
current_year = gtk.ToolItem()
self.current_year_label = Gtk.Label()
current_year = Gtk.ToolItem()
current_year.add(self.current_year_label)
self.insert(current_year, -1)
arrow_right = gtk.Arrow(gtk.ARROW_RIGHT, gtk.SHADOW_NONE)
next_year = gtk.ToolButton()
arrow_right = Gtk.Arrow(
arrow_type=Gtk.ArrowType.RIGHT, shadow_type=Gtk.ShadowType.NONE)
next_year = Gtk.ToolButton()
next_year.set_icon_widget(arrow_right)
next_year.set_label(_("next year"))
next_year.set_expand(False)
@@ -99,25 +105,24 @@ class Toolbar(gtk.Toolbar):
next_year.connect("clicked", self.on_next_year_clicked)
self.insert(next_year, -1)
blank_widget = gtk.ToolItem()
blank_widget = Gtk.ToolItem()
blank_widget.set_expand(True)
self.insert(blank_widget, -1)
week_button = gtk.RadioToolButton()
week_button = Gtk.RadioToolButton()
week_button.set_label(_('Week View'))
week_button.connect("clicked", self.on_week_button_clicked)
week_button.add_accelerator("clicked", self.accel_group, gtk.keysyms.w,
gtk.gdk.MODIFIER_MASK, gtk.ACCEL_VISIBLE)
week_button.add_accelerator(
"clicked", self.accel_group, Gdk.KEY_w,
Gdk.ModifierType.MODIFIER_MASK, Gtk.AccelFlags.VISIBLE)
self.insert(week_button, -1)
if hasattr(gtk.RadioToolButton, 'new_from_widget'):
month_button = gtk.RadioToolButton.new_from_widget(week_button)
else:
month_button = gtk.RadioToolButton(week_button)
month_button.set_label_widget(gtk.Label(_('Month View')))
month_button = Gtk.RadioToolButton.new_from_widget(week_button)
month_button.set_label_widget(Gtk.Label(label=_('Month View')))
month_button.connect("clicked", self.on_month_button_clicked)
month_button.add_accelerator("clicked", self.accel_group,
gtk.keysyms.m, gtk.gdk.MODIFIER_MASK, gtk.ACCEL_VISIBLE)
month_button.add_accelerator(
"clicked", self.accel_group, Gdk.KEY_m,
Gdk.ModifierType.MODIFIER_MASK, Gtk.AccelFlags.VISIBLE)
self.insert(month_button, -1)
buttons = {
'month': month_button,
@@ -125,7 +130,7 @@ class Toolbar(gtk.Toolbar):
}
buttons[self.goocalendar.view].set_active(True)
self.update_displayed_date()
self.set_style(gtk.TOOLBAR_ICONS)
self.set_style(Gtk.ToolbarStyle.ICONS)
def update_displayed_date(self):
date = self.goocalendar.selected_date
@@ -160,17 +165,17 @@ class Toolbar(gtk.Toolbar):
return True
def on_cal_popup_key_pressed(self, widget, event):
if event.keyval != gtk.keysyms.Escape:
if event.keyval != Gdk.KEY_Escape:
return False
widget.stop_emission('key-press-event')
widget.stop_emission_by_name('key-press-event')
self.cal_popup_hide()
return True
def on_cal_popup_button_pressed(self, widget, event):
child = event.window
if child != widget.window:
if child != widget.props.window:
while child:
if child == widget.window:
if child == widget.props.window:
return False
child = child.get_parent()
self.cal_popup_hide()
@@ -189,7 +194,7 @@ class Toolbar(gtk.Toolbar):
self.cal_popup_hide()
def on_goocalendar_day_selected(self, goocalendar, day):
# months go from 0 to 11 in gtk.Calendar instead of 1 to 12
# months go from 0 to 11 in Gtk.Calendar instead of 1 to 12
new_date = self.goocalendar.selected_date
self.gtkcal.select_month(new_date.month - 1, new_date.year)
self.gtkcal.handler_block_by_func(self.on_gtkcal_day_selected)
+47 -43
View File
@@ -1,18 +1,19 @@
# 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 operator
import gtk
import gettext
from collections import defaultdict
from gi.repository import Gtk
from . import View
from tryton.common.focus import (get_invisible_ancestor, find_focused_child,
next_focus_widget, find_focusable_child, find_first_focus_widget)
from tryton.common import Tooltips, node_attributes, IconFactory
from tryton.common import Tooltips, node_attributes, IconFactory, get_align
from tryton.common.underline import set_underline
from tryton.common.button import Button
from tryton.config import CONFIG
from .form_gtk.calendar import Date, Time, DateTime
from .form_gtk.calendar_ import Date, Time, DateTime
from .form_gtk.float import Float
from .form_gtk.integer import Integer
from .form_gtk.selection import Selection
@@ -56,7 +57,7 @@ class Container(object):
if col < 0:
col = 0
self.col = col
self.table = gtk.Table(1, col)
self.table = Gtk.Table(n_rows=1, n_columns=col)
self.table.set_homogeneous(homogeneous)
self.table.set_col_spacings(0)
self.table.set_row_spacings(0)
@@ -95,21 +96,21 @@ class Container(object):
yopt = 0
if attributes.get('yexpand'):
yopt = gtk.EXPAND
yopt = Gtk.AttachOptions.EXPAND
if attributes.get('yfill'):
if yopt:
yopt |= gtk.FILL
yopt |= Gtk.AttachOptions.FILL
else:
yopt = gtk.FILL
yopt = Gtk.AttachOptions.FILL
xopt = 0
if attributes.get('xexpand', True):
xopt = gtk.EXPAND
xopt = Gtk.AttachOptions.EXPAND
if attributes.get('xfill', True):
if xopt:
xopt |= gtk.FILL
xopt |= Gtk.AttachOptions.FILL
else:
xopt = gtk.FILL
xopt = Gtk.AttachOptions.FILL
if attributes.get('help'):
self.tooltips.set_tip(widget, attributes['help'])
@@ -125,7 +126,7 @@ class Container(object):
class VContainer(Container):
def __init__(self, col=1, homogeneous=False):
self.col = 1
self.table = gtk.VBox()
self.table = Gtk.VBox()
self.table.set_homogeneous(homogeneous)
def add_row(self):
@@ -145,7 +146,7 @@ class VContainer(Container):
class HContainer(Container):
def __init__(self, col=0, homogeneous=False):
self.col = 0
self.table = gtk.HBox()
self.table = Gtk.HBox()
self.table.set_homogeneous(homogeneous)
def add_row(self):
@@ -175,18 +176,19 @@ class ViewForm(View):
container = self.parse(xml)
vbox = gtk.VBox()
vp = gtk.Viewport()
vp.set_shadow_type(gtk.SHADOW_NONE)
vbox = Gtk.VBox()
vp = Gtk.Viewport()
vp.set_shadow_type(Gtk.ShadowType.NONE)
vp.add(container.table)
self.scroll = scroll = gtk.ScrolledWindow()
self.scroll = scroll = Gtk.ScrolledWindow()
scroll.add(vp)
scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
scroll.set_placement(gtk.CORNER_TOP_LEFT)
viewport = gtk.Viewport()
viewport.set_shadow_type(gtk.SHADOW_ETCHED_IN)
scroll.set_policy(
Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
scroll.set_placement(Gtk.CornerType.TOP_LEFT)
viewport = Gtk.Viewport()
viewport.set_shadow_type(Gtk.ShadowType.ETCHED_IN)
viewport.add(scroll)
vbox.pack_start(viewport, expand=True, fill=True)
vbox.pack_start(viewport, expand=True, fill=True, padding=0)
self.widget = vbox
self._viewport = vp
@@ -238,12 +240,12 @@ class ViewForm(View):
attributes[attr] = field.attrs[attr]
vbox = VBox(attrs=attributes)
if attributes.get('string'):
label = Label(attributes['string'], attrs=attributes)
label.set_alignment(float(attributes.get('xalign', 0.0)),
float(attributes.get('yalign', 0.5)))
vbox.pack_start(label)
label = Label(label=attributes['string'], attrs=attributes)
label.set_halign(get_align(attributes.get('xalign', 0.0)))
label.set_valign(get_align(attributes.get('yalign', 0.5)))
vbox.pack_start(label, expand=True, fill=True, padding=0)
self.state_widgets.append(label)
vbox.pack_start(gtk.HSeparator())
vbox.pack_start(Gtk.HSeparator(), expand=True, fill=True, padding=0)
self.state_widgets.append(vbox)
container.add(vbox, attributes)
@@ -260,9 +262,9 @@ class ViewForm(View):
if CONFIG['client.modepda']:
attributes['xalign'] = 0.0
label = Label(attributes.get('string', ''), attrs=attributes)
label.set_alignment(float(attributes.get('xalign', 1.0)),
float(attributes.get('yalign', 0.5)))
label = Label(label=attributes.get('string', ''), attrs=attributes)
label.set_halign(get_align(attributes.get('xalign', 1.0)))
label.set_valign(get_align(attributes.get('yalign', 0.5)))
label.set_angle(int(attributes.get('angle', 0)))
attributes.setdefault('xexpand', 0)
self.state_widgets.append(label)
@@ -307,7 +309,7 @@ class ViewForm(View):
self.parse(node, notebook)
def _parse_page(self, node, notebook, attributes):
tab_box = gtk.HBox(spacing=3)
tab_box = Gtk.HBox(spacing=3)
if 'name' in attributes:
field = self.group.fields[attributes['name']]
if attributes['name'] == self.screen.exclude_field:
@@ -315,20 +317,22 @@ class ViewForm(View):
for attr in ('states', 'string'):
if attr not in attributes and attr in field.attrs:
attributes[attr] = field.attrs[attr]
label = gtk.Label(set_underline(attributes['string']))
label = Gtk.Label(label=set_underline(attributes['string']))
label.set_use_underline(True)
if 'icon' in attributes:
tab_box.pack_start(IconFactory.get_image(
attributes['icon'], gtk.ICON_SIZE_SMALL_TOOLBAR))
tab_box.pack_start(label)
attributes['icon'], Gtk.IconSize.SMALL_TOOLBAR),
expand=True, fill=True, padding=0)
tab_box.pack_start(label, expand=True, fill=True, padding=0)
tab_box.show_all()
viewport = gtk.Viewport()
viewport.set_shadow_type(gtk.SHADOW_NONE)
viewport = Gtk.Viewport()
viewport.set_shadow_type(Gtk.ShadowType.NONE)
scrolledwindow = ScrolledWindow(attrs=attributes)
scrolledwindow.set_shadow_type(gtk.SHADOW_NONE)
scrolledwindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
scrolledwindow.set_shadow_type(Gtk.ShadowType.NONE)
scrolledwindow.set_policy(
Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
scrolledwindow.add(viewport)
scrolledwindow.show_all()
self.state_widgets.append(scrolledwindow)
@@ -388,12 +392,12 @@ class ViewForm(View):
can_expand = attributes.get('expandable')
if can_expand:
widget = Expander(attributes.get('string'), attrs=attributes)
widget = Expander(label=attributes.get('string'), attrs=attributes)
widget.add(group.table)
widget.set_expanded(can_expand == '1')
self.expandables.append(widget)
else:
widget = Frame(attributes.get('string'), attrs=attributes)
widget = Frame(label=attributes.get('string'), attrs=attributes)
widget.add(group.table)
self.state_widgets.append(widget)
@@ -409,10 +413,10 @@ class ViewForm(View):
self.parse(node, paned)
def _parse_hpaned(self, node, container, attributes):
self._parse_paned(node, container, attributes, gtk.HPaned)
self._parse_paned(node, container, attributes, Gtk.HPaned)
def _parse_vpaned(self, node, container, attributes):
self._parse_paned(node, container, attributes, gtk.VPaned)
self._parse_paned(node, container, attributes, Gtk.VPaned)
def _parse_child(self, node, paned, attributes):
container = self.parse(node)
@@ -479,7 +483,7 @@ class ViewForm(View):
for widget in widgets:
if (not focused_widget
or widget.widget.is_focus()
or (isinstance(widget.widget, gtk.Container)
or (isinstance(widget.widget, Gtk.Container)
and widget.widget.get_focus_child())):
widget.set_value()
@@ -495,7 +499,7 @@ class ViewForm(View):
for w in widgets)
def get_buttons(self):
return [b for b in self.state_widgets if isinstance(b, gtk.Button)]
return [b for b in self.state_widgets if isinstance(b, Gtk.Button)]
def reset(self):
record = self.record
@@ -1,10 +1,12 @@
# 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 urllib.request import urlopen
from urllib.parse import urlparse, unquote
from gi.repository import Gdk, Gtk
from tryton.common import common
from tryton.common import file_selection, Tooltips, file_open, file_write
from tryton.common.entry_position import reset_position
@@ -22,38 +24,39 @@ class BinaryMixin(Widget):
def toolbar(self):
'Return HBox with the toolbar'
hbox = gtk.HBox(spacing=0)
hbox = Gtk.HBox(spacing=0)
tooltips = Tooltips()
self.but_save_as = gtk.Button()
self.but_save_as = Gtk.Button()
self.but_save_as.set_image(common.IconFactory.get_image(
'tryton-save', gtk.ICON_SIZE_SMALL_TOOLBAR))
self.but_save_as.set_relief(gtk.RELIEF_NONE)
'tryton-save', Gtk.IconSize.SMALL_TOOLBAR))
self.but_save_as.set_relief(Gtk.ReliefStyle.NONE)
self.but_save_as.connect('clicked', self.save_as)
tooltips.set_tip(self.but_save_as, _('Save As...'))
hbox.pack_start(self.but_save_as, expand=False, fill=False)
hbox.pack_start(self.but_save_as, expand=False, fill=False, padding=0)
self.but_select = gtk.Button()
self.but_select = Gtk.Button()
self.but_select.set_image(common.IconFactory.get_image(
'tryton-search', gtk.ICON_SIZE_SMALL_TOOLBAR))
self.but_select.set_relief(gtk.RELIEF_NONE)
'tryton-search', Gtk.IconSize.SMALL_TOOLBAR))
self.but_select.set_relief(Gtk.ReliefStyle.NONE)
self.but_select.connect('clicked', self.select)
target_entry = gtk.TargetEntry.new('text/uri-list', 0, 0)
self.but_select.drag_dest_set(gtk.DEST_DEFAULT_ALL, [
target_entry = Gtk.TargetEntry.new('text/uri-list', 0, 0)
self.but_select.drag_dest_set(Gtk.DestDefaults.ALL, [
target_entry,
], gtk.gdk.ACTION_MOVE | gtk.gdk.ACTION_COPY)
],
Gdk.DragAction.MOVE | Gdk.DragAction.COPY)
self.but_select.connect(
'drag-data-received', self.select_drag_data_received)
tooltips.set_tip(self.but_select, _('Select...'))
hbox.pack_start(self.but_select, expand=False, fill=False)
hbox.pack_start(self.but_select, expand=False, fill=False, padding=0)
self.but_clear = gtk.Button()
self.but_clear = Gtk.Button()
self.but_clear.set_image(common.IconFactory.get_image(
'tryton-clear', gtk.ICON_SIZE_SMALL_TOOLBAR))
self.but_clear.set_relief(gtk.RELIEF_NONE)
'tryton-clear', Gtk.IconSize.SMALL_TOOLBAR))
self.but_clear.set_relief(Gtk.ReliefStyle.NONE)
self.but_clear.connect('clicked', self.clear)
tooltips.set_tip(self.but_clear, _('Clear'))
hbox.pack_start(self.but_clear, expand=False, fill=False)
hbox.pack_start(self.but_clear, expand=False, fill=False, padding=0)
tooltips.enable()
return hbox
@@ -64,7 +67,7 @@ class BinaryMixin(Widget):
@property
def filters(self):
filter_all = gtk.FileFilter()
filter_all = Gtk.FileFilter()
filter_all.set_name(_('All files'))
filter_all.add_pattern("*")
return [filter_all]
@@ -130,7 +133,7 @@ class BinaryMixin(Widget):
if self.filename_field:
filename = self.filename_field.get(self.record)
filename = file_selection(_('Save As...'), filename=filename,
action=gtk.FILE_CHOOSER_ACTION_SAVE)
action=Gtk.FileChooserAction.SAVE)
if filename:
with open(filename, 'wb') as fp:
fp.write(self.get_data())
@@ -147,26 +150,28 @@ class Binary(BinaryMixin, Widget):
def __init__(self, view, attrs):
super(Binary, self).__init__(view, attrs)
self.widget = gtk.HBox(spacing=0)
self.wid_size = gtk.Entry()
self.widget = Gtk.HBox(spacing=0)
self.wid_size = Gtk.Entry()
self.wid_size.set_width_chars(self.default_width_chars)
self.wid_size.set_alignment(1.0)
self.wid_size.props.sensitive = False
if self.filename and attrs.get('filename_visible'):
self.wid_text = gtk.Entry()
self.wid_text = Gtk.Entry()
self.wid_text.set_property('activates_default', True)
self.wid_text.connect('focus-out-event',
lambda x, y: self._focus_out())
self.wid_text.connect_after('key_press_event', self.sig_key_press)
self.wid_text.connect('icon-press', self.sig_icon_press)
self.widget.pack_start(self.wid_text, expand=True, fill=True)
self.widget.pack_start(
self.wid_text, expand=True, fill=True, padding=0)
else:
self.wid_text = None
self.mnemonic_widget = self.wid_text
self.widget.pack_start(self.wid_size, expand=not self.filename,
fill=True)
self.widget.pack_start(
self.wid_size, expand=not self.filename, fill=True, padding=0)
self.widget.pack_start(self.toolbar(), expand=False, fill=False)
self.widget.pack_start(
self.toolbar(), expand=False, fill=False, padding=0)
def _readonly_set(self, value):
self.but_select.set_sensitive(not value)
@@ -180,10 +185,10 @@ class Binary(BinaryMixin, Widget):
def sig_key_press(self, widget, event, *args):
editable = self.wid_text and self.wid_text.get_editable()
if event.keyval == gtk.keysyms.F3 and editable:
if event.keyval == Gdk.KEY_F3 and editable:
self.sig_new(widget)
return True
elif event.keyval == gtk.keysyms.F2:
elif event.keyval == Gdk.KEY_F2:
if self.filename:
self.sig_open(widget)
else:
@@ -192,7 +197,7 @@ class Binary(BinaryMixin, Widget):
return False
def sig_icon_press(self, widget, icon_pos, event):
if icon_pos == gtk.ENTRY_ICON_PRIMARY:
if icon_pos == Gtk.EntryIconPosition.PRIMARY:
self.open_()
def display(self):
@@ -216,10 +221,10 @@ class Binary(BinaryMixin, Widget):
icon, tooltip = 'tryton-open', _("Open...")
else:
icon, tooltip = None, ''
pos = gtk.ENTRY_ICON_PRIMARY
pos = Gtk.EntryIconPosition.PRIMARY
if icon:
pixbuf = common.IconFactory.get_pixbuf(
icon, gtk.ICON_SIZE_MENU)
icon, Gtk.IconSize.MENU)
else:
pixbuf = None
self.wid_text.set_icon_from_pixbuf(pos, pixbuf)
@@ -1,11 +1,9 @@
# 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 datetime
import gtk
import gettext
import gobject
from gi.repository import GLib, Gtk
from .widget import Widget
from tryton import common
@@ -21,7 +19,7 @@ class Date(Widget):
def __init__(self, view, attrs, _entry=DateEntry):
super(Date, self).__init__(view, attrs)
self.widget = gtk.HBox()
self.widget = Gtk.HBox()
self.entry = self.mnemonic_widget = add_operators(_entry())
self.real_entry.set_property('activates_default', True)
self.real_entry.connect('key_press_event', self.sig_key_press)
@@ -29,7 +27,7 @@ class Date(Widget):
self.real_entry.connect('changed', lambda _: self.send_modified())
self.real_entry.connect('focus-out-event',
lambda x, y: self._focus_out())
self.widget.pack_start(self.entry, expand=False, fill=False)
self.widget.pack_start(self.entry, expand=False, fill=False, padding=0)
@property
def real_entry(self):
@@ -37,7 +35,7 @@ class Date(Widget):
def _set_editable(self, value):
self.entry.set_editable(value)
self.entry.set_icon_sensitive(gtk.ENTRY_ICON_PRIMARY, value)
self.entry.set_icon_sensitive(Gtk.EntryIconPosition.PRIMARY, value)
def _readonly_set(self, value):
self._set_editable(not value)
@@ -122,18 +120,18 @@ class Time(Date):
# Only when changed from pop list
if not combobox.get_child().has_focus():
# Must be deferred because it triggers a display of the form
gobject.idle_add(focus_out)
GLib.idle_add(focus_out)
class DateTime(Date):
def __init__(self, view, attrs):
Widget.__init__(self, view, attrs)
self.widget = gtk.HBox()
self.widget = Gtk.HBox()
self.entry = self.mnemonic_widget = DateTimeEntry()
for child in self.entry.get_children():
add_operators(child)
if isinstance(child, gtk.ComboBoxEntry):
if isinstance(child, Gtk.ComboBox):
child.set_focus_chain([child.get_child()])
child = child.get_child()
child.set_property('activates_default', True)
@@ -141,7 +139,7 @@ class DateTime(Date):
child.connect('activate', self.sig_activate)
child.connect('changed', lambda _: self.send_modified())
child.connect('focus-out-event', lambda x, y: self._focus_out())
self.widget.pack_start(self.entry, expand=False, fill=False)
self.widget.pack_start(self.entry, expand=False, fill=False, padding=0)
@classmethod
def cast(cls, value):
@@ -149,10 +147,10 @@ class DateTime(Date):
def _set_editable(self, value):
for child in self.entry.get_children():
if isinstance(child, gtk.Entry):
if isinstance(child, Gtk.Entry):
child.set_editable(value)
child.set_icon_sensitive(gtk.ENTRY_ICON_PRIMARY, value)
elif isinstance(child, gtk.ComboBoxEntry):
child.set_icon_sensitive(Gtk.EntryIconPosition.PRIMARY, value)
elif isinstance(child, Gtk.ComboBox):
child.set_sensitive(value)
def set_format(self):
@@ -2,8 +2,8 @@
# this repository contains the full copyright notices and license terms.
import gettext
import gobject
import gtk
from gi.repository import GLib, Gtk
from .widget import Widget, TranslateMixin
from tryton.common import Tooltips, IconFactory
from tryton.common.entry_position import reset_position
@@ -19,10 +19,10 @@ class Char(Widget, TranslateMixin, PopdownMixin):
def __init__(self, view, attrs):
super(Char, self).__init__(view, attrs)
self.widget = gtk.HBox()
self.widget = Gtk.HBox()
self.autocomplete = bool(attrs.get('autocomplete'))
if self.autocomplete:
self.entry = gtk.ComboBoxEntry()
self.entry = Gtk.ComboBox(has_entry=True)
selection_shortcuts(self.entry)
focus_entry = self.entry.get_child()
self.set_popdown([], self.entry)
@@ -30,9 +30,9 @@ class Char(Widget, TranslateMixin, PopdownMixin):
self.entry.connect('move-active', self._move_active)
self.entry.connect(
'scroll-event',
lambda c, e: c.emit_stop_by_name('scroll-event'))
lambda c, e: c.stop_emission_by_name('scroll-event'))
else:
self.entry = gtk.Entry()
self.entry = Gtk.Entry()
focus_entry = self.entry
self.mnemonic_widget = focus_entry
@@ -43,16 +43,16 @@ class Char(Widget, TranslateMixin, PopdownMixin):
expand, fill = True, True
if attrs.get('size'):
expand, fill = False, False
self.widget.pack_start(self.entry, expand=expand, fill=fill)
self.widget.pack_start(self.entry, expand=expand, fill=fill, padding=0)
if attrs.get('translate'):
self.entry.set_icon_from_pixbuf(
gtk.ENTRY_ICON_SECONDARY,
IconFactory.get_pixbuf('tryton-translate', gtk.ICON_SIZE_MENU))
Gtk.EntryIconPosition.SECONDARY,
IconFactory.get_pixbuf('tryton-translate', Gtk.IconSize.MENU))
self.entry.connect('icon-press', self.translate)
def translate_widget(self):
entry = gtk.Entry()
entry = Gtk.Entry()
entry.set_property('activates_default', True)
if self.record:
field_size = self.record.expr_eval(self.attrs.get('size'))
@@ -78,7 +78,7 @@ class Char(Widget, TranslateMixin, PopdownMixin):
# Only when changed from pop list
if not combobox.get_child().has_focus():
# Must be deferred because it triggers a display of the form
gobject.idle_add(focus_out)
GLib.idle_add(focus_out)
@property
def modified(self):
@@ -141,10 +141,13 @@ class Char(Widget, TranslateMixin, PopdownMixin):
def _move_active(self, combobox, scroll_type):
if not combobox.get_child().get_editable():
combobox.emit_stop_by_name('move-active')
combobox.stop_emission_by_name('move-active')
def _readonly_set(self, value):
sensitivity = {True: gtk.SENSITIVITY_OFF, False: gtk.SENSITIVITY_AUTO}
sensitivity = {
True: Gtk.SensitivityType.OFF,
False: Gtk.SensitivityType.AUTO,
}
super(Char, self)._readonly_set(value)
if self.autocomplete:
entry_editable = self.entry.get_child()
@@ -164,10 +167,11 @@ class Password(Char):
super(Password, self).__init__(view, attrs)
self.entry.props.visibility = False
self.visibility_checkbox = gtk.CheckButton()
self.visibility_checkbox = Gtk.CheckButton()
self.visibility_checkbox.connect('toggled', self.toggle_visibility)
Tooltips().set_tip(self.visibility_checkbox, _('Show plain text'))
self.widget.pack_start(self.visibility_checkbox, expand=False)
self.widget.pack_start(
self.visibility_checkbox, expand=False, fill=True, padding=0)
def _readonly_set(self, value):
super(Char, self)._readonly_set(value)
@@ -1,9 +1,11 @@
# 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 .widget import Widget
import gettext
from gi.repository import Gtk
from .widget import Widget
_ = gettext.gettext
@@ -11,7 +13,7 @@ class CheckBox(Widget):
def __init__(self, view, attrs):
super(CheckBox, self).__init__(view, attrs)
self.widget = self.mnemonic_widget = gtk.CheckButton()
self.widget = self.mnemonic_widget = Gtk.CheckButton()
self.widget.connect('focus-out-event', lambda x, y: self._focus_out())
self.widget.connect_after('toggled', self.sig_activate)
@@ -2,13 +2,13 @@
# repository contains the full copyright notices and license terms.
import operator
import gobject
import gtk
import locale
import decimal
import gettext
from decimal import Decimal
from gi.repository import GLib, GObject, Gtk
from .widget import Widget
from .integer import IntegerMixin
from .float import FloatMixin
@@ -40,7 +40,7 @@ class DictEntry(object):
self.widget = self.create_widget()
def create_widget(self):
widget = gtk.Entry()
widget = Gtk.Entry()
widget.connect('key-press-event', self.parent_widget.send_modified)
widget.connect('focus-out-event',
lambda w, e: self.parent_widget._focus_out())
@@ -65,7 +65,7 @@ class DictEntry(object):
class DictBooleanEntry(DictEntry):
def create_widget(self):
widget = gtk.CheckButton()
widget = Gtk.CheckButton()
widget.connect('toggled', self.parent_widget.sig_activate)
widget.connect('focus-out-event', lambda w, e:
self.parent_widget._focus_out())
@@ -91,7 +91,7 @@ class DictSelectionEntry(DictEntry):
fill = False
def create_widget(self):
widget = gtk.ComboBoxEntry()
widget = Gtk.ComboBox(has_entry=True)
# customizing entry
child = widget.get_child()
@@ -104,11 +104,12 @@ class DictSelectionEntry(DictEntry):
widget.connect('notify::active',
lambda w, e: self.parent_widget._focus_out())
widget.connect(
'scroll-event', lambda c, e: c.emit_stop_by_name('scroll-event'))
'scroll-event',
lambda c, e: c.stop_emission_by_name('scroll-event'))
selection_shortcuts(widget)
# setting completion and selection
model = gtk.ListStore(gobject.TYPE_STRING)
model = Gtk.ListStore(GObject.TYPE_STRING)
model.append(('',))
self._selection = {'': None}
width = 10
@@ -123,7 +124,7 @@ class DictSelectionEntry(DictEntry):
widget.set_model(model)
widget.set_text_column(0)
child.set_width_chars(width)
completion = gtk.EntryCompletion()
completion = Gtk.EntryCompletion()
completion.set_inline_selection(True)
completion.set_model(model)
child.set_completion(completion)
@@ -293,28 +294,28 @@ class DictWidget(Widget):
self.buttons = {}
self.rows = {}
self.widget = gtk.Frame()
label = gtk.Label(set_underline(attrs.get('string', '')))
self.widget = Gtk.Frame()
label = Gtk.Label(label=set_underline(attrs.get('string', '')))
label.set_use_underline(True)
self.widget.set_label_widget(label)
self.widget.set_shadow_type(gtk.SHADOW_OUT)
self.widget.set_shadow_type(Gtk.ShadowType.OUT)
vbox = gtk.VBox()
vbox = Gtk.VBox()
self.widget.add(vbox)
self.table = gtk.Table(1, 3, homogeneous=False)
self.table = Gtk.Table(n_rows=1, n_columns=3, homogeneous=False)
self.table.set_col_spacings(0)
self.table.set_row_spacings(0)
self.table.set_border_width(0)
vbox.pack_start(self.table, expand=True, fill=True)
vbox.pack_start(self.table, expand=True, fill=True, padding=0)
hbox = gtk.HBox()
hbox = Gtk.HBox()
hbox.set_border_width(2)
self.wid_text = gtk.Entry()
self.wid_text = Gtk.Entry()
self.wid_text.set_placeholder_text(_('Search'))
self.wid_text.props.width_chars = 13
self.wid_text.connect('activate', self._sig_activate)
hbox.pack_start(self.wid_text, expand=True, fill=True)
hbox.pack_start(self.wid_text, expand=True, fill=True, padding=0)
label.set_mnemonic_widget(self.wid_text)
if int(self.attrs.get('completion', 1)):
@@ -326,14 +327,14 @@ class DictWidget(Widget):
else:
self.wid_completion = None
self.but_add = gtk.Button()
self.but_add = Gtk.Button()
self.but_add.connect('clicked', self._sig_add)
self.but_add.add(IconFactory.get_image(
'tryton-add', gtk.ICON_SIZE_SMALL_TOOLBAR))
self.but_add.set_relief(gtk.RELIEF_NONE)
hbox.pack_start(self.but_add, expand=False, fill=False)
self.but_add.add(
IconFactory.get_image('tryton-add', Gtk.IconSize.SMALL_TOOLBAR))
self.but_add.set_relief(Gtk.ReliefStyle.NONE)
hbox.pack_start(self.but_add, expand=False, fill=False, padding=0)
hbox.set_focus_chain([self.wid_text])
vbox.pack_start(hbox, expand=True, fill=True)
vbox.pack_start(hbox, expand=True, fill=True, padding=0)
self.tooltips = Tooltips()
self.tooltips.set_tip(self.but_add, _('Add value'))
@@ -347,10 +348,10 @@ class DictWidget(Widget):
return self.wid_text
def _new_remove_btn(self):
but_remove = gtk.Button()
but_remove.add(IconFactory.get_image(
'tryton-remove', gtk.ICON_SIZE_SMALL_TOOLBAR))
but_remove.set_relief(gtk.RELIEF_NONE)
but_remove = Gtk.Button()
but_remove.add(
IconFactory.get_image('tryton-remove', Gtk.IconSize.SMALL_TOOLBAR))
but_remove.set_relief(Gtk.ReliefStyle.NONE)
return but_remove
def _sig_activate(self, *args):
@@ -382,7 +383,7 @@ class DictWidget(Widget):
if not focus:
# Use idle add because it can be called from the callback
# of WinSearch while the popup is still there
gobject.idle_add(self.fields[key_name].widget.grab_focus)
GLib.idle_add(self.fields[key_name].widget.grab_focus)
focus = True
def _sig_remove(self, button, key, modified=True):
@@ -432,32 +433,37 @@ class DictWidget(Widget):
key_schema = self.field.keys[key]
self.fields[key] = DICT_ENTRIES[key_schema['type_']](key, self)
field = self.fields[key]
alignment = gtk.Alignment(
float(self.attrs.get('xalign', 0.0)),
float(self.attrs.get('yalign', 0.5)),
float(self.attrs.get('xexpand', 1.0)),
float(self.attrs.get('yexpand', 1.0)))
hbox = gtk.HBox()
hbox.pack_start(field.widget, expand=field.expand, fill=field.fill)
alignment = Gtk.Alignment()
alignment.props.xalign = float(self.attrs.get('xalign', 0.0))
alignment.props.yalign = float(self.attrs.get('yalign', 0.5))
alignment.props.xscale = float(self.attrs.get('xexpand', 1.0))
alignment.props.yscale = float(self.attrs.get('yexpand', 1.0))
hbox = Gtk.HBox()
hbox.pack_start(
field.widget, expand=field.expand, fill=field.fill, padding=0)
alignment.add(hbox)
n_rows = self.table.props.n_rows
self.table.resize(n_rows + 1, 3)
text = key_schema['string'] + _(':')
label = gtk.Label(set_underline(text))
label.set_use_underline(True)
label.set_alignment(1., .5)
self.table.attach(label, 0, 1, n_rows - 1, n_rows,
xoptions=gtk.FILL, yoptions=False, xpadding=2)
label = Gtk.Label(
label=set_underline(text),
use_underline=True, halign=Gtk.Align.START)
self.table.attach(
label, 0, 1, n_rows - 1, n_rows,
xoptions=Gtk.AttachOptions.FILL, xpadding=2, yoptions=False)
label.set_mnemonic_widget(field.widget)
label.show()
self.table.attach(alignment, 1, 2, n_rows - 1, n_rows,
xoptions=gtk.FILL | gtk.EXPAND, yoptions=False, xpadding=2)
self.table.attach(
alignment, 1, 2, n_rows - 1, n_rows,
xoptions=Gtk.AttachOptions.FILL | Gtk.AttachOptions.EXPAND,
xpadding=2, yoptions=False)
alignment.show_all()
remove_but = self._new_remove_btn()
self.tooltips.set_tip(remove_but, _('Remove "%s"') %
key_schema['string'])
self.table.attach(remove_but, 2, 3, n_rows - 1, n_rows,
xoptions=gtk.FILL, yoptions=False, xpadding=2)
self.table.attach(
remove_but, 2, 3, n_rows - 1, n_rows,
xoptions=Gtk.AttachOptions.FILL, xpadding=2, yoptions=False)
remove_but.connect('clicked', self._sig_remove, key)
remove_but.show_all()
self.rows[key] = [label, alignment, remove_but]
@@ -1,7 +1,9 @@
# 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 locale
from gi.repository import Gdk
from .integer import Integer, IntegerMixin
@@ -22,16 +24,16 @@ class FloatMixin(IntegerMixin):
try:
value = locale.atof(new_value)
except ValueError:
entry.stop_emission('insert-text')
entry.stop_emission_by_name('insert-text')
return
digits = self.digits
if digits and not (round(value, digits[1]) == float(value)):
entry.stop_emission('insert-text')
entry.stop_emission_by_name('insert-text')
def _key_press_event(self, entry, event):
for name in ['KP_Decimal', 'KP_Separator']:
if event.keyval == gtk.gdk.keyval_from_name(name):
event.keyval = int(gtk.gdk.unicode_to_keyval(
if event.keyval == Gdk.keyval_from_name(name):
event.keyval = int(Gdk.unicode_to_keyval(
ord(locale.localeconv()['decimal_point'])))
@property
@@ -1,9 +1,10 @@
# 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 urllib.request
from gi.repository import Gdk, Gtk
from tryton.common import resize_pixbuf, data2pixbuf
from tryton.config import CONFIG
from .widget import Widget
@@ -20,24 +21,26 @@ class Image(BinaryMixin, Widget):
self.height = int(attrs.get('height', 100))
self.width = int(attrs.get('width', 300))
self.widget = gtk.VBox(spacing=3)
self.event = gtk.EventBox()
self.event.drag_dest_set(gtk.DEST_DEFAULT_ALL, [
gtk.TargetEntry.new('text/plain', 0, 0),
gtk.TargetEntry.new('text/uri-list', 0, 1),
gtk.TargetEntry.new("image/x-xpixmap", 0, 2)], gtk.gdk.ACTION_MOVE)
self.widget = Gtk.VBox(spacing=3)
self.event = Gtk.EventBox()
self.event.drag_dest_set(Gtk.DestDefaults.ALL, [
Gtk.TargetEntry.new('text/plain', 0, 0),
Gtk.TargetEntry.new('text/uri-list', 0, 1),
Gtk.TargetEntry.new("image/x-xpixmap", 0, 2)],
Gdk.DragAction.MOVE)
self.event.connect('drag_motion', self.drag_motion)
self.event.connect('drag_data_received', self.drag_data_received)
self.image = gtk.Image()
self.image = Gtk.Image()
self.event.add(self.image)
self.widget.pack_start(self.event, expand=True, fill=True)
self.widget.pack_start(self.event, expand=True, fill=True, padding=0)
toolbar = self.toolbar() # Set button attributes even if not display
if not attrs.get('readonly'):
alignment = gtk.Alignment(xalign=0.5, yalign=0.5)
alignment = Gtk.Alignment(xalign=0.5, yalign=0.5)
alignment.add(toolbar)
self.widget.pack_start(alignment, expand=False, fill=False)
self.widget.pack_start(
alignment, expand=False, fill=False, padding=0)
self._readonly = False
@@ -46,7 +49,7 @@ class Image(BinaryMixin, Widget):
@property
def filters(self):
filters = super(Image, self).filters
filter_image = gtk.FileFilter()
filter_image = Gtk.FileFilter()
filter_image.set_name(_('Images'))
for mime in ("image/png", "image/jpeg", "image/gif"):
filter_image.add_mime_type(mime)
@@ -67,7 +70,7 @@ class Image(BinaryMixin, Widget):
def drag_motion(self, widget, context, x, y, timestamp):
if self._readonly:
return False
context.drag_status(gtk.gdk.ACTION_COPY, timestamp)
context.drag_status(Gdk.DragAction.COPY, timestamp)
return True
def drag_data_received(self, widget, context, x, y, selection,
@@ -22,7 +22,7 @@ class IntegerMixin:
try:
locale.atoi(new_value)
except ValueError:
entry.stop_emission('insert-text')
entry.stop_emission_by_name('insert-text')
class Integer(IntegerMixin, Char):
@@ -1,16 +1,17 @@
# 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 tryton.gui.window.view_form.screen import Screen
from .widget import Widget
from tryton.gui.window.win_search import WinSearch
from tryton.gui.window.win_form import WinForm
import tryton.common as common
import gettext
from gi.repository import Gdk, Gtk
import tryton.common as common
from .widget import Widget
from tryton.common.completion import get_completion, update_completion
from tryton.common.domain_parser import quote
from tryton.common.underline import set_underline
from tryton.gui.window.view_form.screen import Screen
from tryton.gui.window.win_search import WinSearch
from tryton.gui.window.win_form import WinForm
_ = gettext.gettext
@@ -21,33 +22,33 @@ class Many2Many(Widget):
def __init__(self, view, attrs):
super(Many2Many, self).__init__(view, attrs)
self.widget = gtk.Frame()
self.widget.set_shadow_type(gtk.SHADOW_NONE)
self.widget = Gtk.Frame()
self.widget.set_shadow_type(Gtk.ShadowType.NONE)
self.widget.get_accessible().set_name(attrs.get('string', ''))
vbox = gtk.VBox(homogeneous=False, spacing=5)
vbox = Gtk.VBox(homogeneous=False, spacing=5)
self.widget.add(vbox)
self._readonly = True
self._required = False
self._position = 0
hbox = gtk.HBox(homogeneous=False, spacing=0)
hbox = Gtk.HBox(homogeneous=False, spacing=0)
hbox.set_border_width(2)
self.title = gtk.Label(set_underline(attrs.get('string', '')))
self.title.set_use_underline(True)
self.title.set_alignment(0.0, 0.5)
hbox.pack_start(self.title, expand=True, fill=True)
self.title = Gtk.Label(
label=set_underline(attrs.get('string', '')),
use_underline=True, halign=Gtk.Align.START)
hbox.pack_start(self.title, expand=True, fill=True, padding=0)
hbox.pack_start(gtk.VSeparator(), expand=False, fill=True)
hbox.pack_start(Gtk.VSeparator(), expand=False, fill=True, padding=0)
tooltips = common.Tooltips()
self.wid_text = gtk.Entry()
self.wid_text = Gtk.Entry()
self.wid_text.set_placeholder_text(_('Search'))
self.wid_text.set_property('width_chars', 13)
self.wid_text.connect('focus-out-event', self._focus_out)
self.focus_out = True
hbox.pack_start(self.wid_text, expand=True, fill=True)
hbox.pack_start(self.wid_text, expand=True, fill=True, padding=0)
if int(self.attrs.get('completion', 1)):
self.wid_completion = get_completion(
@@ -62,30 +63,30 @@ class Many2Many(Widget):
else:
self.wid_completion = None
self.but_add = gtk.Button()
self.but_add = Gtk.Button()
tooltips.set_tip(self.but_add, _('Add existing record'))
self.but_add.connect('clicked', self._sig_add)
self.but_add.add(common.IconFactory.get_image(
'tryton-add', gtk.ICON_SIZE_SMALL_TOOLBAR))
self.but_add.set_relief(gtk.RELIEF_NONE)
hbox.pack_start(self.but_add, expand=False, fill=False)
'tryton-add', Gtk.IconSize.SMALL_TOOLBAR))
self.but_add.set_relief(Gtk.ReliefStyle.NONE)
hbox.pack_start(self.but_add, expand=False, fill=False, padding=0)
self.but_remove = gtk.Button()
self.but_remove = Gtk.Button()
tooltips.set_tip(self.but_remove, _('Remove selected record <Del>'))
self.but_remove.connect('clicked', self._sig_remove)
self.but_remove.add(common.IconFactory.get_image(
'tryton-remove', gtk.ICON_SIZE_SMALL_TOOLBAR))
self.but_remove.set_relief(gtk.RELIEF_NONE)
hbox.pack_start(self.but_remove, expand=False, fill=False)
'tryton-remove', Gtk.IconSize.SMALL_TOOLBAR))
self.but_remove.set_relief(Gtk.ReliefStyle.NONE)
hbox.pack_start(self.but_remove, expand=False, fill=False, padding=0)
hbox.set_focus_chain([self.wid_text])
tooltips.enable()
frame = gtk.Frame()
frame = Gtk.Frame()
frame.add(hbox)
frame.set_shadow_type(gtk.SHADOW_OUT)
vbox.pack_start(frame, expand=False, fill=True)
frame.set_shadow_type(Gtk.ShadowType.OUT)
vbox.pack_start(frame, expand=False, fill=True, padding=0)
self.screen = Screen(attrs['relation'],
view_ids=attrs.get('view_ids', '').split(','),
@@ -94,7 +95,7 @@ class Many2Many(Widget):
limit=None)
self.screen.signal_connect(self, 'record-message', self._sig_label)
vbox.pack_start(self.screen.widget, expand=True, fill=True)
vbox.pack_start(self.screen.widget, expand=True, fill=True, padding=0)
self.title.set_mnemonic_widget(
self.screen.current_view.mnemonic_widget)
@@ -104,25 +105,25 @@ class Many2Many(Widget):
def on_keypress(self, widget, event):
editable = self.wid_text.get_editable()
activate_keys = [gtk.keysyms.Tab, gtk.keysyms.ISO_Left_Tab]
remove_keys = [gtk.keysyms.Delete, gtk.keysyms.KP_Delete]
activate_keys = [Gdk.KEY_Tab, Gdk.KEY_ISO_Left_Tab]
remove_keys = [Gdk.KEY_Delete, Gdk.KEY_KP_Delete]
if not self.wid_completion:
activate_keys.append(gtk.keysyms.Return)
activate_keys.append(Gdk.KEY_Return)
if widget == self.screen.widget:
if event.keyval == gtk.keysyms.F3 and editable:
if event.keyval == Gdk.KEY_F3 and editable:
self._sig_add()
return True
elif event.keyval == gtk.keysyms.F2:
elif event.keyval == Gdk.KEY_F2:
self._sig_edit()
return True
elif event.keyval in remove_keys and editable:
self._sig_remove()
return True
elif widget == self.wid_text:
if event.keyval == gtk.keysyms.F3:
if event.keyval == Gdk.KEY_F3:
self._sig_new()
return True
elif event.keyval == gtk.keysyms.F2:
elif event.keyval == Gdk.KEY_F2:
self._sig_add()
return True
elif event.keyval in activate_keys and self.wid_text.get_text():
@@ -163,7 +164,7 @@ class Many2Many(Widget):
title=self.attrs.get('string'))
win.screen.search_filter(quote(value))
if len(win.screen.group) == 1:
win.response(None, gtk.RESPONSE_OK)
win.response(None, Gtk.ResponseType.OK)
else:
win.show()
@@ -1,9 +1,9 @@
# 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 gobject
import gettext
from gi.repository import Gdk, GLib, Gtk
from .widget import Widget
import tryton.common as common
from tryton.gui.window.view_form.screen import Screen
@@ -23,10 +23,10 @@ class Many2One(Widget):
def __init__(self, view, attrs):
super(Many2One, self).__init__(view, attrs)
self.widget = gtk.HBox(spacing=0)
self.widget = Gtk.HBox(spacing=0)
self.widget.set_property('sensitive', True)
self.wid_text = self.mnemonic_widget = gtk.Entry()
self.wid_text = self.mnemonic_widget = Gtk.Entry()
self.wid_text.set_property('width-chars', self.default_width_chars)
self.wid_text.set_property('activates_default', True)
self.wid_text.connect('key-press-event', self.send_modified)
@@ -44,7 +44,7 @@ class Many2One(Widget):
self.wid_text.connect('icon-press', self.sig_edit)
self.widget.pack_end(self.wid_text, expand=True, fill=True)
self.widget.pack_end(self.wid_text, expand=True, fill=True, padding=0)
self._readonly = False
@@ -62,9 +62,9 @@ class Many2One(Widget):
def _set_button_sensitive(self):
self.wid_text.set_editable(not self._readonly)
self.wid_text.set_icon_sensitive(
gtk.ENTRY_ICON_PRIMARY, self.read_access)
Gtk.EntryIconPosition.PRIMARY, self.read_access)
self.wid_text.set_icon_sensitive(
gtk.ENTRY_ICON_SECONDARY, not self._readonly)
Gtk.EntryIconPosition.SECONDARY, not self._readonly)
def get_access(self, type_):
model = self.get_model()
@@ -140,7 +140,7 @@ class Many2One(Widget):
title=self.attrs.get('string'))
win.screen.search_filter(quote(text))
if len(win.screen.group) == 1:
win.response(None, gtk.RESPONSE_OK)
win.response(None, Gtk.ResponseType.OK)
else:
win.show()
return
@@ -184,7 +184,7 @@ class Many2One(Widget):
self.focus_out = False
value = self.field.get(self.record)
if (icon_pos == gtk.ENTRY_ICON_SECONDARY
if (icon_pos == Gtk.EntryIconPosition.SECONDARY
and not self._readonly
and self.has_target(value)):
self.field.set_client(self.record, self.value_from_id(None, ''))
@@ -233,15 +233,15 @@ class Many2One(Widget):
def sig_key_press(self, widget, event, *args):
editable = self.wid_text.get_editable()
activate_keys = [gtk.keysyms.Tab, gtk.keysyms.ISO_Left_Tab]
activate_keys = [Gdk.KEY_Tab, Gdk.KEY_ISO_Left_Tab]
if not self.wid_completion:
activate_keys.append(gtk.keysyms.Return)
if (event.keyval == gtk.keysyms.F3
activate_keys.append(Gdk.KEY_Return)
if (event.keyval == Gdk.KEY_F3
and editable
and self.create_access):
self.sig_new(widget, event)
return True
elif event.keyval == gtk.keysyms.F2 and self.read_access:
elif event.keyval == Gdk.KEY_F2 and self.read_access:
self.sig_edit(widget)
return True
elif (event.keyval in activate_keys
@@ -249,8 +249,7 @@ class Many2One(Widget):
self.sig_activate()
elif (self.has_target(self.field.get(self.record))
and editable
and event.keyval in (gtk.keysyms.Delete,
gtk.keysyms.BackSpace)):
and event.keyval in [Gdk.KEY_Delete, Gdk.KEY_BackSpace]):
self.wid_text.set_text('')
return False
@@ -272,7 +271,7 @@ class Many2One(Widget):
# Restore text and position after display
self.wid_text.set_text(text)
self.wid_text.set_position(position)
gobject.idle_add(clean)
GLib.idle_add(clean)
return False
def get_value(self):
@@ -310,11 +309,11 @@ class Many2One(Widget):
if not self.wid_text.get_editable():
icon2, tooltip2 = None, ''
for pos, icon, tooltip in [
(gtk.ENTRY_ICON_PRIMARY, icon1, tooltip1),
(gtk.ENTRY_ICON_SECONDARY, icon2, tooltip2)]:
(Gtk.EntryIconPosition.PRIMARY, icon1, tooltip1),
(Gtk.EntryIconPosition.SECONDARY, icon2, tooltip2)]:
if icon:
pixbuf = common.IconFactory.get_pixbuf(
icon, gtk.ICON_SIZE_MENU)
icon, Gtk.IconSize.MENU)
else:
pixbuf = None
self.wid_text.set_icon_from_pixbuf(pos, pixbuf)
@@ -325,7 +324,7 @@ class Many2One(Widget):
value = self.field.get(self.record)
if self.has_target(value):
# Delay filling of popup as it can take time
gobject.idle_add(populate, menu, self.get_model(),
GLib.idle_add(populate, menu, self.get_model(),
self.id_from_value(value), '', self.field)
return True
@@ -345,7 +344,7 @@ class Many2One(Widget):
rec_name, record_id = model.get(iter_, 0, 1)
# GTK on win32 doesn't like synchronous call to set_client
# because it triggers a display which reset the completion
gobject.idle_add(self.field.set_client, self.record,
GLib.idle_add(self.field.set_client, self.record,
self.value_from_id(record_id, rec_name), True)
completion_model = self.wid_completion.get_model()
@@ -1,7 +1,6 @@
# 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 gobject
from gi.repository import GLib, GObject, Gtk
from .widget import Widget
from tryton.common.selection import SelectionMixin
@@ -15,27 +14,28 @@ class MultiSelection(Widget, SelectionMixin):
super(MultiSelection, self).__init__(view, attrs)
if int(attrs.get('yexpand', self.expand)):
self.widget = gtk.ScrolledWindow()
self.widget.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
self.widget.set_shadow_type(gtk.SHADOW_ETCHED_IN)
self.widget = Gtk.ScrolledWindow()
self.widget.set_policy(
Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
self.widget.set_shadow_type(Gtk.ShadowType.ETCHED_IN)
else:
self.widget = gtk.VBox()
self.widget = Gtk.VBox()
self.widget.set_size_request(100, 100)
self.widget.get_accessible().set_name(attrs.get('string', ''))
self.model = gtk.ListStore(gobject.TYPE_INT, gobject.TYPE_STRING)
self.model = Gtk.ListStore(GObject.TYPE_INT, GObject.TYPE_STRING)
self.tree = self.mnemonic_widget = TreeViewControl()
self.tree.set_model(self.model)
self.tree.set_search_column(1)
self.tree.connect('focus-out-event', lambda *a: self._focus_out())
self.tree.set_headers_visible(False)
selection = self.tree.get_selection()
selection.set_mode(gtk.SELECTION_MULTIPLE)
selection.set_mode(Gtk.SelectionMode.MULTIPLE)
selection.connect('changed', self.changed)
self.widget.add(self.tree)
name_column = gtk.TreeViewColumn()
name_cell = gtk.CellRendererText()
name_column.pack_start(name_cell)
name_column = Gtk.TreeViewColumn()
name_cell = Gtk.CellRendererText()
name_column.pack_start(name_cell, expand=True)
name_column.add_attribute(name_cell, 'text', 1)
self.tree.append_column(name_column)
@@ -61,7 +61,7 @@ class MultiSelection(Widget, SelectionMixin):
if self.widget.props.window:
self._focus_out()
# Must be deferred because it triggers a display of the form
gobject.idle_add(focus_out)
GLib.idle_add(focus_out)
def get_value(self):
model, paths = self.tree.get_selection().get_selected_rows()
@@ -1,9 +1,10 @@
# 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 itertools
from gi.repository import Gdk, Gtk
from .widget import Widget
from tryton.gui.window.view_form.screen import Screen
from tryton.gui.window.win_search import WinSearch
@@ -22,66 +23,66 @@ class One2Many(Widget):
def __init__(self, view, attrs):
super(One2Many, self).__init__(view, attrs)
self.widget = gtk.Frame()
self.widget.set_shadow_type(gtk.SHADOW_NONE)
self.widget = Gtk.Frame()
self.widget.set_shadow_type(Gtk.ShadowType.NONE)
self.widget.get_accessible().set_name(attrs.get('string', ''))
vbox = gtk.VBox(homogeneous=False, spacing=2)
vbox = Gtk.VBox(homogeneous=False, spacing=2)
self.widget.add(vbox)
self._readonly = True
self._required = False
self._position = 0
self._length = 0
self.title_box = hbox = gtk.HBox(homogeneous=False, spacing=0)
self.title_box = hbox = Gtk.HBox(homogeneous=False, spacing=0)
hbox.set_border_width(2)
self.title = gtk.Label(set_underline(attrs.get('string', '')))
self.title.set_use_underline(True)
self.title.set_alignment(0.0, 0.5)
hbox.pack_start(self.title, expand=True, fill=True)
self.title = Gtk.Label(
label=set_underline(attrs.get('string', '')),
use_underline=True, halign=Gtk.Align.START)
hbox.pack_start(self.title, expand=True, fill=True, padding=0)
hbox.pack_start(gtk.VSeparator(), expand=False, fill=True)
hbox.pack_start(Gtk.VSeparator(), expand=False, fill=True, padding=0)
tooltips = common.Tooltips()
but_switch = gtk.Button()
but_switch = Gtk.Button()
tooltips.set_tip(but_switch, _('Switch'))
but_switch.connect('clicked', self.switch_view)
but_switch.add(common.IconFactory.get_image(
'tryton-switch', gtk.ICON_SIZE_SMALL_TOOLBAR))
but_switch.set_relief(gtk.RELIEF_NONE)
hbox.pack_start(but_switch, expand=False, fill=False)
'tryton-switch', Gtk.IconSize.SMALL_TOOLBAR))
but_switch.set_relief(Gtk.ReliefStyle.NONE)
hbox.pack_start(but_switch, expand=False, fill=False, padding=0)
self.but_pre = gtk.Button()
self.but_pre = Gtk.Button()
tooltips.set_tip(self.but_pre, _('Previous'))
self.but_pre.connect('clicked', self._sig_previous)
self.but_pre.add(common.IconFactory.get_image(
'tryton-back', gtk.ICON_SIZE_SMALL_TOOLBAR))
self.but_pre.set_relief(gtk.RELIEF_NONE)
hbox.pack_start(self.but_pre, expand=False, fill=False)
'tryton-back', Gtk.IconSize.SMALL_TOOLBAR))
self.but_pre.set_relief(Gtk.ReliefStyle.NONE)
hbox.pack_start(self.but_pre, expand=False, fill=False, padding=0)
self.label = gtk.Label('(0,0)')
hbox.pack_start(self.label, expand=False, fill=False)
self.label = Gtk.Label(label='(0,0)')
hbox.pack_start(self.label, expand=False, fill=False, padding=0)
self.but_next = gtk.Button()
self.but_next = Gtk.Button()
tooltips.set_tip(self.but_next, _('Next'))
self.but_next.connect('clicked', self._sig_next)
self.but_next.add(common.IconFactory.get_image(
'tryton-forward', gtk.ICON_SIZE_SMALL_TOOLBAR))
self.but_next.set_relief(gtk.RELIEF_NONE)
hbox.pack_start(self.but_next, expand=False, fill=False)
'tryton-forward', Gtk.IconSize.SMALL_TOOLBAR))
self.but_next.set_relief(Gtk.ReliefStyle.NONE)
hbox.pack_start(self.but_next, expand=False, fill=False, padding=0)
hbox.pack_start(gtk.VSeparator(), expand=False, fill=True)
hbox.pack_start(Gtk.VSeparator(), expand=False, fill=True, padding=0)
self.focus_out = True
self.wid_completion = None
if attrs.get('add_remove'):
self.wid_text = gtk.Entry()
self.wid_text = Gtk.Entry()
self.wid_text.set_placeholder_text(_('Search'))
self.wid_text.set_property('width_chars', 13)
self.wid_text.connect('focus-out-event', self._focus_out)
hbox.pack_start(self.wid_text, expand=True, fill=True)
hbox.pack_start(self.wid_text, expand=True, fill=True, padding=0)
if int(self.attrs.get('completion', 1)):
access = common.MODELACCESS[attrs['relation']]
@@ -95,56 +96,58 @@ class One2Many(Widget):
self.wid_text.set_completion(self.wid_completion)
self.wid_text.connect('changed', self._update_completion)
self.but_add = gtk.Button()
self.but_add = Gtk.Button()
tooltips.set_tip(self.but_add, _('Add existing record'))
self.but_add.connect('clicked', self._sig_add)
self.but_add.add(common.IconFactory.get_image(
'tryton-add', gtk.ICON_SIZE_SMALL_TOOLBAR))
self.but_add.set_relief(gtk.RELIEF_NONE)
hbox.pack_start(self.but_add, expand=False, fill=False)
'tryton-add', Gtk.IconSize.SMALL_TOOLBAR))
self.but_add.set_relief(Gtk.ReliefStyle.NONE)
hbox.pack_start(self.but_add, expand=False, fill=False, padding=0)
self.but_remove = gtk.Button()
self.but_remove = Gtk.Button()
tooltips.set_tip(self.but_remove,
_('Remove selected record'))
self.but_remove.connect('clicked', self._sig_remove, True)
self.but_remove.add(common.IconFactory.get_image(
'tryton-remove', gtk.ICON_SIZE_SMALL_TOOLBAR))
self.but_remove.set_relief(gtk.RELIEF_NONE)
hbox.pack_start(self.but_remove, expand=False, fill=False)
'tryton-remove', Gtk.IconSize.SMALL_TOOLBAR))
self.but_remove.set_relief(Gtk.ReliefStyle.NONE)
hbox.pack_start(
self.but_remove, expand=False, fill=False, padding=0)
hbox.pack_start(gtk.VSeparator(), expand=False, fill=True)
hbox.pack_start(
Gtk.VSeparator(), expand=False, fill=True, padding=0)
self.but_new = gtk.Button()
self.but_new = Gtk.Button()
tooltips.set_tip(self.but_new, _('Create a new record <F3>'))
self.but_new.connect('clicked', self._sig_new)
self.but_new.add(common.IconFactory.get_image(
'tryton-create', gtk.ICON_SIZE_SMALL_TOOLBAR))
self.but_new.set_relief(gtk.RELIEF_NONE)
hbox.pack_start(self.but_new, expand=False, fill=False)
'tryton-create', Gtk.IconSize.SMALL_TOOLBAR))
self.but_new.set_relief(Gtk.ReliefStyle.NONE)
hbox.pack_start(self.but_new, expand=False, fill=False, padding=0)
self.but_open = gtk.Button()
self.but_open = Gtk.Button()
tooltips.set_tip(self.but_open, _('Edit selected record <F2>'))
self.but_open.connect('clicked', self._sig_edit)
self.but_open.add(common.IconFactory.get_image(
'tryton-open', gtk.ICON_SIZE_SMALL_TOOLBAR))
self.but_open.set_relief(gtk.RELIEF_NONE)
hbox.pack_start(self.but_open, expand=False, fill=False)
'tryton-open', Gtk.IconSize.SMALL_TOOLBAR))
self.but_open.set_relief(Gtk.ReliefStyle.NONE)
hbox.pack_start(self.but_open, expand=False, fill=False, padding=0)
self.but_del = gtk.Button()
self.but_del = Gtk.Button()
tooltips.set_tip(self.but_del, _('Delete selected record <Del>'))
self.but_del.connect('clicked', self._sig_remove, False)
self.but_del.add(common.IconFactory.get_image(
'tryton-delete', gtk.ICON_SIZE_SMALL_TOOLBAR))
self.but_del.set_relief(gtk.RELIEF_NONE)
hbox.pack_start(self.but_del, expand=False, fill=False)
'tryton-delete', Gtk.IconSize.SMALL_TOOLBAR))
self.but_del.set_relief(Gtk.ReliefStyle.NONE)
hbox.pack_start(self.but_del, expand=False, fill=False, padding=0)
self.but_undel = gtk.Button()
self.but_undel = Gtk.Button()
tooltips.set_tip(self.but_undel, _('Undelete selected record <Ins>'))
self.but_undel.connect('clicked', self._sig_undelete)
self.but_undel.add(common.IconFactory.get_image(
'tryton-undo', gtk.ICON_SIZE_SMALL_TOOLBAR))
self.but_undel.set_relief(gtk.RELIEF_NONE)
hbox.pack_start(self.but_undel, expand=False, fill=False)
'tryton-undo', Gtk.IconSize.SMALL_TOOLBAR))
self.but_undel.set_relief(Gtk.ReliefStyle.NONE)
hbox.pack_start(self.but_undel, expand=False, fill=False, padding=0)
if attrs.get('add_remove'):
hbox.set_focus_chain([self.wid_text])
@@ -153,10 +156,10 @@ class One2Many(Widget):
tooltips.enable()
frame = gtk.Frame()
frame = Gtk.Frame()
frame.add(hbox)
frame.set_shadow_type(gtk.SHADOW_OUT)
vbox.pack_start(frame, expand=False, fill=True)
frame.set_shadow_type(Gtk.ShadowType.OUT)
vbox.pack_start(frame, expand=False, fill=True, padding=0)
self.screen = Screen(attrs['relation'],
mode=attrs.get('mode', 'tree,form').split(','),
@@ -168,7 +171,7 @@ class One2Many(Widget):
self.screen.pre_validate = bool(int(attrs.get('pre_validate', 0)))
self.screen.signal_connect(self, 'record-message', self._sig_label)
vbox.pack_start(self.screen.widget, expand=True, fill=True)
vbox.pack_start(self.screen.widget, expand=True, fill=True, padding=0)
self.title.set_mnemonic_widget(
self.screen.current_view.mnemonic_widget)
@@ -180,27 +183,27 @@ class One2Many(Widget):
but_switch.props.sensitive = self.screen.number_of_views > 1
def on_keypress(self, widget, event):
if (event.keyval == gtk.keysyms.F3) \
and self.but_new.get_property('sensitive'):
if ((event.keyval == Gdk.KEY_F3)
and self.but_new.get_property('sensitive')):
self._sig_new(widget)
return True
if event.keyval == gtk.keysyms.F2 \
and widget == self.screen.widget:
if (event.keyval == Gdk.KEY_F2
and widget == self.screen.widget):
self._sig_edit(widget)
return True
if (event.keyval in (gtk.keysyms.Delete, gtk.keysyms.KP_Delete)
if (event.keyval in [Gdk.KEY_Delete, Gdk.KEY_KP_Delete]
and widget == self.screen.widget
and self.but_del.get_property('sensitive')):
self._sig_remove(widget)
return True
if event.keyval == gtk.keysyms.Insert and widget == self.screen.widget:
if event.keyval == Gdk.KEY_Insert and widget == self.screen.widget:
self._sig_undelete(widget)
return True
if self.attrs.get('add_remove'):
editable = self.wid_text.get_editable()
activate_keys = [gtk.keysyms.Tab, gtk.keysyms.ISO_Left_Tab]
activate_keys = [Gdk.KEY_Tab, Gdk.KEY_ISO_Left_Tab]
if not self.wid_completion:
activate_keys.append(gtk.keysyms.Return)
activate_keys.append(Gdk.KEY_Return)
if (widget == self.wid_text
and event.keyval in activate_keys
and editable
@@ -1,8 +1,9 @@
# 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
from gi.repository import Gtk
from .widget import Widget
_ = gettext.gettext
@@ -11,18 +12,19 @@ _ = gettext.gettext
class ProgressBar(Widget):
'Progress Bar'
orientations = {
'left_to_right': gtk.PROGRESS_LEFT_TO_RIGHT,
'right_to_left': gtk.PROGRESS_RIGHT_TO_LEFT,
'bottom_to_top': gtk.PROGRESS_BOTTOM_TO_TOP,
'top_to_bottom': gtk.PROGRESS_TOP_TO_BOTTOM,
'left_to_right': (Gtk.Orientation.HORIZONTAL, False),
'right_to_left': (Gtk.Orientation.HORIZONTAL, True),
'bottom_to_top': (Gtk.Orientation.VERTICAL, True),
'top_to_bottom': (Gtk.Orientation.VERTICAL, False),
}
def __init__(self, view, attrs):
super(ProgressBar, self).__init__(view, attrs)
self.widget = self.mnemonic_widget = gtk.ProgressBar()
orientation = self.orientations.get(attrs.get('orientation',
'left_to_right'), gtk.PROGRESS_LEFT_TO_RIGHT)
self.widget = self.mnemonic_widget = Gtk.ProgressBar()
orientation, inverted = self.orientations.get(
attrs.get('orientation', 'left_to_right'))
self.widget.set_orientation(orientation)
self.widget.set_prinverted(inverted)
def display(self):
super(ProgressBar, self).display()
@@ -1,8 +1,9 @@
# 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
from gi.repository import Gtk
from .many2one import Many2One
from tryton.common.selection import SelectionMixin, PopdownMixin, \
selection_shortcuts
@@ -16,7 +17,7 @@ class Reference(Many2One, SelectionMixin, PopdownMixin):
def __init__(self, view, attrs):
super(Reference, self).__init__(view, attrs)
self.widget_combo = gtk.ComboBoxEntry()
self.widget_combo = Gtk.ComboBox(has_entry=True)
child = self.widget_combo.get_child()
child.connect('activate', lambda *a: self._focus_out())
child.connect('focus-out-event', lambda *a: self._focus_out())
@@ -24,11 +25,13 @@ class Reference(Many2One, SelectionMixin, PopdownMixin):
self.widget_combo.connect('changed', self.sig_changed_combo)
self.widget_combo.connect('move-active', self._move_active)
self.widget_combo.connect(
'scroll-event', lambda c, e: c.emit_stop_by_name('scroll-event'))
'scroll-event',
lambda c, e: c.stop_emission_by_name('scroll-event'))
selection_shortcuts(self.widget_combo)
self.widget_combo.set_focus_chain([child])
self.widget.pack_start(self.widget_combo, expand=False, fill=True)
self.widget.pack_start(
self.widget_combo, expand=False, fill=True, padding=0)
self.init_selection()
self.set_popdown(self.selection, self.widget_combo)
@@ -51,13 +54,14 @@ class Reference(Many2One, SelectionMixin, PopdownMixin):
def _move_active(self, combobox, scroll_type):
if not combobox.get_child().get_editable():
combobox.emit_stop_by_name('move-active')
combobox.stop_emission_by_name('move-active')
def _set_button_sensitive(self):
super(Reference, self)._set_button_sensitive()
self.widget_combo.get_child().set_editable(not self._readonly)
self.widget_combo.set_button_sensitivity(
gtk.SENSITIVITY_OFF if self._readonly else gtk.SENSITIVITY_AUTO)
Gtk.SensitivityType.OFF if self._readonly
else Gtk.SensitivityType.AUTO)
if self._readonly and CONFIG['client.fast_tabbing']:
self.widget.set_focus_chain([])
else:
@@ -3,7 +3,7 @@
from gettext import gettext as _
from weakref import WeakKeyDictionary
import gtk
from gi.repository import Gtk
from .textbox import TextBox
from tryton.common import get_toplevel_window, IconFactory
@@ -25,71 +25,70 @@ class RichTextBox(TextBox):
self.colors = {}
if int(self.attrs.get('toolbar', 1)):
self.toolbar = self.get_toolbar(self.textview)
self.widget.pack_start(self.toolbar, expand=False, fill=True)
self.widget.pack_start(
self.toolbar, expand=False, fill=True, padding=0)
def get_toolbar(self, textview):
toolbar = gtk.Toolbar()
toolbar = Gtk.Toolbar()
toolbar.set_style({
'default': False,
'both': gtk.TOOLBAR_BOTH,
'text': gtk.TOOLBAR_TEXT,
'icons': gtk.TOOLBAR_ICONS}[CONFIG['client.toolbar']])
'both': Gtk.ToolbarStyle.BOTH,
'text': Gtk.ToolbarStyle.TEXT,
'icons': Gtk.ToolbarStyle.ICONS,
}[CONFIG['client.toolbar']])
tag_widgets = self.tag_widgets[textview] = {}
for icon in ['bold', 'italic', 'underline']:
button = gtk.ToggleToolButton()
button = Gtk.ToggleToolButton()
button.set_icon_widget(IconFactory.get_image(
'tryton-format-%s' % icon,
gtk.ICON_SIZE_SMALL_TOOLBAR))
Gtk.IconSize.SMALL_TOOLBAR))
button.connect('toggled', self.toggle_props, icon, textview)
toolbar.insert(button, -1)
tag_widgets[icon] = button
toolbar.insert(gtk.SeparatorToolItem(), -1)
toolbar.insert(Gtk.SeparatorToolItem(), -1)
for name, options, active in [
('family', FAMILIES, FAMILIES.index('normal')),
('size', SIZES, SIZES.index('4')),
]:
try:
combobox = gtk.ComboBoxText()
except AttributeError:
combobox = gtk.combo_box_new_text()
combobox = Gtk.ComboBoxText()
for option in options:
combobox.append_text(option)
combobox.set_active(active)
combobox.set_focus_on_click(False)
combobox.connect('changed', self.change_props, name, textview)
tool = gtk.ToolItem()
tool = Gtk.ToolItem()
tool.add(combobox)
toolbar.insert(tool, -1)
tag_widgets[name] = combobox
toolbar.insert(gtk.SeparatorToolItem(), -1)
toolbar.insert(Gtk.SeparatorToolItem(), -1)
button = None
for name in ['left', 'center', 'right', 'justify']:
icon = 'tryton-format-align-%s' % name
button = gtk.RadioToolButton.new_from_widget(button)
button = Gtk.RadioToolButton.new_from_widget(button)
button.set_icon_widget(IconFactory.get_image(
icon, gtk.ICON_SIZE_SMALL_TOOLBAR))
icon, Gtk.IconSize.SMALL_TOOLBAR))
button.set_active(icon == 'left')
button.connect(
'toggled', self.toggle_justification, name, textview)
toolbar.insert(button, -1)
tag_widgets[name] = button
toolbar.insert(gtk.SeparatorToolItem(), -1)
toolbar.insert(Gtk.SeparatorToolItem(), -1)
for icon, label in [
('foreground', _('Foreground')),
# TODO ('background', _('Background')),
]:
button = gtk.ToolButton()
button = Gtk.ToolButton()
if icon == 'foreground':
button.set_icon_widget(IconFactory.get_image(
'tryton-format-color-text',
gtk.ICON_SIZE_SMALL_TOOLBAR))
Gtk.IconSize.SMALL_TOOLBAR))
button.set_label(label)
button.connect('clicked', self.toggle_color, icon, textview)
toolbar.insert(button, -1)
@@ -114,7 +113,7 @@ class RichTextBox(TextBox):
textview = widget.get_children()[-1].get_child()
if self.toolbar:
widget.pack_start(
self.get_toolbar(textview), expand=False, fill=True)
self.get_toolbar(textview), expand=False, fill=True, padding=0)
return widget
def translate_widget_set_readonly(self, widget, value):
@@ -266,19 +265,19 @@ class RichTextBox(TextBox):
def _apply_tool(self, text_buffer, name, tool, start, end):
# First test RadioToolButton as they inherit from ToggleToolButton
if isinstance(tool, gtk.RadioToolButton):
if isinstance(tool, Gtk.RadioToolButton):
name = 'justification %s' % name
if not tool.get_active():
remove_tags(text_buffer, start, end, name)
else:
remove_tags(text_buffer, start, end, 'justification')
text_buffer.apply_tag_by_name(name, start, end)
elif isinstance(tool, gtk.ToggleToolButton):
elif isinstance(tool, Gtk.ToggleToolButton):
if tool.get_active():
text_buffer.apply_tag_by_name(name, start, end)
else:
text_buffer.remove_tag_by_name(name, start, end)
elif isinstance(tool, gtk.ComboBox):
elif isinstance(tool, Gtk.ComboBoxText):
value = tool.get_active_text()
remove_tags(text_buffer, start, end, name)
name = '%s %s' % (name, value)
@@ -325,14 +324,14 @@ class RichTextBox(TextBox):
start = start.get_offset()
end = end.get_offset()
dialog = gtk.ColorSelectionDialog(_('Select a color'))
dialog = Gtk.ColorSelectionDialog(_('Select a color'))
dialog.set_transient_for(get_toplevel_window())
colorsel = dialog.get_color_selection()
colorsel.set_has_palette(True)
color = self.colors.get(name)
if color:
colorsel.set_current_color(color)
if dialog.run() == gtk.RESPONSE_OK:
if dialog.run() == Gtk.ResponseType.OK:
color = colorsel.get_current_color()
self.colors[name] = color
if start is not None and end is not None:
@@ -1,7 +1,6 @@
# 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 gobject
from gi.repository import GLib, Gtk
from .widget import Widget
from tryton.common.selection import SelectionMixin, selection_shortcuts, \
@@ -14,8 +13,8 @@ class Selection(Widget, SelectionMixin, PopdownMixin):
def __init__(self, view, attrs):
super(Selection, self).__init__(view, attrs)
self.widget = gtk.HBox(spacing=3)
self.entry = gtk.ComboBoxEntry()
self.widget = Gtk.HBox(spacing=3)
self.entry = Gtk.ComboBox(has_entry=True)
child = self.mnemonic_widget = self.entry.get_child()
child.set_property('activates_default', True)
child.set_max_length(int(attrs.get('size', 0)))
@@ -27,8 +26,9 @@ class Selection(Widget, SelectionMixin, PopdownMixin):
self.entry.connect('changed', self.changed)
self.entry.connect('move-active', self._move_active)
self.entry.connect(
'scroll-event', lambda c, e: c.emit_stop_by_name('scroll-event'))
self.widget.pack_start(self.entry)
'scroll-event',
lambda c, e: c.stop_emission_by_name('scroll-event'))
self.widget.pack_start(self.entry, expand=True, fill=True, padding=0)
self.widget.set_focus_chain([child])
self.selection = attrs.get('selection', [])[:]
@@ -41,17 +41,17 @@ class Selection(Widget, SelectionMixin, PopdownMixin):
if combobox.props.window:
self._focus_out()
# Must be deferred because it triggers a display of the form
gobject.idle_add(focus_out)
GLib.idle_add(focus_out)
def _move_active(self, combobox, scroll_type):
if not combobox.get_child().get_editable():
combobox.emit_stop_by_name('move-active')
combobox.stop_emission_by_name('move-active')
def _readonly_set(self, value):
super(Selection, self)._readonly_set(value)
self.entry.get_child().set_editable(not value)
self.entry.set_button_sensitivity(
gtk.SENSITIVITY_OFF if value else gtk.SENSITIVITY_AUTO)
Gtk.SensitivityType.OFF if value else Gtk.SensitivityType.AUTO)
if value and CONFIG['client.fast_tabbing']:
self.widget.set_focus_chain([])
else:
@@ -1,6 +1,6 @@
# 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 gi.repository import Gtk
import tryton.common as common
@@ -22,7 +22,7 @@ class StateMixin(object):
self.show()
class Label(StateMixin, gtk.Label):
class Label(StateMixin, Gtk.Label):
def state_set(self, record):
super(Label, self).state_set(record)
@@ -47,11 +47,11 @@ class Label(StateMixin, gtk.Label):
common.apply_label_attributes(self, readonly, required)
class VBox(StateMixin, gtk.VBox):
class VBox(StateMixin, Gtk.VBox):
pass
class Image(StateMixin, gtk.Image):
class Image(StateMixin, Gtk.Image):
def state_set(self, record):
super(Image, self).state_set(record)
@@ -62,21 +62,21 @@ class Image(StateMixin, gtk.Image):
field = record.group.fields[name]
name = field.get(record)
self.set_from_pixbuf(common.IconFactory.get_pixbuf(
name, gtk.ICON_SIZE_DIALOG))
name, Gtk.IconSize.DIALOG))
class Frame(StateMixin, gtk.Frame):
class Frame(StateMixin, Gtk.Frame):
def __init__(self, label=None, attrs=None):
if not label: # label must be None to have no label widget
label = None
super(Frame, self).__init__(label=label, attrs=attrs)
if not label:
self.set_shadow_type(gtk.SHADOW_NONE)
self.set_shadow_type(Gtk.ShadowType.NONE)
self.set_border_width(0)
class ScrolledWindow(StateMixin, gtk.ScrolledWindow):
class ScrolledWindow(StateMixin, Gtk.ScrolledWindow):
def state_set(self, record):
# Force to show first to ensure it is displayed in the Notebook
@@ -84,7 +84,7 @@ class ScrolledWindow(StateMixin, gtk.ScrolledWindow):
super(ScrolledWindow, self).state_set(record)
class Notebook(StateMixin, gtk.Notebook):
class Notebook(StateMixin, Gtk.Notebook):
def state_set(self, record):
super(Notebook, self).state_set(record)
@@ -98,20 +98,20 @@ class Notebook(StateMixin, gtk.Notebook):
widget._readonly_set(True)
class Alignment(gtk.Alignment):
class Alignment(Gtk.Alignment):
def __init__(self, widget, attrs):
super(Alignment, self).__init__(
float(attrs.get('xalign', 0.0)),
float(attrs.get('yalign', 0.5)),
float(attrs.get('xexpand', 1.0)),
float(attrs.get('yexpand', 1.0)))
super(Alignment, self).__init__()
self.props.xalign = float(attrs.get('xalign', 0.0))
self.props.yalign = float(attrs.get('yalign', 0.5))
self.props.xscale = float(attrs.get('xexpand', 1.0))
self.props.yscale = float(attrs.get('yexpand', 1.0))
self.add(widget)
widget.connect('show', lambda *a: self.show())
widget.connect('hide', lambda *a: self.hide())
class Expander(StateMixin, gtk.Expander):
class Expander(StateMixin, Gtk.Expander):
def __init__(self, label=None, attrs=None):
if not label:
@@ -2,15 +2,16 @@
# this repository contains the full copyright notices and license terms.
import logging
import gtk
from .widget import Widget, TranslateMixin
from tryton.config import CONFIG
from gi.repository import Gtk
try:
from gi.repository import GtkSpell
except ImportError:
GtkSpell = None
from .widget import Widget, TranslateMixin
from tryton.config import CONFIG
logger = logging.getLogger(__name__)
@@ -20,11 +21,11 @@ class TextBox(Widget, TranslateMixin):
def __init__(self, view, attrs):
super(TextBox, self).__init__(view, attrs)
self.widget = gtk.VBox()
self.scrolledwindow = gtk.ScrolledWindow()
self.scrolledwindow.set_policy(gtk.POLICY_AUTOMATIC,
gtk.POLICY_AUTOMATIC)
self.scrolledwindow.set_shadow_type(gtk.SHADOW_ETCHED_IN)
self.widget = Gtk.VBox()
self.scrolledwindow = Gtk.ScrolledWindow()
self.scrolledwindow.set_policy(
Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
self.scrolledwindow.set_shadow_type(Gtk.ShadowType.ETCHED_IN)
self.scrolledwindow.set_size_request(100, 100)
self.textview = self.mnemonic_widget = self._get_textview()
@@ -37,33 +38,35 @@ class TextBox(Widget, TranslateMixin):
self.button = None
if attrs.get('translate'):
self.button = self.translate_button()
self.widget.pack_end(self.button, False, False)
self.widget.pack_end(
self.button, expand=False, fill=False, padding=0)
self.widget.pack_end(self.scrolledwindow)
self.widget.pack_end(
self.scrolledwindow, expand=True, fill=True, padding=0)
def _get_textview(self):
if self.attrs.get('size'):
textbuffer = TextBufferLimitSize(int(self.attrs['size']))
textview = gtk.TextView()
textview = Gtk.TextView()
textview.set_buffer(textbuffer)
else:
textview = gtk.TextView()
textview.set_wrap_mode(gtk.WRAP_WORD)
textview = Gtk.TextView()
textview.set_wrap_mode(Gtk.WrapMode.WORD)
# TODO better tab solution
textview.set_accepts_tab(False)
return textview
def translate_widget(self):
box = gtk.VBox()
scrolledwindow = gtk.ScrolledWindow()
scrolledwindow.set_policy(gtk.POLICY_AUTOMATIC,
gtk.POLICY_AUTOMATIC)
scrolledwindow.set_shadow_type(gtk.SHADOW_ETCHED_IN)
box = Gtk.VBox()
scrolledwindow = Gtk.ScrolledWindow()
scrolledwindow.set_policy(
Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
scrolledwindow.set_shadow_type(Gtk.ShadowType.ETCHED_IN)
scrolledwindow.set_size_request(-1, 80)
textview = self._get_textview()
scrolledwindow.add(textview)
box.pack_end(scrolledwindow)
box.pack_end(scrolledwindow, expand=True, fill=True, padding=0)
return box
def translate_widget_set(self, widget, value):
@@ -141,7 +144,7 @@ class TextBox(Widget, TranslateMixin):
checker.detach()
class TextBufferLimitSize(gtk.TextBuffer):
class TextBufferLimitSize(Gtk.TextBuffer):
__gsignals__ = {
'insert-text': 'override',
}
@@ -154,4 +157,4 @@ class TextBufferLimitSize(gtk.TextBuffer):
free_chars = self.max_length - self.get_char_count()
text = text[0:free_chars]
length = len(text)
return gtk.TextBuffer.do_insert_text(self, iter, text, length)
return Gtk.TextBuffer.do_insert_text(self, iter, text, length)
@@ -1,6 +1,6 @@
# 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 gi.repository import Gtk
from tryton.config import CONFIG
from tryton.common.entry_position import reset_position
@@ -12,15 +12,15 @@ class TimeDelta(Widget):
def __init__(self, view, attrs):
super(TimeDelta, self).__init__(view, attrs)
self.widget = gtk.HBox()
self.entry = self.mnemonic_widget = gtk.Entry()
self.widget = Gtk.HBox()
self.entry = self.mnemonic_widget = Gtk.Entry()
self.entry.set_alignment(1.0)
self.entry.set_property('activates_default', True)
self.entry.connect('activate', self.sig_activate)
self.entry.connect('focus-out-event', lambda x, y: self._focus_out())
self.entry.connect('key-press-event', self.send_modified)
self.widget.pack_start(self.entry)
self.widget.pack_start(self.entry, expand=True, fill=True, padding=0)
@property
def modified(self):
@@ -1,8 +1,10 @@
# 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 .char import Char
import webbrowser
from gi.repository import Gtk
from .char import Char
import tryton.common as common
from tryton.config import CONFIG
@@ -14,13 +16,13 @@ class URL(Char):
super(URL, self).__init__(view, attrs)
self.tooltips = common.Tooltips()
self.button = gtk.Button()
self.button = Gtk.Button()
self.button.set_image(common.IconFactory.get_image(
'tryton-public', gtk.ICON_SIZE_SMALL_TOOLBAR))
self.button.set_relief(gtk.RELIEF_NONE)
'tryton-public', Gtk.IconSize.SMALL_TOOLBAR))
self.button.set_relief(Gtk.ReliefStyle.NONE)
self.button.connect('clicked', self.button_clicked)
self.button.set_alignment(0.5, 0.5)
self.widget.pack_start(self.button, expand=False, fill=False)
self.widget.pack_start(
self.button, expand=False, fill=False, padding=0)
self.widget.set_focus_chain([self.entry])
def display(self):
@@ -34,7 +36,7 @@ class URL(Char):
else:
value = icon
self.button.set_image(common.IconFactory.get_image(
value, gtk.ICON_SIZE_SMALL_TOOLBAR))
value, Gtk.IconSize.SMALL_TOOLBAR))
def set_tooltips(self):
value = self.entry.get_text()
@@ -1,9 +1,9 @@
# 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 gobject
import gettext
from gi.repository import Gdk, GLib, Gtk
import tryton.common as common
from tryton.common import RPCExecute, RPCException
from tryton.common import TRYTON_ICON
@@ -84,9 +84,9 @@ class Widget(object):
def get_value():
if not self.widget.props.window:
return
gobject.timeout_add(300, send, self.get_value())
GLib.timeout_add(300, send, self.get_value())
# Wait the current event is finished to retreive the value
gobject.idle_add(get_value)
GLib.idle_add(get_value)
return False
def invisible_set(self, value):
@@ -135,44 +135,50 @@ class TranslateDialog(NoModal):
def __init__(self, widget, languages, readonly):
NoModal.__init__(self)
self.widget = widget
self.win = gtk.Dialog(_('Translation'), self.parent,
gtk.DIALOG_DESTROY_WITH_PARENT)
self.win = Gtk.Dialog(
title=_('Translation'), transient_for=self.parent,
destroy_with_parent=True)
Main().add_window(self.win)
self.win.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
self.win.set_position(Gtk.WindowPosition.CENTER_ON_PARENT)
self.win.set_icon(TRYTON_ICON)
self.win.connect('response', self.response)
self.win.set_default_size(-1, self.default_size()[1])
self.accel_group = gtk.AccelGroup()
self.accel_group = Gtk.AccelGroup()
self.win.add_accel_group(self.accel_group)
cancel_button = self.win.add_button(
set_underline(_("Cancel")), gtk.RESPONSE_CANCEL)
cancel_button.set_image(common.IconFactory.get_image(
'tryton-cancel', gtk.ICON_SIZE_BUTTON))
set_underline(_("Cancel")), Gtk.ResponseType.CANCEL)
cancel_button.set_image(
common.IconFactory.get_image('tryton-cancel', Gtk.IconSize.BUTTON))
cancel_button.set_always_show_image(True)
ok_button = self.win.add_button(
set_underline(_("OK")), gtk.RESPONSE_OK)
ok_button.set_image(common.IconFactory.get_image(
'tryton-ok', gtk.ICON_SIZE_BUTTON))
set_underline(_("OK")), Gtk.ResponseType.OK)
ok_button.set_image(
common.IconFactory.get_image('tryton-ok', Gtk.IconSize.BUTTON))
ok_button.set_always_show_image(True)
ok_button.add_accelerator(
'clicked', self.accel_group, gtk.keysyms.Return,
gtk.gdk.CONTROL_MASK, gtk.ACCEL_VISIBLE)
'clicked', self.accel_group, Gdk.KEY_Return,
Gdk.ModifierType.CONTROL_MASK, Gtk.AccelFlags.VISIBLE)
tooltips = common.Tooltips()
self.widgets = {}
table = gtk.Table(len(languages), 4)
table = Gtk.Table(n_rows=len(languages), n_columns=4)
table.set_homogeneous(False)
table.set_col_spacings(3)
table.set_row_spacings(2)
table.set_border_width(1)
for i, language in enumerate(languages):
label = language['name'] + _(':')
label = gtk.Label(label)
label.set_alignment(1.0, 0.0 if self.widget.expand else 0.5)
table.attach(label, 0, 1, i, i + 1, xoptions=gtk.FILL, xpadding=2)
label = Gtk.Label(
label=label,
halign=Gtk.Alignment.END,
valign=(Gtk.Alignment.START if self.widget.expand
else Gtk.Alignment.FILL))
table.attach(
label, 0, 1, i, i + 1,
xoptions=Gtk.AttachOptions.FILL, xpadding=2)
context = dict(
language=language['code'],
@@ -201,31 +207,35 @@ class TranslateDialog(NoModal):
self.widget.translate_widget_set_readonly(widget, True)
yopt = 0
if self.widget.expand:
yopt = gtk.EXPAND | gtk.FILL
yopt = Gtk.AttachOptions.EXPAND | Gtk.AttachOptions.FILL
table.attach(widget, 1, 2, i, i + 1, yoptions=yopt)
editing = gtk.CheckButton()
editing = Gtk.CheckButton()
editing.connect('toggled', self.editing_toggled, widget)
editing.props.sensitive = not readonly
tooltips.set_tip(editing, _('Edit'))
table.attach(editing, 2, 3, i, i + 1, xoptions=gtk.FILL)
fuzzy = gtk.CheckButton()
table.attach(
editing, 2, 3, i, i + 1, xoptions=Gtk.AttachOptions.FILL)
fuzzy = Gtk.CheckButton()
fuzzy.set_active(value != fuzzy_value)
fuzzy.props.sensitive = False
tooltips.set_tip(fuzzy, _('Fuzzy'))
table.attach(fuzzy, 4, 5, i, i + 1, xoptions=gtk.FILL)
table.attach(
fuzzy, 4, 5, i, i + 1, xoptions=Gtk.AttachOptions.FILL)
self.widgets[language['code']] = (widget, editing, fuzzy)
tooltips.enable()
vbox = gtk.VBox()
vbox.pack_start(table, self.widget.expand, True)
viewport = gtk.Viewport()
viewport.set_shadow_type(gtk.SHADOW_NONE)
vbox = Gtk.VBox()
vbox.pack_start(table, expand=self.widget.expand, fill=True, padding=0)
viewport = Gtk.Viewport()
viewport.set_shadow_type(Gtk.ShadowType.NONE)
viewport.add(vbox)
scrolledwindow = gtk.ScrolledWindow()
scrolledwindow.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
scrolledwindow.set_shadow_type(gtk.SHADOW_NONE)
scrolledwindow = Gtk.ScrolledWindow()
scrolledwindow.set_policy(
Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
scrolledwindow.set_shadow_type(Gtk.ShadowType.NONE)
scrolledwindow.add(viewport)
self.win.vbox.pack_start(scrolledwindow, True, True)
self.win.vbox.pack_start(
scrolledwindow, expand=True, fill=True, padding=0)
self.win.show_all()
self.register()
@@ -236,7 +246,7 @@ class TranslateDialog(NoModal):
not editing.get_active())
def response(self, win, response):
if response == gtk.RESPONSE_OK:
if response == Gtk.ResponseType.OK:
for code, widget in self.widgets.items():
widget, editing, fuzzy = widget
if not editing.get_active():
@@ -271,10 +281,10 @@ class TranslateDialog(NoModal):
class TranslateMixin:
def translate_button(self):
button = gtk.Button()
button = Gtk.Button()
button.set_image(common.IconFactory.get_image(
'tryton-translate', gtk.ICON_SIZE_SMALL_TOOLBAR))
button.set_relief(gtk.RELIEF_NONE)
'tryton-translate', Gtk.IconSize.SMALL_TOOLBAR))
button.set_relief(Gtk.ReliefStyle.NONE)
button.connect('clicked', self.translate)
return button
+41 -31
View File
@@ -2,9 +2,10 @@
# this repository contains the full copyright notices and license terms.
import sys
import gtk
import gettext
from gi.repository import Gtk
from . import View
from .graph_gtk.bar import VerticalBar, HorizontalBar
from .graph_gtk.line import Line
@@ -54,7 +55,7 @@ class ViewGraph(View):
Widget = self.get_widget(self.attributes.get('type', 'vbar'))
widget = Widget(self, xfield, yfields)
self.widgets['root'] = widget
event = gtk.EventBox()
event = Gtk.EventBox()
event.add(widget)
event.connect('button-press-event', self.button_press)
return event
@@ -99,44 +100,50 @@ class ViewGraph(View):
def save(self, widget):
parent = get_toplevel_window()
dia = gtk.Dialog(_('Image Size'), parent,
gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT)
dia = Gtk.Dialog(
title=_('Image Size'), transient_for=parent, modal=True,
destroy_with_parent=True)
Main().add_window(dia)
cancel_button = dia.add_button(
set_underline(_("Cancel")), gtk.RESPONSE_CANCEL)
set_underline(_("Cancel")), Gtk.ResponseType.CANCEL)
cancel_button.set_image(IconFactory.get_image(
'tryton-cancel', gtk.ICON_SIZE_BUTTON))
'tryton-cancel', Gtk.IconSize.BUTTON))
cancel_button.set_always_show_image(True)
ok_button = dia.add_button(
set_underline(_("OK")), gtk.RESPONSE_OK)
set_underline(_("OK")), Gtk.ResponseType.OK)
ok_button.set_image(IconFactory.get_image(
'tryton-ok', gtk.ICON_SIZE_BUTTON))
'tryton-ok', Gtk.IconSize.BUTTON))
ok_button.set_always_show_image(True)
dia.set_icon(TRYTON_ICON)
dia.set_default_response(gtk.RESPONSE_OK)
dia.set_default_response(Gtk.ResponseType.OK)
hbox = gtk.HBox(spacing=3)
dia.vbox.pack_start(hbox, False, True)
hbox = Gtk.HBox(spacing=3)
dia.vbox.pack_start(hbox, expand=False, fill=True, padding=0)
hbox.pack_start(gtk.Label(_('Width:')), False, True)
spinwidth = gtk.SpinButton()
spinwidth.configure(gtk.Adjustment(400.0, 0.0, sys.maxsize, 1.0, 10.0),
hbox.pack_start(
Gtk.Label(label=_('Width:')), expand=False, fill=True, padding=0)
spinwidth = Gtk.SpinButton()
spinwidth.configure(Gtk.Adjustment(
value=400.0, lower=0.0, upper=sys.maxsize,
step_increment=1.0, page_increment=10.0),
climb_rate=1, digits=0)
spinwidth.set_numeric(True)
spinwidth.set_activates_default(True)
hbox.pack_start(spinwidth, True, True)
hbox.pack_start(spinwidth, expand=True, fill=True, padding=0)
hbox.pack_start(gtk.Label(_('Height:')), False, True)
spinheight = gtk.SpinButton()
spinheight.configure(gtk.Adjustment(
200.0, 0.0, sys.maxsize, 1.0, 10.0),
hbox.pack_start(
Gtk.Label(label=_('Height:')), expand=False, fill=True, padding=0)
spinheight = Gtk.SpinButton()
spinheight.configure(Gtk.Adjustment(
value=200.0, lower=0.0, upper=sys.maxsize,
step_increment=1.0, page_increment=10.0),
climb_rate=1, digits=0)
spinheight.set_numeric(True)
spinheight.set_activates_default(True)
hbox.pack_start(spinheight, True, True)
hbox.pack_start(spinheight, expand=True, fill=True, padding=0)
dia.show_all()
filter = gtk.FileFilter()
filter = Gtk.FileFilter()
filter.set_name(_('PNG image (*.png)'))
filter.add_mime_type('image/png')
filter.add_pattern('*.png')
@@ -145,9 +152,10 @@ class ViewGraph(View):
response = dia.run()
width = spinwidth.get_value_as_int()
height = spinheight.get_value_as_int()
if response == gtk.RESPONSE_OK:
filename = file_selection(_('Save As'),
action=gtk.FILE_CHOOSER_ACTION_SAVE,
if response == Gtk.ResponseType.OK:
filename = file_selection(
_('Save As'),
action=Gtk.FileChooserAction.SAVE,
preview=False,
filters=[filter])
if width and height and filename:
@@ -158,8 +166,9 @@ class ViewGraph(View):
filename, width, height)
break
except MemoryError:
message(_('Image size too large.'), dia,
gtk.MESSAGE_ERROR)
message(
_('Image size too large.'), dia,
Gtk.MessageType.ERROR)
else:
break
parent.present()
@@ -167,14 +176,15 @@ class ViewGraph(View):
def button_press(self, widget, event):
if event.button == 3:
menu = gtk.Menu()
item = gtk.ImageMenuItem(_('Save As...'))
item.set_image(IconFactory.get_image(
'tryton-save-as', gtk.ICON_SIZE_MENU))
menu = Gtk.Menu()
item = Gtk.MenuItem(label=_('Save As...'))
item.connect('activate', self.save)
item.show()
menu.append(item)
menu.popup(None, None, None, event.button, event.time)
if hasattr(menu, 'popup_at_pointer'):
menu.popup_at_pointer(event)
else:
menu.popup(None, None, None, event.button, event.time)
return True
elif event.button == 1:
self.widgets['root'].action()
@@ -2,31 +2,31 @@
# this repository contains the full copyright notices and license terms.
# This code is inspired by the pycha project
# (http://www.lorenzogil.com/projects/pycha/)
import gtk
from functools import reduce
from tryton.common import hex2rgb, generateColorscheme, \
COLOR_SCHEMES
from tryton.pyson import PYSONDecoder
import datetime
import locale
import math
import datetime
from dateutil.relativedelta import relativedelta
import tryton.rpc as rpc
from functools import reduce
import cairo
from gi.repository import Gdk, Gtk
import tryton.rpc as rpc
from tryton.action import Action
from tryton.common import hex2rgb, generateColorscheme, COLOR_SCHEMES
from tryton.gui.window import Window
from tryton.pyson import PYSONDecoder
class Popup(object):
def __init__(self, widget):
self.win = gtk.Window(gtk.WINDOW_POPUP)
self.win = Gtk.Window(type=Gtk.WindowType.POPUP)
self.win.set_name('gtk-tooltips')
self.win.set_resizable(False)
self.win.set_border_width(1)
self.win.set_transient_for(widget.window)
self.label = gtk.Label()
self.win.set_transient_for(widget.props.window)
self.label = Gtk.Label()
self.win.add(self.label)
self.win.connect('enter-notify-event', self.enter)
@@ -34,7 +34,7 @@ class Popup(object):
self.label.set_text(text)
def set_position(self, widget, x, y):
widget_x, widget_y = widget.window.get_origin()
origin = widget.props.window.get_origin()
allocation = widget.get_allocation()
width, height = allocation.width, allocation.height
popup_width, popup_height = self.win.get_size()
@@ -42,14 +42,14 @@ class Popup(object):
x = popup_width // 2
if x > width - popup_width // 2:
x = width - popup_width // 2
pos_x = widget_x + x - popup_width // 2
pos_x = origin.x + x - popup_width // 2
if pos_x < 0:
pos_x = 0
if y < popup_height + 5:
y = popup_height + 5
if y > height:
y = height
pos_y = widget_y + y - popup_height - 5
pos_y = origin.y + y - popup_height - 5
if pos_y < 0:
pos_y = 0
self.win.move(int(pos_x), int(pos_y))
@@ -67,7 +67,7 @@ class Popup(object):
self.win.hide()
class Graph(gtk.DrawingArea):
class Graph(Gtk.DrawingArea):
'Graph'
__gsignals__ = {"draw": "override"}
@@ -82,7 +82,7 @@ class Graph(gtk.DrawingArea):
self.bottomPadding = 15
self.rightPadding = 30
self.leftPadding = 30
self.set_events(gtk.gdk.POINTER_MOTION_MASK)
self.set_events(Gdk.EventMask.POINTER_MOTION_MASK)
self.connect('motion-notify-event', self.motion)
self.connect('leave-notify-event', self.leave)
self.popup = Popup(self)
@@ -106,7 +106,6 @@ class Graph(gtk.DrawingArea):
self.popup.hide()
def do_draw(self, cr):
cr = self.window.cairo_create()
width = self.get_allocated_width()
height = self.get_allocated_height()
@@ -142,10 +141,10 @@ class Graph(gtk.DrawingArea):
del ctx['active_ids']
if 'active_id' in ctx:
del ctx['active_id']
event = gtk.get_current_event()
event = Gtk.get_current_event()
allow_similar = False
if (event.state & gtk.gdk.CONTROL_MASK
or event.state & gtk.gdk.MOD1_MASK):
if (event.state & Gdk.ModifierType.CONTROL_MASK
or event.state & Gdk.ModifierType.MOD1_MASK):
allow_similar = True
with Window(hide_current=True, allow_similar=allow_similar):
return Action.exec_keyword('graph_open', {
+100 -96
View File
@@ -1,7 +1,5 @@
# 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 gobject
import gtk
import sys
import json
import locale
@@ -9,6 +7,9 @@ import gettext
from functools import wraps
from collections import defaultdict
from gi.repository import Gdk, GLib, GObject, Gtk
from pygtkcompat.generictreemodel import GenericTreeModel
from tryton.config import CONFIG
from tryton.common.cellrendererbutton import CellRendererButton
from tryton.gui.window import Window
@@ -37,7 +38,7 @@ def delay(func):
if self.treeview.display_counter == display_counter:
func(self, *args, **kwargs)
display_counter = self.treeview.display_counter
gobject.idle_add(wait)
GLib.idle_add(wait)
return wrapper
@@ -57,7 +58,7 @@ def path_convert_id2pos(model, id_path):
return tuple(indexes)
class AdaptModelGroup(gtk.GenericTreeModel):
class AdaptModelGroup(GenericTreeModel):
def __init__(self, group, children_field=None):
super(AdaptModelGroup, self).__init__()
@@ -154,7 +155,7 @@ class AdaptModelGroup(gtk.GenericTreeModel):
prev = record
if prev:
prev.next[id(self.group)] = None
path = gtk.TreePath()
path = Gtk.TreePath()
# XXX pygobject does not allow to create empty TreePath,
# it is always a path of 0
# see: https://bugzilla.gnome.org/show_bug.cgi?id=770665
@@ -168,7 +169,7 @@ class AdaptModelGroup(gtk.GenericTreeModel):
def on_get_flags(self):
if not self.children_field:
return gtk.TREE_MODEL_LIST_ONLY
return Gtk.TreeModelFlags.LIST_ONLY
return 0
def on_get_n_columns(self):
@@ -177,7 +178,7 @@ class AdaptModelGroup(gtk.GenericTreeModel):
def on_get_column_type(self, index):
# XXX
return gobject.TYPE_PYOBJECT
return GObject.TYPE_PYOBJECT
def on_get_path(self, record):
return record.get_index_path(self.group)
@@ -258,14 +259,14 @@ class ViewTree(View):
self.state_widgets = []
self.children_field = children_field
self.sum_widgets = []
self.sum_box = gtk.HBox()
self.sum_box = Gtk.HBox()
self.reload = False
if self.attributes.get('editable') and not screen.readonly:
self.treeview = EditableTreeView(self.attributes['editable'], self)
grid_lines = gtk.TREE_VIEW_GRID_LINES_BOTH
grid_lines = Gtk.TreeViewGridLines.BOTH
else:
self.treeview = TreeView(self)
grid_lines = gtk.TREE_VIEW_GRID_LINES_VERTICAL
grid_lines = Gtk.TreeViewGridLines.VERTICAL
self.mnemonic_widget = self.treeview
self.parse(xml)
@@ -273,7 +274,7 @@ class ViewTree(View):
self.treeview.set_property('rules-hint', True)
self.treeview.set_property('enable-grid-lines', grid_lines)
self.treeview.set_fixed_height_mode(
all(c.get_sizing() == gtk.TREE_VIEW_COLUMN_FIXED
all(c.get_sizing() == Gtk.TreeViewColumnSizing.FIXED
for c in self.treeview.get_columns()))
self.treeview.connect('button-press-event', self.__button_press)
self.treeview.connect('key-press-event', self.on_keypress)
@@ -284,23 +285,25 @@ class ViewTree(View):
self.treeview.set_rubber_banding(True)
selection = self.treeview.get_selection()
selection.set_mode(gtk.SELECTION_MULTIPLE)
selection.set_mode(Gtk.SelectionMode.MULTIPLE)
selection.connect('changed', self.__select_changed)
self.set_drag_and_drop()
self.widget = gtk.VBox()
self.scroll = scroll = gtk.ScrolledWindow()
self.widget = Gtk.VBox()
self.scroll = scroll = Gtk.ScrolledWindow()
scroll.add(self.treeview)
scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
scroll.set_placement(gtk.CORNER_TOP_LEFT)
viewport = gtk.Viewport()
viewport.set_shadow_type(gtk.SHADOW_ETCHED_IN)
scroll.set_policy(
Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
scroll.set_placement(Gtk.CornerType.TOP_LEFT)
viewport = Gtk.Viewport()
viewport.set_shadow_type(Gtk.ShadowType.ETCHED_IN)
viewport.add(scroll)
self.widget.pack_start(viewport, expand=True, fill=True)
self.widget.pack_start(viewport, expand=True, fill=True, padding=0)
self.sum_box.show()
self.widget.pack_start(self.sum_box, expand=False, fill=False)
self.widget.pack_start(
self.sum_box, expand=False, fill=False, padding=0)
self.display()
@@ -342,7 +345,7 @@ class ViewTree(View):
widget = Widget(self, node_attrs)
self.widgets[name].append(widget)
column = gtk.TreeViewColumn(node_attrs['string'])
column = Gtk.TreeViewColumn(node_attrs['string'])
column._type = 'field'
column.name = name
@@ -394,7 +397,7 @@ class ViewTree(View):
widget = Button(self, node_attrs)
self.state_widgets.append(widget)
column = gtk.TreeViewColumn(node_attrs.get('string', ''),
column = Gtk.TreeViewColumn(node_attrs.get('string', ''),
widget.renderer)
column._type = 'button'
column.name = None
@@ -441,8 +444,8 @@ class ViewTree(View):
def set_column_widget(self, column, field, attributes,
arrow=True, align=0.5):
hbox = gtk.HBox(False, 2)
label = gtk.Label(attributes['string'])
hbox = Gtk.HBox(homogeneous=False, spacing=2)
label = Gtk.Label(label=attributes['string'])
if field and self.editable:
required = field.attrs.get('required')
readonly = field.attrs.get('readonly')
@@ -458,12 +461,14 @@ class ViewTree(View):
tooltips.set_tip(label, help)
tooltips.enable()
if arrow:
arrow_widget = gtk.Arrow(gtk.ARROW_NONE, gtk.SHADOW_NONE)
arrow_widget = Gtk.Arrow(
arrow_type=Gtk.ArrowType.NONE, shadow_type=Gtk.ShadowType.NONE)
arrow_widget.show()
column.arrow = arrow_widget
hbox.pack_start(label, True, True, 0)
hbox.pack_start(label, expand=True, fill=True, padding=0)
if arrow:
hbox.pack_start(arrow_widget, False, False, 0)
hbox.pack_start(
arrow_widget, expand=False, fill=False, padding=0)
column.set_clickable(True)
hbox.show()
column.set_widget(hbox)
@@ -505,7 +510,7 @@ class ViewTree(View):
column.set_expand(expand)
column.set_resizable(True)
if attributes.get('widget') != 'text':
column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
column.set_sizing(Gtk.TreeViewColumnSizing.FIXED)
def get_column_widget(self, column):
'Return the widget of the column'
@@ -517,30 +522,30 @@ class ViewTree(View):
if 'sum' not in attributes:
return
text = attributes['sum'] + _(':')
label, sum_ = gtk.Label(text), gtk.Label()
label, sum_ = Gtk.Label(label=text), Gtk.Label()
hbox = gtk.HBox()
hbox = Gtk.HBox()
hbox.pack_start(label, expand=True, fill=False, padding=2)
hbox.pack_start(sum_, expand=True, fill=False, padding=2)
hbox.show_all()
self.sum_box.pack_start(hbox, expand=False, fill=False)
self.sum_box.pack_start(hbox, expand=False, fill=False, padding=0)
self.sum_widgets.append((attributes['name'], sum_))
def sort_model(self, column):
for col in self.treeview.get_columns():
if col != column and getattr(col, 'arrow', None):
col.arrow.set(gtk.ARROW_NONE, gtk.SHADOW_NONE)
col.arrow.set(Gtk.ArrowType.NONE, Gtk.ShadowType.NONE)
self.screen.order = self.screen.default_order
if column.arrow.props.arrow_type == gtk.ARROW_NONE:
column.arrow.set(gtk.ARROW_DOWN, gtk.SHADOW_IN)
if column.arrow.props.arrow_type == Gtk.ArrowType.NONE:
column.arrow.set(Gtk.ArrowType.DOWN, Gtk.ShadowType.IN)
self.screen.order = [(column.name, 'ASC')]
else:
if column.arrow.props.arrow_type == gtk.ARROW_DOWN:
column.arrow.set(gtk.ARROW_UP, gtk.SHADOW_IN)
if column.arrow.props.arrow_type == Gtk.ArrowType.DOWN:
column.arrow.set(Gtk.ArrowType.UP, Gtk.ShadowType.IN)
self.screen.order = [(column.name, 'DESC')]
else:
column.arrow.set(gtk.ARROW_NONE, gtk.SHADOW_NONE)
column.arrow.set(Gtk.ArrowType.NONE, Gtk.ShadowType.NONE)
model = self.treeview.get_model()
unsaved_records = [x for x in model.group if x.id < 0]
search_string = self.screen.screen_container.get_text() or ''
@@ -558,8 +563,8 @@ class ViewTree(View):
if order and len(order) == 1:
(name, direction), = order
direction = {
'ASC': gtk.ARROW_DOWN,
'DESC': gtk.ARROW_UP,
'ASC': Gtk.ArrowType.DOWN,
'DESC': Gtk.ArrowType.UP,
}[direction]
else:
name, direction = None, None
@@ -568,19 +573,19 @@ class ViewTree(View):
arrow = getattr(col, 'arrow', None)
if arrow:
if col.name != name:
arrow.set(gtk.ARROW_NONE, gtk.SHADOW_NONE)
arrow.set(Gtk.ArrowType.NONE, Gtk.ShadowType.NONE)
else:
arrow.set(direction, gtk.SHADOW_IN)
arrow.set(direction, Gtk.ShadowType.IN)
def add_last_column(self):
for column in self.treeview.get_columns():
if column.get_expand():
break
else:
column = gtk.TreeViewColumn()
column = Gtk.TreeViewColumn()
column._type = 'fill'
column.name = None
column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
column.set_sizing(Gtk.TreeViewColumnSizing.FIXED)
self.treeview.append_column(column)
def set_drag_and_drop(self):
@@ -602,20 +607,20 @@ class ViewTree(View):
return
self.treeview.enable_model_drag_dest(
[('MY_TREE_MODEL_ROW', gtk.TARGET_SAME_WIDGET, 0)],
gtk.gdk.ACTION_MOVE)
[('MY_TREE_MODEL_ROW', Gtk.TargetFlags.SAME_WIDGET, 0)],
Gdk.DragAction.MOVE)
self.treeview.enable_model_drag_source(
gtk.gdk.BUTTON1_MASK | gtk.gdk.BUTTON3_MASK,
[('MY_TREE_MODEL_ROW', gtk.TARGET_SAME_WIDGET, 0)],
gtk.gdk.ACTION_MOVE)
Gdk.ModifierType.BUTTON1_MASK | Gdk.ModifierType.BUTTON3_MASK,
[('MY_TREE_MODEL_ROW', Gtk.TargetFlags.SAME_WIDGET, 0)],
Gdk.DragAction.MOVE)
# XXX have to set manually because enable_model_drag_source
# does not set the mask
# https://bugzilla.gnome.org/show_bug.cgi?id=756177
self.treeview.drag_source_set(
gtk.gdk.BUTTON1_MASK | gtk.gdk.BUTTON3_MASK,
[gtk.TargetEntry.new(
'MY_TREE_MODEL_ROW', gtk.TARGET_SAME_WIDGET, 0)],
gtk.gdk.ACTION_MOVE)
Gdk.ModifierType.BUTTON1_MASK | Gdk.ModifierType.BUTTON3_MASK,
[Gtk.TargetEntry.new(
'MY_TREE_MODEL_ROW', Gtk.TargetFlags.SAME_WIDGET, 0)],
Gdk.DragAction.MOVE)
self.treeview.connect("drag-data-get", self.drag_data_get)
self.treeview.connect('drag-data-received',
@@ -640,14 +645,14 @@ class ViewTree(View):
if isinstance(b.renderer, CellRendererButton)]
def on_keypress(self, widget, event):
control_mask = gtk.gdk.CONTROL_MASK
control_mask = Gdk.ModifierType.CONTROL_MASK
if sys.platform == 'darwin':
control_mask = gtk.gdk.MOD2_MASK
if (event.keyval == gtk.keysyms.c
control_mask = Gdk.ModifierType.MOD2_MASK
if (event.keyval == Gdk.KEY_c
and event.state & control_mask):
self.on_copy()
return False
if (event.keyval == gtk.keysyms.v
if (event.keyval == Gdk.KEY_v
and event.state & control_mask):
self.on_paste()
return False
@@ -674,8 +679,8 @@ class ViewTree(View):
return False
def on_copy(self):
for clipboard_type in (gtk.gdk.SELECTION_CLIPBOARD,
gtk.gdk.SELECTION_PRIMARY):
for clipboard_type in [
Gdk.SELECTION_CLIPBOARD, Gdk.SELECTION_PRIMARY]:
clipboard = self.treeview.get_clipboard(clipboard_type)
selection = self.treeview.get_selection()
data = []
@@ -704,8 +709,8 @@ class ViewTree(View):
return value[1:-1]
return value
data = []
for clipboard_type in (gtk.gdk.SELECTION_CLIPBOARD,
gtk.gdk.SELECTION_PRIMARY):
for clipboard_type in [
Gdk.SELECTION_CLIPBOARD, Gdk.SELECTION_PRIMARY]:
clipboard = self.treeview.get_clipboard(clipboard_type)
text = clipboard.wait_for_text()
if not text:
@@ -751,7 +756,7 @@ class ViewTree(View):
def drag_data_get(self, treeview, context, selection, target_id,
etime):
treeview.emit_stop_by_name('drag-data-get')
treeview.stop_emission_by_name('drag-data-get')
def _func_sel_get(model, path, iter_, data):
value = model.get_value(iter_, 0)
@@ -767,7 +772,7 @@ class ViewTree(View):
def drag_data_received(self, treeview, context, x, y, selection,
info, etime):
treeview.emit_stop_by_name('drag-data-received')
treeview.stop_emission_by_name('drag-data-received')
if self.attributes.get('sequence'):
field = self.group.fields[self.attributes['sequence']]
for record in self.group:
@@ -786,7 +791,7 @@ class ViewTree(View):
# internal state of the cursor.
cursor, column = treeview.get_cursor()
if column:
for renderer in column.get_cell_renderers():
for renderer in column.get_cells():
if renderer.props.editing:
return
@@ -811,36 +816,34 @@ class ViewTree(View):
if drop_info:
path, position = drop_info
check_path = tuple(path)
if position in (gtk.TREE_VIEW_DROP_BEFORE,
gtk.TREE_VIEW_DROP_AFTER):
if position in [
Gtk.TreeViewDropPosition.BEFORE,
Gtk.TreeViewDropPosition.AFTER]:
check_path = path[:-1]
if not check_recursion(record_path, check_path):
return
if position == gtk.TREE_VIEW_DROP_BEFORE:
if position == Gtk.TreeViewDropPosition.BEFORE:
model.move_before(record, path)
elif position == gtk.TREE_VIEW_DROP_AFTER:
elif position == Gtk.TreeViewDropPosition.AFTER:
model.move_after(record, path)
elif self.children_field:
model.move_into(record, path)
else:
model.move_after(record, (len(model) - 1,))
if hasattr(gtk.gdk, 'drop_finish'):
gtk.gdk.drop_finish(context, False, etime)
else:
context.drop_finish(False, etime)
Gdk.drop_finish(context, False, etime)
if self.attributes.get('sequence'):
record.group.set_sequence(field=self.attributes['sequence'])
return True
def drag_drop(self, treeview, context, x, y, time):
treeview.emit_stop_by_name('drag-drop')
treeview.stop_emission_by_name('drag-drop')
targets = treeview.drag_dest_get_target_list()
target = treeview.drag_dest_find_target(context, targets)
treeview.drag_get_data(context, target, time)
return True
def drag_data_delete(self, treeview, context):
treeview.emit_stop_by_name('drag-data-delete')
treeview.stop_emission_by_name('drag-data-delete')
def __button_press(self, treeview, event):
if event.button == 3:
@@ -850,18 +853,19 @@ class ViewTree(View):
except TypeError:
# Outside row
return False
menu = gtk.Menu()
copy_item = gtk.ImageMenuItem('gtk-copy')
copy_item.set_use_stock(True)
menu = Gtk.Menu()
copy_item = Gtk.MenuItem(label=_('Copy'))
copy_item.connect('activate', lambda x: self.on_copy())
menu.append(copy_item)
if self.editable:
paste_item = gtk.ImageMenuItem('gtk-paste')
paste_item.set_use_stock(True)
paste_item = Gtk.MenuItem(label=_('Paste'))
paste_item.connect('activate', lambda x: self.on_paste())
menu.append(paste_item)
menu.show_all()
menu.popup(None, None, None, event.button, event.time)
if hasattr(menu, 'popup_at_pointer'):
menu.popup_at_pointer(event)
else:
menu.popup(None, None, None, event.button, event.time)
def pop(menu, group, record):
# Don't activate actions if parent is modified
@@ -897,13 +901,13 @@ class ViewTree(View):
selection = treeview.get_selection()
if selection.count_selected_rows() == 1:
group = self.group
if selection.get_mode() == gtk.SELECTION_SINGLE:
if selection.get_mode() == Gtk.SelectionMode.SINGLE:
model = selection.get_selected()[0]
elif selection.get_mode() == gtk.SELECTION_MULTIPLE:
elif selection.get_mode() == Gtk.SelectionMode.MULTIPLE:
model = selection.get_selected_rows()[0]
record = model.get_value(model.get_iter(path), 0)
# Delay filling of popup as it can take time
gobject.idle_add(pop, menu, group, record)
GLib.idle_add(pop, menu, group, record)
return True # Don't change the selection
elif event.button == 2:
with Window(allow_similar=True):
@@ -961,9 +965,9 @@ class ViewTree(View):
if column._type == 'button':
return
allow_similar = False
event = gtk.get_current_event()
if (event.state & gtk.gdk.MOD1_MASK
or event.state & gtk.gdk.SHIFT_MASK):
event = Gtk.get_current_event()
if (event.state & Gdk.ModifierType.MOD1_MASK
or event.state & Gdk.ModifierType.SHIFT_MASK):
allow_similar = True
with Window(allow_similar=allow_similar):
if not self.screen.row_activate() and self.children_field:
@@ -977,7 +981,7 @@ class ViewTree(View):
if previous_record and previous_record not in previous_record.group:
previous_record = None
if tree_sel.get_mode() == gtk.SELECTION_SINGLE:
if tree_sel.get_mode() == Gtk.SelectionMode.SINGLE:
model, iter_ = tree_sel.get_selected()
if model and iter_:
record = model.get_value(iter_, 0)
@@ -985,7 +989,7 @@ class ViewTree(View):
else:
self.record = None
elif tree_sel.get_mode() == gtk.SELECTION_MULTIPLE:
elif tree_sel.get_mode() == Gtk.SelectionMode.MULTIPLE:
model, paths = tree_sel.get_selected_rows()
if model and paths:
iter_ = model.get_iter(paths[0])
@@ -1009,7 +1013,7 @@ class ViewTree(View):
go_previous()
return True
# Delay the save to let GTK process the current event
gobject.idle_add(save)
GLib.idle_add(save)
elif previous_record != self.record and self.screen.pre_validate:
def pre_validate():
@@ -1017,7 +1021,7 @@ class ViewTree(View):
if not previous_record.pre_validate():
go_previous()
# Delay the pre_validate to let GTK process the current event
gobject.idle_add(pre_validate)
GLib.idle_add(pre_validate)
self.update_sum()
def set_value(self):
@@ -1140,18 +1144,18 @@ class ViewTree(View):
model = self.treeview.get_model()
if self.record and model:
path = self.record.get_index_path(model.group)
if model.get_flags() & gtk.TREE_MODEL_LIST_ONLY:
if model.get_flags() & Gtk.TreeModelFlags.LIST_ONLY:
path = (path[0],)
focus_column, focus_cell = self.treeview.next_column(
path, editable=new)
if path[:-1]:
self.treeview.expand_to_path(gtk.TreePath(path[:-1]))
self.treeview.expand_to_path(Gtk.TreePath(path[:-1]))
self.treeview.scroll_to_cell(path, focus_column,
use_align=False)
current_path = self.treeview.get_cursor()[0]
selected_path = \
self.treeview.get_selection().get_selected_rows()[1]
path = gtk.TreePath(path)
path = Gtk.TreePath(path)
if (current_path != path and path not in selected_path) or new:
self.treeview.set_cursor(path, focus_column, new)
@@ -1188,7 +1192,7 @@ class ViewTree(View):
for node in nodes:
path = path_convert_id2pos(model, node)
if path:
selection.select_path(gtk.TreePath(path))
selection.select_path(Gtk.TreePath(path))
if not scroll:
self.treeview.scroll_to_cell(path)
scroll = True
@@ -1203,12 +1207,12 @@ class ViewTree(View):
id_paths = []
model = self.treeview.get_model()
if starting_path:
iter_ = model.get_iter(gtk.TreePath(starting_path))
iter_ = model.get_iter(Gtk.TreePath(starting_path))
else:
iter_ = None
for path_idx in range(model.iter_n_children(iter_)):
path = starting_path + (path_idx,)
expanded = self.treeview.row_expanded(gtk.TreePath(path))
expanded = self.treeview.row_expanded(Gtk.TreePath(path))
if expanded:
iter_ = model.get_iter(path)
expanded_record = model.get_value(iter_, 0)
@@ -1223,4 +1227,4 @@ class ViewTree(View):
for node in nodes:
expand_path = path_convert_id2pos(model, node)
if expand_path:
self.treeview.expand_to_path(gtk.TreePath(expand_path))
self.treeview.expand_to_path(Gtk.TreePath(expand_path))
@@ -1,11 +1,9 @@
# 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 gobject
from itertools import islice, cycle, chain
from gi.repository import Gtk
from gi.repository import Gdk, GLib, Gtk
from tryton.common import MODELACCESS
from tryton.common.datetime_ import Date, Time
@@ -20,7 +18,7 @@ def focusable_cells(column, editable=True):
yield cell
class TreeView(gtk.TreeView):
class TreeView(Gtk.TreeView):
display_counter = 0
def __init__(self, view):
@@ -73,10 +71,10 @@ class TreeView(gtk.TreeView):
class EditableTreeView(TreeView):
leaving_record_events = (gtk.keysyms.Up, gtk.keysyms.Down,
gtk.keysyms.Return)
leaving_events = leaving_record_events + (gtk.keysyms.Tab,
gtk.keysyms.ISO_Left_Tab, gtk.keysyms.KP_Enter)
leaving_record_events = (
Gdk.KEY_Up, Gdk.KEY_Down, Gdk.KEY_Return)
leaving_events = leaving_record_events + (
Gdk.KEY_Tab, Gdk.KEY_ISO_Left_Tab, Gdk.KEY_KP_Enter)
def __init__(self, position, view):
super(EditableTreeView, self).__init__(view)
@@ -137,7 +135,7 @@ class EditableTreeView(TreeView):
self.grab_focus()
if focus_column:
widget = self.view.get_column_widget(focus_column)
if isinstance(widget.renderer, gtk.CellRendererToggle):
if isinstance(widget.renderer, Gtk.CellRendererToggle):
start_editing = False
self.scroll_to_cell(path, focus_column, use_align=False)
if cell:
@@ -150,7 +148,7 @@ class EditableTreeView(TreeView):
path, column = self.get_cursor()
if not path or not column or not column.name:
return True
for renderer in column.get_cell_renderers():
for renderer in column.get_cells():
if renderer.props.editing:
widget = self.view.get_column_widget(column)
self.on_editing_done(widget.editable, renderer)
@@ -163,16 +161,16 @@ class EditableTreeView(TreeView):
self.display_counter += 1 # Force a display
leaving = False
if event.keyval == gtk.keysyms.Right:
if isinstance(entry, gtk.Entry):
if event.keyval == Gdk.KEY_Right:
if isinstance(entry, Gtk.Entry):
if entry.get_position() >= \
len(entry.get_text()) \
and not entry.get_selection_bounds():
leaving = True
else:
leaving = True
elif event.keyval == gtk.keysyms.Left:
if isinstance(entry, gtk.Entry):
elif event.keyval == Gdk.KEY_Left:
if isinstance(entry, Gtk.Entry):
if entry.get_position() <= 0 \
and not entry.get_selection_bounds():
leaving = True
@@ -183,22 +181,30 @@ class EditableTreeView(TreeView):
if isinstance(entry, (Date, Time)):
entry.activate()
txt = entry.props.value
elif isinstance(entry, gtk.Entry):
elif isinstance(entry, Gtk.Entry):
txt = entry.get_text()
elif isinstance(entry, Gtk.ComboBox):
active = entry.get_active()
if active < 0:
txt = None
else:
model = entry.get_model()
index = entry.get_property('entry-text-column')
txt = model[active][index]
else:
txt = entry.get_active_text()
return True
keyval = event.keyval
entry.handler_block(entry.editing_done_id)
def callback():
entry.handler_unblock(entry.editing_done_id)
if (keyval in (gtk.keysyms.Tab, gtk.keysyms.KP_Enter)
or (keyval == gtk.keysyms.Right and leaving)):
gobject.idle_add(self.set_cursor, path,
if (keyval in [Gdk.KEY_Tab, Gdk.KEY_KP_Enter]
or (keyval == Gdk.KEY_Right and leaving)):
GLib.idle_add(self.set_cursor, path,
*self.next_column(path, column, renderer), True)
elif (keyval == gtk.keysyms.ISO_Left_Tab
or (keyval == gtk.keysyms.Left and leaving)):
gobject.idle_add(self.set_cursor, path,
elif (keyval == Gdk.KEY_ISO_Left_Tab
or (keyval == Gdk.KEY_Left and leaving)):
GLib.idle_add(self.set_cursor, path,
*self.prev_column(path, column, renderer), True)
elif keyval in self.leaving_record_events:
fields = list(self.view.widgets.keys())
@@ -208,53 +214,61 @@ class EditableTreeView(TreeView):
for col in self.get_columns():
if col.name in invalid_fields:
break
gobject.idle_add(self.set_cursor, path, col, True)
GLib.idle_add(self.set_cursor, path, col, True)
return
if ((self.view.screen.pre_validate
and not record.pre_validate())
or (not self.view.screen.parent
and not record.save())):
gobject.idle_add(self.set_cursor, path, column,
GLib.idle_add(self.set_cursor, path, column,
True)
return
entry.handler_block(entry.editing_done_id)
if keyval == gtk.keysyms.Up:
if keyval == Gdk.KEY_Up:
self._key_up(path, model, column)
elif keyval == gtk.keysyms.Down:
elif keyval == Gdk.KEY_Down:
self._key_down(path, model, column)
elif keyval == gtk.keysyms.Return:
elif keyval == Gdk.KEY_Return:
if self.editable == 'top':
new_path = self._key_up(path, model)
else:
new_path = self._key_down(path, model)
gobject.idle_add(self.set_cursor, new_path,
GLib.idle_add(self.set_cursor, new_path,
*self.next_column(new_path), True)
entry.handler_unblock(entry.editing_done_id)
else:
gobject.idle_add(self.set_cursor, path, column, True)
GLib.idle_add(self.set_cursor, path, column, True)
self.on_quit_cell(record, column, renderer, txt, callback=callback)
return True
elif event.keyval in (gtk.keysyms.F3, gtk.keysyms.F2):
if isinstance(entry, gtk.Entry):
elif event.keyval in [Gdk.KEY_F3, Gdk.KEY_F2]:
if isinstance(entry, Gtk.Entry):
value = entry.get_text()
elif isinstance(entry, Gtk.ComboBox):
active = entry.get_active()
if active < 0:
value = None
else:
model = entry.get_model()
index = entry.get_property('entry-text-column')
value = model[active][index]
else:
value = entry.get_active_text()
return True
entry.handler_block(entry.editing_done_id)
def callback():
widget = self.view.get_column_widget(column)
value = widget.get_textual_value(record)
if isinstance(entry, gtk.Entry):
if isinstance(entry, Gtk.Entry):
entry.set_text(value)
else:
entry.set_active_text(value)
entry.handler_unblock(entry.editing_done_id)
self.on_open_remote(record, column,
create=(event.keyval == gtk.keysyms.F3), value=value,
create=(event.keyval == Gdk.KEY_F3), value=value,
callback=callback)
else:
field = record[column.name]
if isinstance(entry, gtk.Entry):
if isinstance(entry, Gtk.Entry):
entry.set_max_length(int(field.attrs.get('size', 0)))
record.modified_fields.setdefault(column.name)
return False
@@ -292,7 +306,7 @@ class EditableTreeView(TreeView):
if isinstance(entry, (Date, Time)):
entry.activate()
text = entry.props.value
elif isinstance(entry, (gtk.ComboBoxEntry, gtk.ComboBox)):
elif isinstance(entry, Gtk.ComboBox):
text = entry.get_active_text
else:
text = entry.get_text()
@@ -2,14 +2,12 @@
# this repository contains the full copyright notices and license terms.
import datetime
import os
import gtk
import gettext
import webbrowser
from gi.repository import Gtk, GObject
from functools import wraps, partial
from gi.repository import Gdk, GLib, Gtk
from tryton.gui.window.win_search import WinSearch
from tryton.gui.window.win_form import WinForm
from tryton.gui.window.view_form.screen import Screen
@@ -38,7 +36,7 @@ def send_keys(renderer, editable, position, treeview):
editable.connect('key_press_event', treeview.on_keypressed, renderer)
editable.editing_done_id = editable.connect('editing_done',
treeview.on_editing_done, renderer)
if isinstance(editable, (gtk.ComboBoxEntry, gtk.ComboBox)):
if isinstance(editable, Gtk.ComboBox):
def changed(combobox):
# "changed" signal is also triggered by text editing
# so only trigger editing-done if a row is active
@@ -90,7 +88,7 @@ class CellCache(list):
@classmethod
def cache(cls, func):
@wraps(func)
def wrapper(self, column, cell, store, iter_):
def wrapper(self, column, cell, store, iter_, user_data=None):
if not hasattr(self, 'display_counters'):
self.display_counters = {}
if not hasattr(self, 'cell_caches'):
@@ -99,11 +97,11 @@ class CellCache(list):
counter = self.view.treeview.display_counter
if (self.display_counters.get(record.id) != counter):
if getattr(cell, 'decorated', None):
func(self, column, cell, store, iter_)
func(self, column, cell, store, iter_, user_data)
else:
cache = cls()
cache.decorate(cell)
func(self, column, cell, store, iter_)
func(self, column, cell, store, iter_, user_data)
cache.undecorate(cell)
self.cell_caches[record.id] = cache
self.display_counters[record.id] = counter
@@ -150,14 +148,14 @@ class Affix(Cell):
if not self.icon:
self.icon = 'tryton-public'
elif self.icon:
self.renderer = gtk.CellRendererPixbuf()
self.renderer = Gtk.CellRendererPixbuf()
else:
self.renderer = gtk.CellRendererText()
self.renderer = Gtk.CellRendererText()
self.view = view
@realized
@CellCache.cache
def setter(self, column, cell, store, iter_):
def setter(self, column, cell, store, iter_, user_data=None):
record, field = self._get_record_field_from_iter(iter_, store)
field = record[self.attrs['name']]
field.state_set(record, states=('invisible',))
@@ -168,7 +166,7 @@ class Affix(Cell):
value = record[self.icon].get_client(record) or ''
else:
value = self.icon
pixbuf = common.IconFactory.get_pixbuf(value, gtk.ICON_SIZE_BUTTON)
pixbuf = common.IconFactory.get_pixbuf(value, Gtk.IconSize.BUTTON)
cell.set_property('pixbuf', pixbuf)
else:
text = self.attrs.get('string', '')
@@ -216,7 +214,7 @@ class GenericText(Cell):
@realized
@CellCache.cache
def setter(self, column, cell, store, iter_):
def setter(self, column, cell, store, iter_, user_data=None):
record = store.get_value(iter_, 0)
text = self.get_textual_value(record)
@@ -254,8 +252,9 @@ class GenericText(Cell):
if isinstance(cell, CellRendererToggle):
cell.set_property('activatable', not readonly)
elif isinstance(cell, (gtk.CellRendererProgress,
CellRendererButton, gtk.CellRendererPixbuf)):
elif isinstance(cell,
(Gtk.CellRendererProgress, CellRendererButton,
Gtk.CellRendererPixbuf)):
pass
else:
cell.set_property('editable', not readonly)
@@ -290,8 +289,8 @@ class Char(GenericText):
@realized
@CellCache.cache
def setter(self, column, cell, store, iter_):
super(Char, self).setter(column, cell, store, iter_)
def setter(self, column, cell, store, iter_, user_data=None):
super(Char, self).setter(column, cell, store, iter_, user_data)
cell.set_property('single-paragraph-mode', True)
@@ -345,8 +344,8 @@ class URL(Char):
@realized
@CellCache.cache
def setter(self, column, cell, store, iter_):
super(URL, self).setter(column, cell, store, iter_)
def setter(self, column, cell, store, iter_, user_data=None):
super(URL, self).setter(column, cell, store, iter_, user_data)
record, field = self._get_record_field_from_iter(iter_, store)
field.state_set(record, states=('readonly',))
readonly = field.get_state_attrs(record).get('readonly', False)
@@ -361,10 +360,10 @@ class Date(GenericText):
super(Date, self).__init__(view, attrs, renderer=renderer)
@realized
def setter(self, column, cell, store, iter_):
def setter(self, column, cell, store, iter_, user_data=None):
record, field = self._get_record_field_from_iter(iter_, store)
self.renderer.props.format = self.get_format(record, field)
super(Date, self).setter(column, cell, store, iter_)
super(Date, self).setter(column, cell, store, iter_, user_data)
def get_format(self, record, field):
if field and record:
@@ -419,8 +418,8 @@ class Float(Int):
super(Float, self).__init__(view, attrs, renderer=renderer)
@realized
def setter(self, column, cell, store, iter_):
super(Float, self).setter(column, cell, store, iter_)
def setter(self, column, cell, store, iter_, user_data=None):
super(Float, self).setter(column, cell, store, iter_, user_data)
record, field = self._get_record_field_from_iter(iter_, store)
digits = field.digits(record, factor=self.factor)
cell.digits = digits
@@ -464,7 +463,7 @@ class Binary(GenericText):
@realized
@CellCache.cache
def setter(self, column, cell, store, iter_):
def setter(self, column, cell, store, iter_, user_data=None):
record, field = self._get_record_field_from_iter(iter_, store)
text = self.get_textual_value(record)
cell.set_property('text', text)
@@ -522,14 +521,14 @@ class _BinarySave(_BinaryIcon):
filename_field = record.group.fields.get(self.attrs['filename'])
filename = filename_field.get(record)
filename = file_selection(_('Save As...'), filename=filename,
action=gtk.FILE_CHOOSER_ACTION_SAVE)
action=Gtk.FileChooserAction.SAVE)
if filename:
with open(filename, 'wb') as fp:
fp.write(self.binary.get_data(record, field))
@realized
@CellCache.cache
def setter(self, column, cell, store, iter_):
def setter(self, column, cell, store, iter_, user_data=None):
record, field = self._get_record_field_from_iter(iter_, store)
if hasattr(field, 'get_size'):
size = field.get_size(record)
@@ -564,11 +563,11 @@ class _BinarySelect(_BinaryIcon):
if filename_field:
filename_field.set_client(
record, os.path.basename(filename))
GObject.idle_add(_select)
GLib.idle_add(_select)
@realized
@CellCache.cache
def setter(self, column, cell, store, iter_):
def setter(self, column, cell, store, iter_, user_data=None):
record, field = self._get_record_field_from_iter(iter_, store)
if hasattr(field, 'get_size'):
size = field.get_size(record)
@@ -601,11 +600,11 @@ class _BinaryOpen(_BinarySave):
root, type_ = os.path.splitext(filename)
if type_:
type_ = type_[1:]
GObject.idle_add(file_open, file_path, type_)
GLib.idle_add(file_open, file_path, type_)
@realized
@CellCache.cache
def setter(self, column, cell, store, iter_):
def setter(self, column, cell, store, iter_, user_data=None):
super().setter(column, cell, store, iter_)
record, field = self._get_record_field_from_iter(iter_, store)
filename_field = record.group.fields.get(self.attrs.get('filename'))
@@ -619,14 +618,14 @@ class Image(GenericText):
def __init__(self, view, attrs=None, renderer=None):
if renderer is None:
renderer = gtk.CellRendererPixbuf
renderer = Gtk.CellRendererPixbuf
super(Image, self).__init__(view, attrs, renderer)
self.renderer.set_fixed_size(self.attrs.get('width', -1),
self.attrs.get('height', -1))
@realized
@CellCache.cache
def setter(self, column, cell, store, iter_):
def setter(self, column, cell, store, iter_, user_data=None):
record, field = self._get_record_field_from_iter(iter_, store)
value = field.get_client(record)
if isinstance(value, int):
@@ -682,7 +681,7 @@ class M2O(GenericText):
field = record[self.attrs['name']]
win = self.search_remote(record, field, text, callback=callback)
if len(win.screen.group) == 1:
win.response(None, gtk.RESPONSE_OK)
win.response(None, Gtk.ResponseType.OK)
else:
win.show()
@@ -704,11 +703,11 @@ class M2O(GenericText):
icon1, tooltip1 = None, ''
icon2, tooltip2 = 'tryton-search', _("Search a record <F2>")
for pos, icon, tooltip in [
(gtk.ENTRY_ICON_PRIMARY, icon1, tooltip1),
(gtk.ENTRY_ICON_SECONDARY, icon2, tooltip2)]:
(Gtk.EntryIconPosition.PRIMARY, icon1, tooltip1),
(Gtk.EntryIconPosition.SECONDARY, icon2, tooltip2)]:
if icon:
pixbuf = common.IconFactory.get_pixbuf(
icon, gtk.ICON_SIZE_MENU)
icon, Gtk.IconSize.MENU)
else:
pixbuf = None
editable.set_icon_from_pixbuf(pos, pixbuf)
@@ -718,7 +717,8 @@ class M2O(GenericText):
value = field.get(record)
if not model:
return
if icon_pos == gtk.ENTRY_ICON_SECONDARY and self.has_target(value):
if (icon_pos == Gtk.EntryIconPosition.SECONDARY
and self.has_target(value)):
field.set_client(
record, self.value_from_id(model, None, ''))
editable.set_text('')
@@ -818,8 +818,7 @@ class M2O(GenericText):
def _key_press(self, entry, event, path):
record, field = self._get_record_field_from_path(path)
if (self.has_target(field.get(record))
and event.keyval in (gtk.keysyms.Delete,
gtk.keysyms.BackSpace)):
and event.keyval in [Gdk.KEY_Delete, Gdk.KEY_BackSpace]):
entry.set_text('')
return False
@@ -974,7 +973,14 @@ class Selection(GenericText, SelectionMixin, PopdownMixin):
def set_value(self, editable, record, field):
value = self.get_popdown_value(editable)
if 'relation' in self.attrs and value:
value = (value, editable.get_active_text())
active = editable.get_active()
if active < 0:
text = None
else:
model = editable.get_model()
index = editable.get_property('entry-text-column')
text = model[active][index]
value = (value, text)
field.set_client(record, value)
return False
@@ -1050,28 +1056,26 @@ class _ReferenceSelection(Selection):
class ProgressBar(object):
align = 0.5
orientations = {
'left_to_right': gtk.PROGRESS_LEFT_TO_RIGHT,
'right_to_left': gtk.PROGRESS_RIGHT_TO_LEFT,
'bottom_to_top': gtk.PROGRESS_BOTTOM_TO_TOP,
'top_to_bottom': gtk.PROGRESS_TOP_TO_BOTTOM,
}
'left_to_right': (Gtk.Orientation.HORIZONTAL, False),
'right_to_left': (Gtk.Orientation.HORIZONTAL, True),
'bottom_to_top': (Gtk.Orientation.VERTICAL, True),
'top_to_bottom': (Gtk.Orientation.VERTICAL, False),
}
def __init__(self, view, attrs):
super(ProgressBar, self).__init__()
self.view = view
self.attrs = attrs
self.renderer = gtk.CellRendererProgress()
orientation = self.orientations.get(self.attrs.get('orientation',
'left_to_right'), gtk.PROGRESS_LEFT_TO_RIGHT)
if hasattr(self.renderer, 'set_orientation'):
self.renderer.set_orientation(orientation)
else:
self.renderer.set_property('orientation', orientation)
self.renderer = Gtk.CellRendererProgress()
orientation, inverted = self.orientations.get(
self.attrs.get('orientation', 'left_to_right'))
self.renderer.set_orientation(orientation)
self.renderer.set_property('inverted', inverted)
self.renderer.set_property('yalign', 0)
@realized
@CellCache.cache
def setter(self, column, cell, store, iter_):
def setter(self, column, cell, store, iter_, user_data=None):
record, field = self._get_record_field_from_iter(iter_, store)
field.state_set(record, states=('invisible',))
invisible = field.get_state_attrs(record).get('invisible', False)
@@ -1110,7 +1114,7 @@ class Button(Cell):
@realized
@CellCache.cache
def setter(self, column, cell, store, iter_):
def setter(self, column, cell, store, iter_, user_data=None):
record = store.get_value(iter_, 0)
states = record.expr_eval(self.attrs.get('states', {}))
invisible = states.get('invisible', False)
@@ -1,11 +1,9 @@
# 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 datetime
from gi.repository import Gtk
import gtk
import gettext
import gobject
from gi.repository import Gdk, GLib, GObject, Gtk
import tryton.common as common
from tryton.common.domain_parser import quote
@@ -22,10 +20,11 @@ class Between(Gtk.HBox):
def __init__(self, _entry=Gtk.Entry):
super().__init__()
self.from_ = _entry()
self.pack_start(self.from_, expand=True, fill=True)
self.pack_start(Gtk.Label(_('..')), expand=False, fill=False)
self.pack_start(self.from_, expand=True, fill=True, padding=0)
self.pack_start(
Gtk.Label(label=_('..')), expand=False, fill=False, padding=0)
self.to = _entry()
self.pack_start(self.to, expand=True, fill=True)
self.pack_start(self.to, expand=True, fill=True, padding=0)
if self._changed_signal:
self.from_.connect_after(
@@ -136,26 +135,27 @@ class DateTimes(BetweenDates):
widget.props.date_format + ' ' + widget.props.time_format)
class Selection(gtk.ScrolledWindow):
class Selection(Gtk.ScrolledWindow):
def __init__(self, selections):
super(Selection, self).__init__()
self.treeview = TreeViewControl()
model = gtk.ListStore(gobject.TYPE_STRING)
model = Gtk.ListStore(GObject.TYPE_STRING)
for selection in selections:
model.append((selection,))
self.treeview.set_model(model)
column = gtk.TreeViewColumn()
cell = gtk.CellRendererText()
column.pack_start(cell)
column = Gtk.TreeViewColumn()
cell = Gtk.CellRendererText()
column.pack_start(cell, expand=True)
column.add_attribute(cell, 'text', 0)
self.treeview.append_column(column)
self.treeview.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
self.treeview.get_selection().set_mode(Gtk.SelectionMode.MULTIPLE)
self.treeview.set_headers_visible(False)
self.add(self.treeview)
self.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
self.set_shadow_type(gtk.SHADOW_ETCHED_IN)
self.set_policy(
Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
self.set_shadow_type(Gtk.ShadowType.ETCHED_IN)
self.set_min_content_height(min(20 * len(selections), 200))
self.set_max_content_height(200)
@@ -173,11 +173,11 @@ class Selection(gtk.ScrolledWindow):
class ScreenContainer(object):
def __init__(self, tab_domain):
self.viewport = gtk.Viewport()
self.viewport.set_shadow_type(gtk.SHADOW_NONE)
self.vbox = gtk.VBox(spacing=3)
self.alternate_viewport = gtk.Viewport()
self.alternate_viewport.set_shadow_type(gtk.SHADOW_NONE)
self.viewport = Gtk.Viewport()
self.viewport.set_shadow_type(Gtk.ShadowType.NONE)
self.vbox = Gtk.VBox(spacing=3)
self.alternate_viewport = Gtk.Viewport()
self.alternate_viewport.set_shadow_type(Gtk.ShadowType.NONE)
self.alternate_view = False
self.search_popover = None
self.search_table = None
@@ -187,20 +187,20 @@ class ScreenContainer(object):
tooltips = common.Tooltips()
self.filter_vbox = gtk.VBox(spacing=0)
self.filter_vbox = Gtk.VBox(spacing=0)
self.filter_vbox.set_border_width(0)
hbox = gtk.HBox(homogeneous=False, spacing=0)
hbox = Gtk.HBox(homogeneous=False, spacing=0)
self.search_entry = gtk.Entry()
self.search_entry = Gtk.Entry()
self.search_entry.set_placeholder_text(_('Search'))
self.search_entry.set_alignment(0.0)
self.search_entry.set_icon_from_pixbuf(
gtk.ENTRY_ICON_PRIMARY,
common.IconFactory.get_pixbuf('tryton-filter', gtk.ICON_SIZE_MENU))
Gtk.EntryIconPosition.PRIMARY,
common.IconFactory.get_pixbuf('tryton-filter', Gtk.IconSize.MENU))
self.search_entry.set_icon_tooltip_text(
gtk.ENTRY_ICON_PRIMARY, _('Open filters'))
self.completion = gtk.EntryCompletion()
self.completion.set_model(gtk.ListStore(str))
Gtk.EntryIconPosition.PRIMARY, _('Open filters'))
self.completion = Gtk.EntryCompletion()
self.completion.set_model(Gtk.ListStore(str))
self.completion.set_text_column(0)
self.completion.props.inline_selection = True
self.completion.props.popup_set_width = False
@@ -212,7 +212,7 @@ class ScreenContainer(object):
self.search_entry.connect('focus-in-event', self.focus_in)
self.search_entry.connect('icon-press', self.icon_press)
hbox.pack_start(self.search_entry, expand=True, fill=True)
hbox.pack_start(self.search_entry, expand=True, fill=True, padding=0)
def popup(widget):
menu = widget._menu
@@ -224,76 +224,77 @@ class ScreenContainer(object):
def menu_position(menu, data=None):
widget_allocation = widget.get_allocation()
if hasattr(widget.window, 'get_root_coords'):
x, y = widget.window.get_root_coords(
widget_allocation.x, widget_allocation.y)
else:
x, y = widget.window.get_origin()
x += widget_allocation.x
y += widget_allocation.y
x, y = widget.get_window().get_root_coords(
widget_allocation.x, widget_allocation.y)
return (x, y + widget_allocation.height, False)
for id_, name, domain in self.bookmarks():
menuitem = gtk.MenuItem(name)
menuitem = Gtk.MenuItem(label=name)
menuitem.connect('activate', self.bookmark_activate, domain)
menu.add(menuitem)
menu.show_all()
menu.popup(None, None, menu_position, 0, 0)
if hasattr(menu, 'popup_at_widget'):
menu.popup_at_widget(
widget, Gdk.Gravity.SOUTH_WEST, Gdk.Gravity.NORTH_WEST,
Gtk.get_current_event())
else:
menu.popup(None, None, menu_position, 0, 0)
def deactivate(menuitem, togglebutton):
togglebutton.props.active = False
but_bookmark = gtk.ToggleButton()
but_bookmark = Gtk.ToggleButton()
self.but_bookmark = but_bookmark
tooltips.set_tip(but_bookmark, _('Show bookmarks of filters'))
but_bookmark.add(common.IconFactory.get_image(
'tryton-bookmarks', gtk.ICON_SIZE_SMALL_TOOLBAR))
but_bookmark.set_relief(gtk.RELIEF_NONE)
menu = gtk.Menu()
'tryton-bookmarks', Gtk.IconSize.SMALL_TOOLBAR))
but_bookmark.set_relief(Gtk.ReliefStyle.NONE)
menu = Gtk.Menu()
menu.set_property('reserve-toggle-size', False)
menu.connect('deactivate', deactivate, but_bookmark)
but_bookmark._menu = menu
but_bookmark.connect('toggled', popup)
hbox.pack_start(but_bookmark, expand=False, fill=False)
hbox.pack_start(but_bookmark, expand=False, fill=False, padding=0)
but_active = gtk.ToggleButton()
but_active = Gtk.ToggleButton()
self.but_active = but_active
self._set_active_tooltip()
but_active.add(common.IconFactory.get_image(
'tryton-archive', gtk.ICON_SIZE_SMALL_TOOLBAR))
but_active.set_relief(gtk.RELIEF_NONE)
'tryton-archive', Gtk.IconSize.SMALL_TOOLBAR))
but_active.set_relief(Gtk.ReliefStyle.NONE)
but_active.connect('toggled', self.search_active)
hbox.pack_start(but_active, expand=False, fill=False)
hbox.pack_start(but_active, expand=False, fill=False, padding=0)
but_prev = gtk.Button()
but_prev = Gtk.Button()
self.but_prev = but_prev
tooltips.set_tip(but_prev, _('Previous'))
but_prev.connect('clicked', self.search_prev)
but_prev.add(common.IconFactory.get_image(
'tryton-back', gtk.ICON_SIZE_SMALL_TOOLBAR))
but_prev.set_relief(gtk.RELIEF_NONE)
hbox.pack_start(but_prev, expand=False, fill=False)
'tryton-back', Gtk.IconSize.SMALL_TOOLBAR))
but_prev.set_relief(Gtk.ReliefStyle.NONE)
hbox.pack_start(but_prev, expand=False, fill=False, padding=0)
but_next = gtk.Button()
but_next = Gtk.Button()
self.but_next = but_next
tooltips.set_tip(but_next, _('Next'))
but_next.connect('clicked', self.search_next)
but_next.add(common.IconFactory.get_image(
'tryton-forward', gtk.ICON_SIZE_SMALL_TOOLBAR))
but_next.set_relief(gtk.RELIEF_NONE)
hbox.pack_start(but_next, expand=False, fill=False)
'tryton-forward', Gtk.IconSize.SMALL_TOOLBAR))
but_next.set_relief(Gtk.ReliefStyle.NONE)
hbox.pack_start(but_next, expand=False, fill=False, padding=0)
hbox.show_all()
hbox.set_focus_chain([self.search_entry])
self.filter_vbox.pack_start(hbox, expand=False, fill=False)
self.filter_vbox.pack_start(hbox, expand=False, fill=False, padding=0)
hseparator = gtk.HSeparator()
hseparator = Gtk.HSeparator()
hseparator.show()
self.filter_vbox.pack_start(hseparator, expand=False, fill=False)
self.filter_vbox.pack_start(
hseparator, expand=False, fill=False, padding=0)
if self.tab_domain:
self.notebook = gtk.Notebook()
self.notebook = Gtk.Notebook()
try:
self.notebook.props.homogeneous = True
except AttributeError:
@@ -301,30 +302,34 @@ class ScreenContainer(object):
pass
self.notebook.set_scrollable(True)
for name, domain, count in self.tab_domain:
hbox = gtk.HBox(spacing=3)
label = gtk.Label('_' + name)
hbox = Gtk.HBox(spacing=3)
label = Gtk.Label(label='_' + name)
label.set_use_underline(True)
hbox.pack_start(label, expand=True, fill=True)
counter = gtk.Label()
hbox.pack_start(counter, expand=False, fill=True)
hbox.pack_start(label, expand=True, fill=True, padding=0)
counter = Gtk.Label()
hbox.pack_start(counter, expand=False, fill=True, padding=0)
hbox.show_all()
self.notebook.append_page(gtk.VBox(), hbox)
self.notebook.append_page(Gtk.VBox(), hbox)
self.tab_counter.append(counter)
self.filter_vbox.pack_start(self.notebook, expand=True, fill=True)
self.filter_vbox.pack_start(
self.notebook, expand=True, fill=True, padding=0)
self.notebook.show_all()
# Set the current page before connecting to switch-page to not
# trigger the search a second times.
self.notebook.set_current_page(0)
self.notebook.get_nth_page(0).pack_end(self.viewport)
self.notebook.get_nth_page(0).pack_end(
self.viewport, expand=True, fill=True, padding=0)
self.notebook.connect('switch-page', self.switch_page)
self.notebook.connect_after('switch-page', self.switch_page_after)
filter_expand = True
else:
self.notebook = None
self.vbox.pack_end(self.viewport)
self.vbox.pack_end(
self.viewport, expand=True, fill=True, padding=0)
filter_expand = False
self.vbox.pack_start(self.filter_vbox, expand=filter_expand, fill=True)
self.vbox.pack_start(
self.filter_vbox, expand=filter_expand, fill=True, padding=0)
self.but_next.set_sensitive(False)
self.but_prev.set_sensitive(False)
@@ -347,7 +352,8 @@ class ScreenContainer(object):
if self.viewport in self.vbox.get_children():
self.vbox.remove(self.viewport)
self.notebook.get_nth_page(self.notebook.get_current_page()
).pack_end(self.viewport)
).pack_end(
self.viewport, expand=True, fill=True, padding=0)
def hide_filter(self):
if self.filter_vbox:
@@ -357,7 +363,8 @@ class ScreenContainer(object):
if self.viewport not in self.vbox.get_children():
self.notebook.get_nth_page(self.notebook.get_current_page()
).remove(self.viewport)
self.vbox.pack_end(self.viewport)
self.vbox.pack_end(
self.viewport, expand=True, fill=True, padding=0)
def set(self, widget):
viewport1 = self.viewport
@@ -399,32 +406,34 @@ class ScreenContainer(object):
current_text = self.get_text()
if current_text:
current_domain = self.screen.domain_parser.parse(current_text)
self.search_entry.set_icon_activatable(gtk.ENTRY_ICON_SECONDARY,
bool(current_text))
self.search_entry.set_icon_sensitive(gtk.ENTRY_ICON_SECONDARY,
bool(current_text))
self.search_entry.set_icon_activatable(
Gtk.EntryIconPosition.SECONDARY, bool(current_text))
self.search_entry.set_icon_sensitive(
Gtk.EntryIconPosition.SECONDARY, bool(current_text))
for id_, name, domain in self.bookmarks():
text = self.screen.domain_parser.string(domain)
domain = self.screen.domain_parser.parse(text)
if (text == current_text
or domain == current_domain):
self.search_entry.set_icon_from_pixbuf(
gtk.ENTRY_ICON_SECONDARY,
Gtk.EntryIconPosition.SECONDARY,
common.IconFactory.get_pixbuf(
'tryton-bookmark', gtk.ICON_SIZE_MENU))
'tryton-bookmark', Gtk.IconSize.MENU))
self.search_entry.set_icon_tooltip_text(
gtk.ENTRY_ICON_SECONDARY, _('Remove this bookmark'))
Gtk.EntryIconPosition.SECONDARY,
_('Remove this bookmark'))
return id_
self.search_entry.set_icon_from_pixbuf(
gtk.ENTRY_ICON_SECONDARY,
Gtk.EntryIconPosition.SECONDARY,
common.IconFactory.get_pixbuf(
'tryton-bookmark-border', gtk.ICON_SIZE_MENU))
'tryton-bookmark-border', Gtk.IconSize.MENU))
if current_text:
self.search_entry.set_icon_tooltip_text(gtk.ENTRY_ICON_SECONDARY,
_('Bookmark this filter'))
elif self.search_entry.get_icon_tooltip_text(gtk.ENTRY_ICON_SECONDARY):
self.search_entry.set_icon_tooltip_text(gtk.ENTRY_ICON_SECONDARY,
None)
self.search_entry.set_icon_tooltip_text(
Gtk.EntryIconPosition.SECONDARY, _('Bookmark this filter'))
elif self.search_entry.get_icon_tooltip_text(
Gtk.EntryIconPosition.SECONDARY):
self.search_entry.set_icon_tooltip_text(
Gtk.EntryIconPosition.SECONDARY, None)
def search_next(self, widget=None):
self.screen.search_next(self.get_text())
@@ -449,7 +458,7 @@ class ScreenContainer(object):
current_page.remove(self.viewport)
new_page = notebook.get_nth_page(page_num)
new_page.pack_end(self.viewport)
new_page.pack_end(self.viewport, expand=True, fill=True, padding=0)
def switch_page_after(self, notebook, page, page_num):
self.do_search()
@@ -490,7 +499,7 @@ class ScreenContainer(object):
return
self.update()
self.search_entry.emit('changed')
gobject.idle_add(callback)
GLib.idle_add(callback)
def activate(self, widget):
if not self.search_entry.get_selection_bounds():
@@ -509,12 +518,12 @@ class ScreenContainer(object):
return
self.update()
self.bookmark_match()
gobject.idle_add(keypress)
GLib.idle_add(keypress)
def icon_press(self, widget, icon_pos, event):
if icon_pos == gtk.ENTRY_ICON_PRIMARY:
if icon_pos == Gtk.EntryIconPosition.PRIMARY:
self.search_box(widget)
elif icon_pos == gtk.ENTRY_ICON_SECONDARY:
elif icon_pos == Gtk.EntryIconPosition.SECONDARY:
model_name = self.screen.model_name
id_ = self.bookmark_match()
if not id_:
@@ -546,7 +555,7 @@ class ScreenContainer(object):
self.search_popover.popdown()
text = ''
for label, entry in self.search_table.fields:
if isinstance(entry, gtk.ComboBox):
if isinstance(entry, Gtk.ComboBoxText):
value = quote(entry.get_active_text()) or None
elif isinstance(entry, (Between, Selection)):
value = entry.get_value()
@@ -564,10 +573,10 @@ class ScreenContainer(object):
self.search_popover = Gtk.Popover()
self.search_popover.set_relative_to(widget)
vbox = gtk.VBox()
vbox = Gtk.VBox()
fields = [f for f in self.screen.domain_parser.fields.values()
if f.get('searchable', True)]
self.search_table = gtk.Table(rows=len(fields), columns=2)
self.search_table = Gtk.Table(n_rows=len(fields), n_columns=2)
self.search_table.set_homogeneous(False)
self.search_table.set_border_width(5)
self.search_table.set_row_spacings(2)
@@ -576,16 +585,14 @@ class ScreenContainer(object):
# Fill table with fields
self.search_table.fields = []
for i, field in enumerate(fields):
label = gtk.Label(field['string'])
label.set_alignment(0.0, 0.0)
self.search_table.attach(label, 0, 1, i, i + 1,
yoptions=gtk.FILL)
label = Gtk.Label(
label=field['string'],
halign=Gtk.Align.START, valign=Gtk.Align.START)
self.search_table.attach(
label, 0, 1, i, i + 1, yoptions=Gtk.AttachOptions.FILL)
yoptions = False
if field['type'] == 'boolean':
if hasattr(gtk, 'ComboBoxText'):
entry = gtk.ComboBoxText()
else:
entry = gtk.combo_box_new_text()
entry = Gtk.ComboBoxText()
entry.append_text('')
selections = (_('True'), _('False'))
for selection in selections:
@@ -593,7 +600,8 @@ class ScreenContainer(object):
elif field['type'] == 'selection':
selections = tuple(x[1] for x in field['selection'])
entry = Selection(selections)
yoptions = gtk.FILL | gtk.EXPAND
yoptions = (
Gtk.AttachOptions.FILL | Gtk.AttachOptions.EXPAND)
elif field['type'] in ('date', 'datetime', 'time'):
date_format = common.date_format(
self.screen.context.get('date_format'))
@@ -607,28 +615,30 @@ class ScreenContainer(object):
entry = DateTimes(date_format, time_format)
entry.connect('activate', lambda *a: search())
else:
entry = gtk.Entry()
entry = Gtk.Entry()
entry.connect('activate', lambda *a: search())
label.set_mnemonic_widget(entry)
self.search_table.attach(entry, 1, 2, i, i + 1,
yoptions=yoptions)
self.search_table.fields.append((field['string'], entry))
scrolled = gtk.ScrolledWindow()
scrolled.add_with_viewport(self.search_table)
scrolled.set_shadow_type(gtk.SHADOW_NONE)
scrolled.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
vbox.pack_start(scrolled, expand=True, fill=True)
find_button = gtk.Button(_('Find'))
scrolled = Gtk.ScrolledWindow()
scrolled.add(self.search_table)
scrolled.set_shadow_type(Gtk.ShadowType.NONE)
scrolled.set_policy(
Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
vbox.pack_start(scrolled, expand=True, fill=True, padding=0)
find_button = Gtk.Button(label=_('Find'))
find_button.connect('clicked', lambda *a: search())
find_button.set_image(common.IconFactory.get_image(
'tryton-search', gtk.ICON_SIZE_SMALL_TOOLBAR))
'tryton-search', Gtk.IconSize.SMALL_TOOLBAR))
find_button.set_can_default(True)
self.search_popover.set_default_widget(find_button)
hbuttonbox = gtk.HButtonBox()
hbuttonbox.pack_start(find_button)
hbuttonbox.set_layout(gtk.BUTTONBOX_END)
vbox.pack_start(hbuttonbox, expand=False, fill=True)
hbuttonbox = Gtk.HButtonBox()
hbuttonbox.pack_start(
find_button, expand=False, fill=False, padding=0)
hbuttonbox.set_layout(Gtk.ButtonBoxStyle.END)
vbox.pack_start(hbuttonbox, expand=False, fill=True, padding=0)
self.search_popover.add(vbox)
vbox.show_all()
scrolled.set_size_request(
@@ -642,7 +652,7 @@ class ScreenContainer(object):
if self.last_search_text.strip() != self.get_text().strip():
for label, entry in self.search_table.fields:
if isinstance(entry, gtk.ComboBox):
if isinstance(entry, Gtk.ComboBoxText):
entry.set_active(-1)
elif isinstance(entry, Between):
entry.set_value(None, None)
+104 -104
View File
@@ -3,11 +3,10 @@
import locale
import os
import sys
import gtk
import gobject
import gettext
from gi.repository import Gdk, GObject, Gtk
from tryton.common import IconFactory
from tryton.common.underline import set_underline
from tryton.config import TRYTON_ICON
@@ -37,103 +36,111 @@ class WinCSV(NoModal):
def __init__(self, *args, **kwargs):
super(WinCSV, self).__init__(*args, **kwargs)
self.dialog = gtk.Dialog(
parent=self.parent, flags=gtk.DIALOG_DESTROY_WITH_PARENT)
self.dialog = Gtk.Dialog(
transient_for=self.parent, destroy_with_parent=True)
Main().add_window(self.dialog)
self.dialog.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
self.dialog.set_position(Gtk.WindowPosition.CENTER_ON_PARENT)
self.dialog.set_icon(TRYTON_ICON)
self.dialog.set_default_size(*self.default_size())
self.dialog.connect('response', self.response)
dialog_vbox = gtk.VBox()
dialog_vbox = Gtk.VBox()
hbox_mapping = gtk.HBox(True)
dialog_vbox.pack_start(hbox_mapping, True, True, 0)
hbox_mapping = Gtk.HBox(homogeneous=True)
dialog_vbox.pack_start(hbox_mapping, expand=True, fill=True, padding=0)
frame_fields = gtk.Frame()
frame_fields.set_shadow_type(gtk.SHADOW_NONE)
viewport_fields = gtk.Viewport()
scrolledwindow_fields = gtk.ScrolledWindow()
scrolledwindow_fields.set_policy(gtk.POLICY_AUTOMATIC,
gtk.POLICY_AUTOMATIC)
frame_fields = Gtk.Frame()
frame_fields.set_shadow_type(Gtk.ShadowType.NONE)
viewport_fields = Gtk.Viewport()
scrolledwindow_fields = Gtk.ScrolledWindow()
scrolledwindow_fields.set_policy(
Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
viewport_fields.add(scrolledwindow_fields)
frame_fields.add(viewport_fields)
label_all_fields = gtk.Label(_('<b>All fields</b>'))
label_all_fields.set_use_markup(True)
label_all_fields = Gtk.Label(
label=_('<b>All fields</b>'), use_markup=True)
frame_fields.set_label_widget(label_all_fields)
hbox_mapping.pack_start(frame_fields, True, True, 0)
hbox_mapping.pack_start(
frame_fields, expand=True, fill=True, padding=0)
vbox_buttons = gtk.VBox(False, 10)
vbox_buttons = Gtk.VBox(homogeneous=False, spacing=10)
vbox_buttons.set_border_width(5)
hbox_mapping.pack_start(vbox_buttons, False, True, 0)
hbox_mapping.pack_start(
vbox_buttons, expand=False, fill=True, padding=0)
button_add = gtk.Button(_('_Add'), stock=None, use_underline=True)
button_add = Gtk.Button(
label=_('_Add'), stock=None, use_underline=True)
button_add.set_image(IconFactory.get_image(
'tryton-add', gtk.ICON_SIZE_BUTTON))
'tryton-add', Gtk.IconSize.BUTTON))
button_add.set_always_show_image(True)
button_add.connect_after('clicked', self.sig_sel)
vbox_buttons.pack_start(button_add, False, False, 0)
vbox_buttons.pack_start(
button_add, expand=False, fill=False, padding=0)
button_remove = gtk.Button(
_('_Remove'), stock=None, use_underline=True)
button_remove = Gtk.Button(
label=_('_Remove'), stock=None, use_underline=True)
button_remove.set_image(IconFactory.get_image(
'tryton-remove', gtk.ICON_SIZE_BUTTON))
'tryton-remove', Gtk.IconSize.BUTTON))
button_remove.set_always_show_image(True)
button_remove.connect_after('clicked', self.sig_unsel)
vbox_buttons.pack_start(button_remove, False, False, 0)
vbox_buttons.pack_start(
button_remove, expand=False, fill=False, padding=0)
button_remove_all = gtk.Button(
_('_Clear'), stock=None, use_underline=True)
button_remove_all = Gtk.Button(
label=_('_Clear'), stock=None, use_underline=True)
button_remove_all.set_image(IconFactory.get_image(
'tryton-clear', gtk.ICON_SIZE_BUTTON))
'tryton-clear', Gtk.IconSize.BUTTON))
button_remove_all.set_always_show_image(True)
button_remove_all.connect_after('clicked', self.sig_unsel_all)
vbox_buttons.pack_start(button_remove_all, False, False, 0)
vbox_buttons.pack_start(
button_remove_all, expand=False, fill=False, padding=0)
hseparator_buttons = gtk.HSeparator()
vbox_buttons.pack_start(hseparator_buttons, False, False, 3)
hseparator_buttons = Gtk.HSeparator()
vbox_buttons.pack_start(
hseparator_buttons, expand=False, fill=False, padding=3)
self.add_buttons(vbox_buttons)
frame_fields_selected = gtk.Frame()
frame_fields_selected.set_shadow_type(gtk.SHADOW_NONE)
viewport_fields_selected = gtk.Viewport()
scrolledwindow_fields_selected = gtk.ScrolledWindow()
frame_fields_selected = Gtk.Frame()
frame_fields_selected.set_shadow_type(Gtk.ShadowType.NONE)
viewport_fields_selected = Gtk.Viewport()
scrolledwindow_fields_selected = Gtk.ScrolledWindow()
scrolledwindow_fields_selected.set_policy(
gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
viewport_fields_selected.add(scrolledwindow_fields_selected)
frame_fields_selected.add(viewport_fields_selected)
label_fields_selected = gtk.Label(_('<b>Fields selected</b>'))
label_fields_selected .set_use_markup(True)
label_fields_selected = Gtk.Label(
label=_('<b>Fields selected</b>'), use_markup=True)
frame_fields_selected.set_label_widget(label_fields_selected)
hbox_mapping.pack_start(frame_fields_selected, True, True, 0)
hbox_mapping.pack_start(
frame_fields_selected, expand=True, fill=True, padding=0)
frame_csv_param = gtk.Frame()
frame_csv_param.set_shadow_type(gtk.SHADOW_ETCHED_OUT)
dialog_vbox.pack_start(frame_csv_param, False, True, 0)
alignment_csv_param = gtk.Alignment(0.5, 0.5, 1, 1)
alignment_csv_param.set_padding(7, 7, 7, 7)
frame_csv_param.add(alignment_csv_param)
frame_csv_param = Gtk.Frame()
frame_csv_param.set_shadow_type(Gtk.ShadowType.ETCHED_OUT)
dialog_vbox.pack_start(
frame_csv_param, expand=False, fill=True, padding=0)
vbox_csv_param = gtk.VBox()
alignment_csv_param.add(vbox_csv_param)
vbox_csv_param = Gtk.VBox()
vbox_csv_param.props.margin = 7
frame_csv_param.add(vbox_csv_param)
self.add_chooser(vbox_csv_param)
expander_csv = gtk.Expander()
vbox_csv_param.pack_start(expander_csv, False, True, 0)
label_csv_param = gtk.Label(_('CSV Parameters'))
expander_csv = Gtk.Expander()
vbox_csv_param.pack_start(
expander_csv, expand=False, fill=True, padding=0)
label_csv_param = Gtk.Label(label=_('CSV Parameters'))
expander_csv.set_label_widget(label_csv_param)
table = gtk.Table(2, 4, False)
table = Gtk.Table(n_rows=2, n_columns=4, homogeneous=False)
table.set_border_width(8)
table.set_row_spacings(9)
table.set_col_spacings(8)
expander_csv.add(table)
label_csv_delimiter = gtk.Label(_('Delimiter:'))
label_csv_delimiter.set_alignment(1, 0.5)
label_csv_delimiter = Gtk.Label(
label=_('Delimiter:'), halign=Gtk.Align.END)
table.attach(label_csv_delimiter, 0, 1, 0, 1)
self.csv_delimiter = gtk.Entry()
self.csv_delimiter = Gtk.Entry()
self.csv_delimiter.set_max_length(1)
if os.name == 'nt' and ',' == locale.localeconv()['decimal_point']:
delimiter = ';'
@@ -144,22 +151,19 @@ class WinCSV(NoModal):
label_csv_delimiter.set_mnemonic_widget(self.csv_delimiter)
table.attach(self.csv_delimiter, 1, 2, 0, 1)
label_csv_quotechar = gtk.Label(_("Quote char:"))
label_csv_quotechar.set_alignment(1, 0.5)
label_csv_quotechar = Gtk.Label(
label=_("Quote char:"), halign=Gtk.Align.END)
table.attach(label_csv_quotechar, 2, 3, 0, 1)
self.csv_quotechar = gtk.Entry()
self.csv_quotechar = Gtk.Entry()
self.csv_quotechar.set_text("\"")
self.csv_quotechar.set_width_chars(1)
label_csv_quotechar.set_mnemonic_widget(self.csv_quotechar)
table.attach(self.csv_quotechar, 3, 4, 0, 1)
label_csv_enc = gtk.Label(_("Encoding:"))
label_csv_enc.set_alignment(1, 0.5)
label_csv_enc = Gtk.Label(
label=_("Encoding:"), halign=Gtk.Align.END)
table.attach(label_csv_enc, 0, 1, 1, 2)
if hasattr(gtk, 'ComboBoxText'):
self.csv_enc = gtk.ComboBoxText()
else:
self.csv_enc = gtk.combo_box_new_text()
self.csv_enc = Gtk.ComboBoxText()
for i, encoding in enumerate(encodings):
self.csv_enc.append_text(encoding)
if ((os.name == 'nt' and encoding == 'cp1252')
@@ -171,37 +175,38 @@ class WinCSV(NoModal):
self.add_csv_header_param(table)
button_cancel = self.dialog.add_button(
set_underline(_("Cancel")), gtk.RESPONSE_CANCEL)
set_underline(_("Cancel")), Gtk.ResponseType.CANCEL)
button_cancel.set_image(IconFactory.get_image(
'tryton-cancel', gtk.ICON_SIZE_BUTTON))
'tryton-cancel', Gtk.IconSize.BUTTON))
button_ok = self.dialog.add_button(
set_underline(_("OK")), gtk.RESPONSE_OK)
set_underline(_("OK")), Gtk.ResponseType.OK)
button_ok.set_image(IconFactory.get_image(
'tryton-ok', gtk.ICON_SIZE_BUTTON))
'tryton-ok', Gtk.IconSize.BUTTON))
self.dialog.vbox.pack_start(dialog_vbox)
self.dialog.vbox.pack_start(
dialog_vbox, expand=True, fill=True, padding=0)
self.view1 = gtk.TreeView()
self.view1.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
self.view1 = Gtk.TreeView()
self.view1.get_selection().set_mode(Gtk.SelectionMode.MULTIPLE)
self.view1.connect('row-expanded', self.on_row_expanded)
scrolledwindow_fields.add(self.view1)
self.view2 = gtk.TreeView()
self.view2.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
self.view2 = Gtk.TreeView()
self.view2.get_selection().set_mode(Gtk.SelectionMode.MULTIPLE)
scrolledwindow_fields_selected.add(self.view2)
self.view1.set_headers_visible(False)
self.view2.set_headers_visible(False)
cell = gtk.CellRendererText()
column = gtk.TreeViewColumn(_('Field name'), cell, text=0)
cell = Gtk.CellRendererText()
column = Gtk.TreeViewColumn(_('Field name'), cell, text=0)
self.view1.append_column(column)
cell = gtk.CellRendererText()
column = gtk.TreeViewColumn(_('Field name'), cell, text=0)
cell = Gtk.CellRendererText()
column = Gtk.TreeViewColumn(_('Field name'), cell, text=0)
self.view2.append_column(column)
self.model1 = gtk.TreeStore(gobject.TYPE_STRING, gobject.TYPE_STRING)
self.model2 = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING)
self.model1 = Gtk.TreeStore(GObject.TYPE_STRING, GObject.TYPE_STRING)
self.model2 = Gtk.ListStore(GObject.TYPE_STRING, GObject.TYPE_STRING)
self.model_populate(self._get_fields(self.model))
@@ -217,14 +222,15 @@ class WinCSV(NoModal):
if sys.platform != 'darwin':
self.view2.drag_source_set(
gtk.gdk.BUTTON1_MASK | gtk.gdk.BUTTON3_MASK,
[gtk.TargetEntry.new(
'EXPORT_TREE', gtk.TARGET_SAME_WIDGET, 0)],
gtk.gdk.ACTION_MOVE)
self.view2.drag_dest_set(gtk.DEST_DEFAULT_ALL,
[gtk.TargetEntry.new(
'EXPORT_TREE', gtk.TARGET_SAME_WIDGET, 0)],
gtk.gdk.ACTION_MOVE)
Gdk.ModifierType.BUTTON1_MASK | Gdk.ModifierType.BUTTON3_MASK,
[Gtk.TargetEntry.new(
'EXPORT_TREE', Gtk.TargetFlags.SAME_WIDGET, 0)],
Gdk.DragAction.MOVE)
self.view2.drag_dest_set(
Gtk.DestDefaults.ALL,
[Gtk.TargetEntry.new(
'EXPORT_TREE', Gtk.TargetFlags.SAME_WIDGET, 0)],
Gdk.DragAction.MOVE)
self.view2.connect('drag-begin', self.drag_begin)
self.view2.connect('drag-motion', self.drag_motion)
self.view2.connect('drag-drop', self.drag_drop)
@@ -240,20 +246,17 @@ class WinCSV(NoModal):
treeview.set_drag_dest_row(*treeview.get_dest_row_at_pos(x, y))
except TypeError:
treeview.set_drag_dest_row(len(treeview.get_model()) - 1,
gtk.TREE_VIEW_DROP_AFTER)
if hasattr(gtk.gdk, 'drag_status'):
gtk.gdk.drag_status(context, gtk.gdk.ACTION_MOVE, time)
else:
context.drag_status(gtk.gdk.ACTION_MOVE, time)
Gtk.TreeViewDropPosition.AFTER)
Gdk.drag_status(context, Gdk.DragAction.MOVE, time)
return True
def drag_drop(self, treeview, context, x, y, time):
treeview.emit_stop_by_name('drag-drop')
treeview.stop_emission_by_name('drag-drop')
return True
def drag_data_get(self, treeview, context, selection, target_id,
etime):
treeview.emit_stop_by_name('drag-data-get')
treeview.stop_emission_by_name('drag-data-get')
def _func_sel_get(store, path, iter_, data):
data.append(path[0])
@@ -268,7 +271,7 @@ class WinCSV(NoModal):
def drag_data_received(self, treeview, context, x, y, selection,
info, etime):
treeview.emit_stop_by_name('drag-data-received')
treeview.stop_emission_by_name('drag-data-received')
try:
selection_data = selection.data
except AttributeError:
@@ -285,22 +288,19 @@ class WinCSV(NoModal):
pos = store.get_iter(path)
else:
pos = store.get_iter((len(store) - 1,))
position = gtk.TREE_VIEW_DROP_AFTER
if position == gtk.TREE_VIEW_DROP_AFTER:
position = Gtk.TreeViewDropPosition.AFTER
if position == Gtk.TreeViewDropPosition.AFTER:
data_iters = reversed(data_iters)
for item in data_iters:
if position == gtk.TREE_VIEW_DROP_BEFORE:
if position == Gtk.TreeViewDropPosition.BEFORE:
store.move_before(item, pos)
else:
store.move_after(item, pos)
if hasattr(gtk.gdk, 'drop_finish'):
gtk.gdk.drop_finish(context, False, etime)
else:
context.drop_finish(False, etime)
Gdk.drop_finish(context, False, etime)
return True
def drag_data_delete(self, treeview, context):
treeview.emit_stop_by_name('drag-data-delete')
treeview.stop_emission_by_name('drag-data-delete')
def get_delimiter(self):
return self.csv_delimiter.get_text() or ','
+37 -39
View File
@@ -3,11 +3,10 @@
import csv
import os
import tempfile
import gtk
import gobject
import gettext
from gi.repository import Gdk, GObject, Gtk
import tryton.common as common
from tryton.common import RPCExecute, RPCException
from tryton.gui.window.win_csv import WinCSV
@@ -28,63 +27,62 @@ class WinExport(WinCSV):
self.dialog.set_title(_('CSV Export: %s') % name)
def add_buttons(self, box):
button_save_export = gtk.Button(
_('_Save Export'), stock=None, use_underline=True)
button_save_export = Gtk.Button(
label=_('_Save Export'), stock=None, use_underline=True)
button_save_export.set_image(common.IconFactory.get_image(
'tryton-save', gtk.ICON_SIZE_BUTTON))
'tryton-save', Gtk.IconSize.BUTTON))
button_save_export.set_always_show_image(True)
button_save_export.connect_after('clicked', self.addreplace_predef)
box.pack_start(button_save_export, False, False, 0)
box.pack_start(
button_save_export, expand=False, fill=False, padding=0)
button_del_export = gtk.Button(
_('_Delete Export'), stock=None, use_underline=True)
button_del_export = Gtk.Button(
label=_('_Delete Export'), stock=None, use_underline=True)
button_del_export.set_image(common.IconFactory.get_image(
'tryton-delete', gtk.ICON_SIZE_BUTTON))
'tryton-delete', Gtk.IconSize.BUTTON))
button_del_export.set_always_show_image(True)
button_del_export.connect_after('clicked', self.remove_predef)
box.pack_start(button_del_export, False, False, 0)
box.pack_start(button_del_export, expand=False, fill=False, padding=0)
frame_predef_exports = gtk.Frame()
frame_predef_exports = Gtk.Frame()
frame_predef_exports.set_border_width(2)
frame_predef_exports.set_shadow_type(gtk.SHADOW_NONE)
box.pack_start(frame_predef_exports, True, True, 0)
viewport_exports = gtk.Viewport()
scrolledwindow_exports = gtk.ScrolledWindow()
scrolledwindow_exports.set_policy(gtk.POLICY_AUTOMATIC,
gtk.POLICY_AUTOMATIC)
label_predef_exports = gtk.Label(_("<b>Predefined exports</b>"))
label_predef_exports.set_use_markup(True)
frame_predef_exports.set_shadow_type(Gtk.ShadowType.NONE)
box.pack_start(frame_predef_exports, expand=True, fill=True, padding=0)
viewport_exports = Gtk.Viewport()
scrolledwindow_exports = Gtk.ScrolledWindow()
scrolledwindow_exports.set_policy(
Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
label_predef_exports = Gtk.Label(
label=_("<b>Predefined exports</b>"), use_markup=True)
frame_predef_exports.set_label_widget(label_predef_exports)
viewport_exports.add(scrolledwindow_exports)
frame_predef_exports.add(viewport_exports)
self.pref_export = gtk.TreeView()
self.pref_export.append_column(gtk.TreeViewColumn(_('Name'),
gtk.CellRendererText(), text=2))
self.pref_export = Gtk.TreeView()
self.pref_export.append_column(
Gtk.TreeViewColumn(_('Name'), Gtk.CellRendererText(), text=2))
scrolledwindow_exports.add(self.pref_export)
self.pref_export.connect("button-press-event", self.export_click)
self.pref_export.connect("key-press-event", self.export_keypress)
self.predef_model = gtk.ListStore(
gobject.TYPE_INT,
gobject.TYPE_PYOBJECT,
gobject.TYPE_STRING)
self.predef_model = Gtk.ListStore(
GObject.TYPE_INT,
GObject.TYPE_PYOBJECT,
GObject.TYPE_STRING)
self.fill_predefwin()
def add_chooser(self, box):
hbox_csv_export = gtk.HBox()
box.pack_start(hbox_csv_export, False, True, 0)
if hasattr(gtk, 'ComboBoxText'):
self.saveas = gtk.ComboBoxText()
else:
self.saveas = gtk.combo_box_new_text()
hbox_csv_export.pack_start(self.saveas, True, True, 0)
hbox_csv_export = Gtk.HBox()
box.pack_start(hbox_csv_export, expand=False, fill=True, padding=0)
self.saveas = Gtk.ComboBoxText()
hbox_csv_export.pack_start(
self.saveas, expand=True, fill=True, padding=0)
self.saveas.append_text(_("Open"))
self.saveas.append_text(_("Save"))
self.saveas.set_active(0)
def add_csv_header_param(self, table):
self.add_field_names = gtk.CheckButton(_("Add _field names"))
self.add_field_names = Gtk.CheckButton(label=_("Add _field names"))
self.add_field_names.set_active(True)
table.attach(self.add_field_names, 2, 4, 1, 2)
@@ -268,7 +266,7 @@ class WinExport(WinCSV):
self.model2.append((long_string, name))
def response(self, dialog, response):
if response == gtk.RESPONSE_OK:
if response == Gtk.ResponseType.OK:
fields = []
fields2 = []
iter = self.model2.get_iter_first()
@@ -291,7 +289,7 @@ class WinExport(WinCSV):
common.file_open(fname, 'csv')
else:
fname = common.file_selection(_('Save As...'),
action=gtk.FILE_CHOOSER_ACTION_SAVE)
action=Gtk.FileChooserAction.SAVE)
if fname:
self.export_csv(fname, fields2, data)
self.destroy()
@@ -328,7 +326,7 @@ class WinExport(WinCSV):
return
path, col, x, y = path_at_pos
selection = treeview.get_selection()
if event.type == gtk.gdk._2BUTTON_PRESS:
if event.type == Gdk.EventType._2BUTTON_PRESS:
self.sel_predef(path)
selection.select_path(path)
return True
@@ -337,7 +335,7 @@ class WinExport(WinCSV):
return True
def export_keypress(self, treeview, event):
if event.keyval not in (gtk.keysyms.Return, gtk.keysyms.space):
if event.keyval not in [Gdk.KEY_Return, Gdk.KEY_.space]:
return
model, selected = treeview.get_selection().get_selected()
if not selected:
+100 -98
View File
@@ -1,14 +1,15 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
from tryton.common import TRYTON_ICON
import tryton.common as common
import gtk
import pango
import gettext
from gi.repository import Gdk, Gtk, Pango
from .infobar import InfoBar
import tryton.common as common
from tryton.common import TRYTON_ICON
from tryton.common.domain_parser import quote
from tryton.common.underline import set_underline
from tryton.common.widget_style import widget_class
from tryton.gui import Main
from tryton.gui.window.nomodal import NoModal
@@ -38,10 +39,11 @@ class WinForm(NoModal, InfoBar):
return
if new:
self.screen.new(rec_name=rec_name)
self.win = gtk.Dialog(_('Link'), self.parent,
gtk.DIALOG_DESTROY_WITH_PARENT)
self.win = Gtk.Dialog(
title=_('Link'), transient_for=self.parent,
destroy_with_parent=True)
Main().add_window(self.win)
self.win.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
self.win.set_position(Gtk.WindowPosition.CENTER_ON_PARENT)
self.win.set_icon(TRYTON_ICON)
self.win.set_deletable(False)
self.win.connect('delete-event', lambda *a: True)
@@ -50,7 +52,7 @@ class WinForm(NoModal, InfoBar):
self.win.set_default_size(*self.default_size())
self.accel_group = gtk.AccelGroup()
self.accel_group = Gtk.AccelGroup()
self.win.add_accel_group(self.accel_group)
readonly = self.screen.readonly or self.screen.group.readonly
@@ -66,184 +68,183 @@ class WinForm(NoModal, InfoBar):
label, icon = _("Cancel"), 'tryton-cancel'
self._initial_value = self.screen.current_record.get_eval()
self.but_cancel = self.win.add_button(
set_underline(label), gtk.RESPONSE_CANCEL)
set_underline(label), Gtk.ResponseType.CANCEL)
self.but_cancel.set_image(common.IconFactory.get_image(
icon, gtk.ICON_SIZE_BUTTON))
icon, Gtk.IconSize.BUTTON))
self.but_cancel.set_always_show_image(True)
if new and self.many:
self.but_new = self.win.add_button(
set_underline(_("New")), gtk.RESPONSE_ACCEPT)
set_underline(_("New")), Gtk.ResponseType.ACCEPT)
self.but_new.set_image(common.IconFactory.get_image(
'tryton-create', gtk.ICON_SIZE_BUTTON))
'tryton-create', Gtk.IconSize.BUTTON))
self.but_new.set_always_show_image(True)
self.but_new.set_accel_path('<tryton>/Form/New', self.accel_group)
if self.save_current:
self.but_ok = gtk.Button(_('_Save'), use_underline=True)
self.but_ok = Gtk.Button(label=_('_Save'), use_underline=True)
self.but_ok.set_image(common.IconFactory.get_image(
'tryton-save', gtk.ICON_SIZE_BUTTON))
'tryton-save', Gtk.IconSize.BUTTON))
self.but_ok.set_always_show_image(True)
self.but_ok.set_accel_path('<tryton>/Form/Save', self.accel_group)
self.but_ok.set_can_default(True)
self.but_ok.show()
self.win.add_action_widget(self.but_ok, gtk.RESPONSE_OK)
self.win.add_action_widget(self.but_ok, Gtk.ResponseType.OK)
if not new:
self.but_ok.props.sensitive = False
else:
self.but_ok = self.win.add_button(
set_underline(_("OK")), gtk.RESPONSE_OK)
set_underline(_("OK")), Gtk.ResponseType.OK)
self.but_ok.set_image(common.IconFactory.get_image(
'tryton-ok', gtk.ICON_SIZE_BUTTON))
'tryton-ok', Gtk.IconSize.BUTTON))
self.but_ok.set_always_show_image(True)
self.but_ok.add_accelerator('clicked', self.accel_group,
gtk.keysyms.Return, gtk.gdk.CONTROL_MASK, gtk.ACCEL_VISIBLE)
self.win.set_default_response(gtk.RESPONSE_OK)
Gdk.KEY_Return, Gdk.ModifierType.CONTROL_MASK,
Gtk.AccelFlags.VISIBLE)
self.win.set_default_response(Gtk.ResponseType.OK)
self.win.set_title(self.title)
title = gtk.Label()
title.modify_font(pango.FontDescription("bold 12"))
title.set_label(common.ellipsize(self.title, 80))
title = Gtk.Label(
label=common.ellipsize(self.title, 80),
halign=Gtk.Align.START, margin=5,
ellipsize=Pango.EllipsizeMode.END)
tooltips.set_tip(title, self.title)
title.set_padding(20, 3)
title.set_alignment(0.0, 0.5)
title.set_size_request(0, -1) # Allow overflow
title.set_max_width_chars(1)
title.set_ellipsize(pango.ELLIPSIZE_END)
title.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse("#000000"))
title.show()
hbox = gtk.HBox()
hbox.pack_start(title, expand=True, fill=True)
hbox = Gtk.HBox()
hbox.pack_start(title, expand=True, fill=True, padding=0)
hbox.show()
frame = gtk.Frame()
frame.set_shadow_type(gtk.SHADOW_ETCHED_IN)
frame = Gtk.Frame()
frame.set_shadow_type(Gtk.ShadowType.ETCHED_IN)
widget_class(frame, 'window-title', True)
frame.add(hbox)
frame.show()
eb = gtk.EventBox()
eb.add(frame)
eb.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse("#ffffff"))
eb.show()
self.win.vbox.pack_start(eb, expand=False, fill=True, padding=3)
self.win.vbox.pack_start(frame, expand=False, fill=True, padding=3)
if view_type == 'tree':
hbox = gtk.HBox(homogeneous=False, spacing=0)
hbox = Gtk.HBox(homogeneous=False, spacing=0)
hbox.set_halign(Gtk.Align.END)
access = common.MODELACCESS[screen.model_name]
but_switch = gtk.Button()
but_switch = Gtk.Button()
tooltips.set_tip(but_switch, _('Switch'))
but_switch.connect('clicked', self.switch_view)
but_switch.add(common.IconFactory.get_image(
'tryton-switch', gtk.ICON_SIZE_SMALL_TOOLBAR))
but_switch.set_relief(gtk.RELIEF_NONE)
hbox.pack_start(but_switch, expand=False, fill=False)
'tryton-switch', Gtk.IconSize.SMALL_TOOLBAR))
but_switch.set_relief(Gtk.ReliefStyle.NONE)
hbox.pack_start(but_switch, expand=False, fill=False, padding=0)
self.but_pre = gtk.Button()
self.but_pre = Gtk.Button()
tooltips.set_tip(self.but_pre, _('Previous'))
self.but_pre.connect('clicked', self._sig_previous)
self.but_pre.add(common.IconFactory.get_image(
'tryton-back', gtk.ICON_SIZE_SMALL_TOOLBAR))
self.but_pre.set_relief(gtk.RELIEF_NONE)
hbox.pack_start(self.but_pre, expand=False, fill=False)
'tryton-back', Gtk.IconSize.SMALL_TOOLBAR))
self.but_pre.set_relief(Gtk.ReliefStyle.NONE)
hbox.pack_start(self.but_pre, expand=False, fill=False, padding=0)
self.label = gtk.Label('(0,0)')
hbox.pack_start(self.label, expand=False, fill=False)
self.label = Gtk.Label(label='(0,0)')
hbox.pack_start(self.label, expand=False, fill=False, padding=0)
self.but_next = gtk.Button()
self.but_next = Gtk.Button()
tooltips.set_tip(self.but_next, _('Next'))
self.but_next.connect('clicked', self._sig_next)
self.but_next.add(common.IconFactory.get_image(
'tryton-forward', gtk.ICON_SIZE_SMALL_TOOLBAR))
self.but_next.set_relief(gtk.RELIEF_NONE)
hbox.pack_start(self.but_next, expand=False, fill=False)
'tryton-forward', Gtk.IconSize.SMALL_TOOLBAR))
self.but_next.set_relief(Gtk.ReliefStyle.NONE)
hbox.pack_start(self.but_next, expand=False, fill=False, padding=0)
hbox.pack_start(gtk.VSeparator(), expand=False, fill=True)
hbox.pack_start(
Gtk.VSeparator(), expand=False, fill=True, padding=0)
if domain is not None:
self.wid_text = gtk.Entry()
self.wid_text = Gtk.Entry()
self.wid_text.set_property('width_chars', 13)
self.wid_text.connect('activate', self._sig_activate)
self.wid_text.connect('focus-out-event', self._focus_out)
hbox.pack_start(self.wid_text, expand=True, fill=True)
hbox.pack_start(
self.wid_text, expand=True, fill=True, padding=0)
self.but_add = gtk.Button()
self.but_add = Gtk.Button()
tooltips.set_tip(self.but_add, _('Add'))
self.but_add.connect('clicked', self._sig_add)
self.but_add.add(common.IconFactory.get_image(
'tryton-add', gtk.ICON_SIZE_SMALL_TOOLBAR))
self.but_add.set_relief(gtk.RELIEF_NONE)
hbox.pack_start(self.but_add, expand=False, fill=False)
'tryton-add', Gtk.IconSize.SMALL_TOOLBAR))
self.but_add.set_relief(Gtk.ReliefStyle.NONE)
hbox.pack_start(
self.but_add, expand=False, fill=False, padding=0)
if not access['read'] or readonly:
self.but_add.set_sensitive(False)
self.but_remove = gtk.Button()
self.but_remove = Gtk.Button()
tooltips.set_tip(self.but_remove, _('Remove <Del>'))
self.but_remove.connect('clicked', self._sig_remove, True)
self.but_remove.add(common.IconFactory.get_image(
'tryton-remove', gtk.ICON_SIZE_SMALL_TOOLBAR))
self.but_remove.set_relief(gtk.RELIEF_NONE)
hbox.pack_start(self.but_remove, expand=False, fill=False)
'tryton-remove', Gtk.IconSize.SMALL_TOOLBAR))
self.but_remove.set_relief(Gtk.ReliefStyle.NONE)
hbox.pack_start(
self.but_remove, expand=False, fill=False, padding=0)
if not access['read'] or readonly:
self.but_remove.set_sensitive(False)
hbox.pack_start(gtk.VSeparator(), expand=False, fill=True)
hbox.pack_start(
Gtk.VSeparator(), expand=False, fill=True, padding=0)
self.but_new = gtk.Button()
self.but_new = Gtk.Button()
tooltips.set_tip(self.but_new, _('Create a new record <F3>'))
self.but_new.connect('clicked', self._sig_new)
self.but_new.add(common.IconFactory.get_image(
'tryton-create', gtk.ICON_SIZE_SMALL_TOOLBAR))
self.but_new.set_relief(gtk.RELIEF_NONE)
hbox.pack_start(self.but_new, expand=False, fill=False)
'tryton-create', Gtk.IconSize.SMALL_TOOLBAR))
self.but_new.set_relief(Gtk.ReliefStyle.NONE)
hbox.pack_start(self.but_new, expand=False, fill=False, padding=0)
if not access['create'] or readonly:
self.but_new.set_sensitive(False)
self.but_del = gtk.Button()
self.but_del = Gtk.Button()
tooltips.set_tip(self.but_del, _('Delete selected record <Del>'))
self.but_del.connect('clicked', self._sig_remove, False)
self.but_del.add(common.IconFactory.get_image(
'tryton-delete', gtk.ICON_SIZE_SMALL_TOOLBAR))
self.but_del.set_relief(gtk.RELIEF_NONE)
hbox.pack_start(self.but_del, expand=False, fill=False)
'tryton-delete', Gtk.IconSize.SMALL_TOOLBAR))
self.but_del.set_relief(Gtk.ReliefStyle.NONE)
hbox.pack_start(self.but_del, expand=False, fill=False, padding=0)
if not access['delete'] or readonly:
self.but_del.set_sensitive(False)
self.but_undel = gtk.Button()
self.but_undel = Gtk.Button()
tooltips.set_tip(self.but_undel,
_('Undelete selected record <Ins>'))
self.but_undel.connect('clicked', self._sig_undelete)
self.but_undel.add(common.IconFactory.get_image(
'tryton-undo', gtk.ICON_SIZE_SMALL_TOOLBAR))
self.but_undel.set_relief(gtk.RELIEF_NONE)
hbox.pack_start(self.but_undel, expand=False, fill=False)
'tryton-undo', Gtk.IconSize.SMALL_TOOLBAR))
self.but_undel.set_relief(Gtk.ReliefStyle.NONE)
hbox.pack_start(
self.but_undel, expand=False, fill=False, padding=0)
if not access['delete'] or readonly:
self.but_undel.set_sensitive(False)
but_switch.props.sensitive = screen.number_of_views > 1
tooltips.enable()
hbox.show_all()
alignment = gtk.Alignment(1.0)
alignment.add(hbox)
alignment.show_all()
self.win.vbox.pack_start(
hbox, expand=False, fill=True, padding=0)
self.win.vbox.pack_start(alignment, expand=False, fill=True)
scroll = gtk.ScrolledWindow()
scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
scroll.set_placement(gtk.CORNER_TOP_LEFT)
scroll.set_shadow_type(gtk.SHADOW_NONE)
scroll = Gtk.ScrolledWindow()
scroll.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
scroll.set_placement(Gtk.CornerType.TOP_LEFT)
scroll.set_shadow_type(Gtk.ShadowType.NONE)
scroll.show()
self.win.vbox.pack_start(scroll, expand=True, fill=True)
self.win.vbox.pack_start(scroll, expand=True, fill=True, padding=0)
scroll.add(self.screen.screen_container.alternate_viewport)
self.create_info_bar()
self.win.vbox.pack_start(self.info_bar, False, True)
self.win.vbox.pack_start(
self.info_bar, expand=False, fill=True, padding=0)
if view_type == 'tree':
self.screen.signal_connect(self, 'record-message', self._sig_label)
@@ -263,12 +264,12 @@ class WinForm(NoModal, InfoBar):
self.screen.current_view.set_cursor()
def on_keypress(self, widget, event):
if (event.keyval == gtk.keysyms.F3) \
and self.but_new.get_property('sensitive'):
if ((event.keyval == Gdk.KEY_F3)
and self.but_new.get_property('sensitive')):
self._sig_new(widget)
return False
if event.keyval in (gtk.keysyms.Delete, gtk.keysyms.KP_Delete) \
and widget == self.screen.screen_container.alternate_viewport:
if (event.keyval in [Gdk.KEY_Delete, Gdk.KEY_KP_Delete]
and widget == self.screen.screen_container.alternate_viewport):
self._sig_remove(widget)
return False
@@ -353,16 +354,17 @@ class WinForm(NoModal, InfoBar):
sensitive = modified or self.but_ok.props.sensitive
self.but_ok.props.sensitive = sensitive
self.win.set_default_response(
gtk.RESPONSE_OK if sensitive else gtk.RESPONSE_CANCEL)
Gtk.ResponseType.OK if sensitive else Gtk.ResponseType.CANCEL)
def close(self, widget):
widget.emit_stop_by_name('close')
self.response(self.win, gtk.RESPONSE_CANCEL)
widget.stop_emission_by_name('close')
self.response(self.win, Gtk.ResponseType.CANCEL)
return True
def response(self, win, response_id):
validate = False
cancel_responses = (gtk.RESPONSE_CANCEL, gtk.RESPONSE_DELETE_EVENT)
cancel_responses = [
Gtk.ResponseType.CANCEL, Gtk.ResponseType.DELETE_EVENT]
self.screen.current_view.set_value()
readonly = self.screen.group.readonly
if (response_id not in cancel_responses
@@ -386,12 +388,12 @@ class WinForm(NoModal, InfoBar):
validate = record.pre_validate()
if not validate:
self.message_info(self.screen.invalid_message(),
gtk.MESSAGE_ERROR)
Gtk.MessageType.ERROR)
self.screen.set_cursor()
self.screen.display()
return
self.message_info()
if response_id == gtk.RESPONSE_ACCEPT:
if response_id == Gtk.ResponseType.ACCEPT:
self.new()
return
if (self.screen.current_record
@@ -418,7 +420,7 @@ class WinForm(NoModal, InfoBar):
self.many -= 1
if self.many == 0:
self.but_new.set_sensitive(False)
self.win.set_default_response(gtk.RESPONSE_OK)
self.win.set_default_response(Gtk.ResponseType.OK)
def destroy(self):
self.screen.screen_container.alternate_view = False
+20 -16
View File
@@ -3,7 +3,7 @@
import csv
import gettext
import gtk
from gi.repository import Gtk
import tryton.common as common
from tryton.common import RPCExecute, RPCException
@@ -26,31 +26,35 @@ class WinImport(WinCSV):
self.dialog.set_title(_('CSV Import: %s') % name)
def add_buttons(self, box):
button_autodetect = gtk.Button(
_('_Auto-Detect'), stock=None, use_underline=True)
button_autodetect.set_alignment(0.0, 0.0)
button_autodetect = Gtk.Button(
label=_('_Auto-Detect'), stock=None, use_underline=True)
button_autodetect.set_image(common.IconFactory.get_image(
'tryton-search', gtk.ICON_SIZE_BUTTON))
'tryton-search', Gtk.IconSize.BUTTON))
button_autodetect.set_always_show_image(True)
button_autodetect.connect_after('clicked', self.sig_autodetect)
box.pack_start(button_autodetect, False, False, 0)
box.pack_start(
button_autodetect, expand=False, fill=False, padding=0)
def add_chooser(self, box):
hbox_csv_import = gtk.HBox()
box.pack_start(hbox_csv_import, False, True, 4)
label_csv_import = gtk.Label(_("File to Import:"))
hbox_csv_import = Gtk.HBox()
box.pack_start(hbox_csv_import, expand=False, fill=True, padding=4)
label_csv_import = Gtk.Label(label=_("File to Import:"))
hbox_csv_import.pack_start(label_csv_import, False, False, 0)
self.import_csv_file = gtk.FileChooserButton(_("Open..."))
self.import_csv_file = Gtk.FileChooserButton(title=_("Open..."))
label_csv_import.set_mnemonic_widget(self.import_csv_file)
hbox_csv_import.pack_start(self.import_csv_file, True, True, 0)
hbox_csv_import.pack_start(
self.import_csv_file, expand=True, fill=True, padding=0)
def add_csv_header_param(self, table):
label_csv_skip = gtk.Label(_('Lines to Skip:'))
label_csv_skip.set_alignment(1, 0.5)
label_csv_skip = Gtk.Label(
label=_('Lines to Skip:'), halign=Gtk.Align.START)
table.attach(label_csv_skip, 2, 3, 1, 2)
self.csv_skip = gtk.SpinButton()
self.csv_skip.configure(gtk.Adjustment(0, 0, 100, 1, 10), 1, 0)
self.csv_skip = Gtk.SpinButton()
self.csv_skip.configure(Gtk.Adjustment(
value=0, lower=0, upper=100,
step_increment=1, page_increment=10),
1, 0)
label_csv_skip.set_mnemonic_widget(self.csv_skip)
table.attach(self.csv_skip, 3, 4, 1, 2)
@@ -163,7 +167,7 @@ class WinImport(WinCSV):
self.model2.clear()
def response(self, dialog, response):
if response == gtk.RESPONSE_OK:
if response == Gtk.ResponseType.OK:
fields = []
iter = self.model2.get_iter_first()
while iter:
+32 -27
View File
@@ -1,8 +1,9 @@
# 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
from gi.repository import Gtk, Gdk
import tryton.common as common
from tryton.common.underline import set_underline
from tryton.config import TRYTON_ICON
@@ -33,49 +34,52 @@ class WinSearch(NoModal):
self.callback = callback
self.title = title
self.win = gtk.Dialog(_('Search'), self.parent,
gtk.DIALOG_DESTROY_WITH_PARENT)
self.win = Gtk.Dialog(
title=_('Search'), transient_for=self.parent,
destroy_with_parent=True)
Main().add_window(self.win)
self.win.set_icon(TRYTON_ICON)
self.win.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
self.win.set_default_response(gtk.RESPONSE_APPLY)
self.win.set_position(Gtk.WindowPosition.CENTER_ON_PARENT)
self.win.set_default_response(Gtk.ResponseType.APPLY)
self.win.connect('response', self.response)
self.win.set_default_size(*self.default_size())
self.accel_group = gtk.AccelGroup()
self.accel_group = Gtk.AccelGroup()
self.win.add_accel_group(self.accel_group)
self.but_cancel = self.win.add_button(
set_underline(_("Cancel")), gtk.RESPONSE_CANCEL)
set_underline(_("Cancel")), Gtk.ResponseType.CANCEL)
self.but_cancel.set_image(common.IconFactory.get_image(
'tryton-cancel', gtk.ICON_SIZE_BUTTON))
'tryton-cancel', Gtk.IconSize.BUTTON))
self.but_cancel.set_always_show_image(True)
self.but_find = self.win.add_button(
set_underline(_("Search")), gtk.RESPONSE_APPLY)
set_underline(_("Search")), Gtk.ResponseType.APPLY)
self.but_find.set_image(common.IconFactory.get_image(
'tryton-search', gtk.ICON_SIZE_BUTTON))
'tryton-search', Gtk.IconSize.BUTTON))
self.but_find.set_always_show_image(True)
if new and common.MODELACCESS[model]['create']:
self.but_new = self.win.add_button(
set_underline(_("New")), gtk.RESPONSE_ACCEPT)
set_underline(_("New")), Gtk.ResponseType.ACCEPT)
self.but_new.set_image(common.IconFactory.get_image(
'tryton-create', gtk.ICON_SIZE_BUTTON))
'tryton-create', Gtk.IconSize.BUTTON))
self.but_new.set_always_show_image(True)
self.but_new.set_accel_path('<tryton>/Form/New', self.accel_group)
self.but_ok = self.win.add_button(
set_underline(_("OK")), gtk.RESPONSE_OK)
set_underline(_("OK")), Gtk.ResponseType.OK)
self.but_ok.set_image(common.IconFactory.get_image(
'tryton-ok', gtk.ICON_SIZE_BUTTON))
'tryton-ok', Gtk.IconSize.BUTTON))
self.but_ok.set_always_show_image(True)
self.but_ok.add_accelerator('clicked', self.accel_group,
gtk.keysyms.Return, gtk.gdk.CONTROL_MASK, gtk.ACCEL_VISIBLE)
self.but_ok.add_accelerator(
'clicked', self.accel_group, Gdk.KEY_Return,
Gdk.ModifierType.CONTROL_MASK, Gtk.AccelFlags.VISIBLE)
hbox = gtk.HBox()
hbox = Gtk.HBox()
hbox.show()
self.win.vbox.pack_start(hbox, expand=False, fill=True)
self.win.vbox.pack_start(gtk.HSeparator(), expand=False, fill=True)
self.win.vbox.pack_start(hbox, expand=False, fill=True, padding=0)
self.win.vbox.pack_start(
Gtk.HSeparator(), expand=False, fill=True, padding=0)
self.screen = Screen(model, domain=domain, mode=['tree'], order=order,
context=context, view_ids=view_ids, views_preload=views_preload,
@@ -87,10 +91,11 @@ class WinSearch(NoModal):
self.win.set_title(_('Search %s') % self.title)
if not sel_multi:
sel.set_mode(gtk.SELECTION_SINGLE)
sel.set_mode(Gtk.SelectionMode.SINGLE)
else:
sel.set_mode(gtk.SELECTION_MULTIPLE)
self.win.vbox.pack_start(self.screen.widget, expand=True, fill=True)
sel.set_mode(Gtk.SelectionMode.MULTIPLE)
self.win.vbox.pack_start(
self.screen.widget, expand=True, fill=True, padding=0)
self.screen.widget.show()
self.model_name = model
@@ -98,8 +103,8 @@ class WinSearch(NoModal):
self.register()
def sig_activate(self, *args):
self.view.treeview.emit_stop_by_name('row_activated')
self.win.response(gtk.RESPONSE_OK)
self.view.treeview.stop_emission_by_name('row_activated')
self.win.response(Gtk.ResponseType.OK)
return True
def destroy(self):
@@ -115,12 +120,12 @@ class WinSearch(NoModal):
def response(self, win, response_id):
res = None
if response_id == gtk.RESPONSE_OK:
if response_id == Gtk.ResponseType.OK:
res = [r.id for r in self.screen.selected_records]
elif response_id == gtk.RESPONSE_APPLY:
elif response_id == Gtk.ResponseType.APPLY:
self.screen.search_filter(self.screen.screen_container.get_text())
return
elif response_id == gtk.RESPONSE_ACCEPT:
elif response_id == Gtk.ResponseType.ACCEPT:
# Remove first tree view as mode if form only
view_ids = self.view_ids[1:]
screen = Screen(self.model_name, domain=self.domain,
+49 -50
View File
@@ -3,10 +3,7 @@
import logging
import gettext
import gtk
import pango
from gi.repository import Gtk
from gi.repository import Gdk, Gtk, Pango
from tryton.signal_event import SignalEvent
import tryton.common as common
@@ -17,6 +14,7 @@ from tryton.gui.window.nomodal import NoModal
from tryton.common.button import Button
from tryton.common import RPCExecute, RPCException, RPCContextReload
from tryton.common import TRYTON_ICON
from tryton.common.widget_style import widget_class
from .infobar import InfoBar
from .tabcontent import TabContent
@@ -28,7 +26,7 @@ class Wizard(InfoBar):
def __init__(self, name=''):
super(Wizard, self).__init__()
self.widget = gtk.VBox(spacing=3)
self.widget = Gtk.VBox(spacing=3)
self.toolbar_box = None
self.widget.show()
self.name = name or ''
@@ -173,7 +171,8 @@ class Wizard(InfoBar):
if (not self.screen.current_record.validate()
and state != self.end_state):
self.screen.display(set_cursor=True)
self.message_info(self.screen.invalid_message(), gtk.MESSAGE_ERROR)
self.message_info(
self.screen.invalid_message(), Gtk.MessageType.ERROR)
return
self.message_info()
self.state = state
@@ -206,52 +205,47 @@ class Wizard(InfoBar):
self.screen.signal_connect(self, 'group-changed',
self._record_changed)
title = gtk.Label()
title.modify_font(pango.FontDescription("bold 14"))
title.set_label(common.ellipsize(self.name, 80))
title = Gtk.Label(
label=common.ellipsize(self.name, 80),
halign=Gtk.Align.START, margin=5,
ellipsize=Pango.EllipsizeMode.END)
tooltips.set_tip(title, self.name)
title.set_padding(20, 4)
title.set_alignment(0.0, 0.5)
title.set_max_width_chars(1)
title.set_ellipsize(pango.ELLIPSIZE_END)
title.set_size_request(0, -1) # Allow overflow
title.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse("#000000"))
title.show()
hbox = gtk.HBox()
hbox.pack_start(title, expand=True, fill=True)
hbox = Gtk.HBox()
hbox.pack_start(title, expand=True, fill=True, padding=0)
hbox.show()
frame = gtk.Frame()
frame.set_shadow_type(gtk.SHADOW_ETCHED_IN)
frame = Gtk.Frame()
frame.set_shadow_type(Gtk.ShadowType.ETCHED_IN)
widget_class(frame, 'wizard-title', True)
frame.add(hbox)
frame.show()
eb = gtk.EventBox()
eb.add(frame)
eb.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse("#ffffff"))
eb.show()
self.widget.pack_start(eb, expand=False, fill=True, padding=3)
self.widget.pack_start(frame, expand=False, fill=True, padding=3)
if self.toolbar_box:
self.widget.pack_start(self.toolbar_box, False, True)
self.widget.pack_start(
self.toolbar_box, expand=False, fill=True, padding=0)
viewport = gtk.Viewport()
viewport.set_shadow_type(gtk.SHADOW_NONE)
viewport = Gtk.Viewport()
viewport.set_shadow_type(Gtk.ShadowType.NONE)
viewport.add(self.screen.widget)
viewport.show()
self.scrolledwindow = gtk.ScrolledWindow()
self.scrolledwindow.set_shadow_type(gtk.SHADOW_NONE)
self.scrolledwindow.set_policy(gtk.POLICY_AUTOMATIC,
gtk.POLICY_AUTOMATIC)
self.scrolledwindow = Gtk.ScrolledWindow()
self.scrolledwindow.set_shadow_type(Gtk.ShadowType.NONE)
self.scrolledwindow.set_policy(
Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
self.scrolledwindow.add(viewport)
self.scrolledwindow.show()
self.widget.pack_start(self.scrolledwindow, expand=True, fill=True)
self.widget.pack_start(
self.scrolledwindow, expand=True, fill=True, padding=0)
self.create_info_bar()
self.widget.pack_start(self.info_bar, False, True)
self.widget.pack_start(
self.info_bar, expand=False, fill=True, padding=0)
class WizardForm(Wizard, TabContent, SignalEvent):
@@ -259,12 +253,13 @@ class WizardForm(Wizard, TabContent, SignalEvent):
def __init__(self, name=''):
super(WizardForm, self).__init__(name=name)
self.toolbar_box = gtk.HBox()
self.hbuttonbox = gtk.HButtonBox()
self.toolbar_box = Gtk.HBox()
self.hbuttonbox = Gtk.HButtonBox()
self.hbuttonbox.set_spacing(5)
self.hbuttonbox.set_layout(gtk.BUTTONBOX_END)
self.hbuttonbox.set_layout(Gtk.ButtonBoxStyle.END)
self.hbuttonbox.show()
self.widget.pack_start(self.toolbar_box, False, True)
self.widget.pack_start(
self.toolbar_box, expand=False, fill=True, padding=0)
self.dialogs = []
self.handlers = {
@@ -280,12 +275,13 @@ class WizardForm(Wizard, TabContent, SignalEvent):
button = super(WizardForm, self)._get_button(state)
response = len(self.states)
button.connect('clicked', self.response, response)
self.hbuttonbox.pack_start(button)
self.hbuttonbox.pack_start(button, expand=True, fill=True, padding=0)
return button
def update(self, view, buttons):
super(WizardForm, self).update(view, buttons)
self.widget.pack_start(self.hbuttonbox, expand=False, fill=True)
self.widget.pack_start(
self.hbuttonbox, expand=False, fill=True, padding=0)
def sig_close(self):
if self.end_state in self.states:
@@ -318,20 +314,22 @@ class WizardDialog(Wizard, NoModal):
name = _('Wizard')
Wizard.__init__(self, name=name)
NoModal.__init__(self)
self.dia = gtk.Dialog(self.name, self.parent,
gtk.DIALOG_DESTROY_WITH_PARENT)
self.dia = Gtk.Dialog(
title=self.name, transient_for=self.parent,
destroy_with_parent=True)
Main().add_window(self.dia)
self.dia.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
self.dia.set_position(Gtk.WindowPosition.CENTER_ON_PARENT)
self.dia.set_icon(TRYTON_ICON)
self.dia.set_deletable(False)
self.dia.connect('delete-event', lambda *a: True)
self.dia.connect('close', self.close)
self.dia.connect('response', self.response)
self.accel_group = gtk.AccelGroup()
self.accel_group = Gtk.AccelGroup()
self.dia.add_accel_group(self.accel_group)
self.dia.vbox.pack_start(self.widget, expand=True, fill=True)
self.dia.vbox.pack_start(
self.widget, expand=True, fill=True, padding=0)
self.register()
@@ -346,9 +344,9 @@ class WizardDialog(Wizard, NoModal):
response = len(self.states)
self.dia.add_action_widget(button, response)
if definition['default']:
button.add_accelerator('clicked', self.accel_group,
gtk.keysyms.Return, gtk.gdk.CONTROL_MASK,
gtk.ACCEL_VISIBLE)
button.add_accelerator(
'clicked', self.accel_group, Gdk.KEY_Return,
Gdk.ModifierType.CONTROL_MASK, Gtk.AccelFlags.VISIBLE)
button.get_style_context().add_class(
Gtk.STYLE_CLASS_SUGGESTED_ACTION)
button.set_can_default(True)
@@ -359,10 +357,11 @@ class WizardDialog(Wizard, NoModal):
def update(self, view, buttons):
super(WizardDialog, self).update(view, buttons)
current_view = self.screen.current_view
self.scrolledwindow.set_policy(gtk.POLICY_NEVER, gtk.POLICY_NEVER)
self.scrolledwindow.set_policy(
Gtk.PolicyType.NEVER, Gtk.PolicyType.NEVER)
if current_view.scroll:
current_view.scroll.set_policy(
gtk.POLICY_NEVER, gtk.POLICY_NEVER)
Gtk.PolicyType.NEVER, Gtk.PolicyType.NEVER)
self.show()
def destroy(self, action=None):
@@ -395,7 +394,7 @@ class WizardDialog(Wizard, NoModal):
screen.client_action(action)
def close(self, widget, event=None):
widget.emit_stop_by_name('close')
widget.stop_emission_by_name('close')
if self.end_state in self.states:
self.states[self.end_state].clicked()
return True
+5 -3
View File
@@ -5,9 +5,10 @@ import os
import locale
import gettext
import logging
import gtk
import sys
from gi.repository import Gtk
from tryton.config import CURRENT_DIR
_ = gettext.gettext
@@ -199,6 +200,7 @@ def setlang(lang=None, locale_dict=None):
def set_language_direction(direction):
if direction == 'rtl':
gtk.widget_set_default_direction(gtk.TEXT_DIR_RTL)
direction = Gtk.TextDirection.RTL
else:
gtk.widget_set_default_direction(gtk.TEXT_DIR_LTR)
direction = Gtk.TextDirection.LTR
Gtk.Widget.set_default_direction(direction)