Improve note button
* Add resources method to ModelStorage * Support badge on icon * Display unread and total of notes * Add two extra colors for icon issue8122 review70561002
This commit is contained in:
1 parent
8a179f313b
commit
aaf9e9e75c
6 files changed
+81
-113
No files matched your search
@@ -1,3 +1,6 @@
|
||||
* Display unread and total of notes
|
||||
* Support badge on icon
|
||||
* Use resources method
|
||||
* Replace Arrow by Image
|
||||
* Remove Fast Tabbing option
|
||||
* Remove usage of focus_chain
|
||||
|
||||
+23
-8
@@ -111,10 +111,12 @@ class IconFactory:
|
||||
cls._tryton_icons.remove((icon['id'], icon['name']))
|
||||
del cls._name2id[icon['name']]
|
||||
|
||||
colors = CONFIG['icon.colors'].split(',')
|
||||
|
||||
@classmethod
|
||||
def get_pixbuf(cls, iconname, size=16, color=None):
|
||||
def get_pixbuf(cls, iconname, size=16, color=None, badge=None):
|
||||
cls.register_icon(iconname)
|
||||
if iconname not in cls._pixbufs[size]:
|
||||
if iconname not in cls._pixbufs[(size, badge)]:
|
||||
if iconname in cls._icons:
|
||||
data = cls._icons[iconname]
|
||||
elif iconname in cls._local_icons:
|
||||
@@ -124,12 +126,24 @@ class IconFactory:
|
||||
else:
|
||||
logger.error("Unknown icon %s" % iconname)
|
||||
return
|
||||
if color is None:
|
||||
color = CONFIG['icon.color']
|
||||
if not color:
|
||||
color = cls.colors[0]
|
||||
try:
|
||||
ET.register_namespace('', 'http://www.w3.org/2000/svg')
|
||||
root = ET.fromstring(data)
|
||||
root.attrib['fill'] = color
|
||||
if badge:
|
||||
if not isinstance(badge, str):
|
||||
try:
|
||||
badge = cls.colors[badge]
|
||||
except IndexError:
|
||||
badge = color
|
||||
ET.SubElement(root, 'circle', {
|
||||
'cx': '20',
|
||||
'cy': '4',
|
||||
'r': '4',
|
||||
'fill': badge,
|
||||
})
|
||||
data = ET.tostring(root)
|
||||
except ET.ParseError:
|
||||
pass
|
||||
@@ -141,12 +155,13 @@ class IconFactory:
|
||||
Gtk.IconSize.DND: 12,
|
||||
Gtk.IconSize.DIALOG: 48,
|
||||
}.get(size, size)
|
||||
cls._pixbufs[size][iconname] = data2pixbuf(data, width, height)
|
||||
return cls._pixbufs[size][iconname]
|
||||
pixbuf = data2pixbuf(data, width, height)
|
||||
cls._pixbufs[(size, badge)][iconname] = pixbuf
|
||||
return cls._pixbufs[(size, badge)][iconname]
|
||||
|
||||
@classmethod
|
||||
def get_image(cls, iconname, size=16, color=None):
|
||||
pixbuf = cls.get_pixbuf(iconname, size, color)
|
||||
def get_image(cls, iconname, size=16, color=None, badge=None):
|
||||
pixbuf = cls.get_pixbuf(iconname, size, color, badge)
|
||||
image = Gtk.Image()
|
||||
image.set_from_pixbuf(pixbuf)
|
||||
return image
|
||||
|
||||
+1
-1
@@ -55,7 +55,7 @@ class ConfigManager(object):
|
||||
'client.limit': 1000,
|
||||
'client.check_version': True,
|
||||
'client.bus_timeout': 10 * 60,
|
||||
'icon.color': '#3465a4',
|
||||
'icon.colors': '#3465a4,#555753,#cc0000',
|
||||
'image.max_size': 10 ** 6,
|
||||
'bug.url': 'https://bugs.tryton.org/',
|
||||
'download.url': 'https://downloads.tryton.org/',
|
||||
|
||||
+38
-51
@@ -53,9 +53,9 @@ class Form(SignalEvent, TabContent):
|
||||
self.screen.signal_connect(self, 'record-modified',
|
||||
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)
|
||||
self.screen.signal_connect(self, 'unread-note', self._unread_note)
|
||||
self.screen.signal_connect(
|
||||
self, 'resources',
|
||||
lambda screen, resources: self.update_resources(resources))
|
||||
|
||||
if res_id not in (None, False):
|
||||
if isinstance(res_id, int):
|
||||
@@ -105,7 +105,7 @@ class Form(SignalEvent, TabContent):
|
||||
def sig_attach(self, widget=None):
|
||||
def window(widget):
|
||||
return Attachment(
|
||||
record, lambda: self.update_attachment_count(reload=True))
|
||||
record, lambda: self.refresh_resources(reload=True))
|
||||
|
||||
def add_file(widget):
|
||||
filenames = common.file_selection(_("Select"), multi=True)
|
||||
@@ -139,61 +139,48 @@ class Form(SignalEvent, TabContent):
|
||||
menu.connect('deactivate', self._popup_menu_hide, button)
|
||||
self.action_popup(button)
|
||||
|
||||
def update_attachment_count(self, reload=False):
|
||||
record = self.screen.current_record
|
||||
if record:
|
||||
attachment_count = record.get_attachment_count(reload=reload)
|
||||
else:
|
||||
attachment_count = 0
|
||||
self._attachment_count(None, attachment_count)
|
||||
|
||||
def _attachment_count(self, widget, signal_data):
|
||||
label = _('Attachment(%d)') % signal_data
|
||||
self.buttons['attach'].set_label(label)
|
||||
if signal_data:
|
||||
# FIXME
|
||||
icon = 'tryton-attach'
|
||||
else:
|
||||
icon = 'tryton-attach'
|
||||
image = common.IconFactory.get_image(icon, Gtk.IconSize.LARGE_TOOLBAR)
|
||||
image.show()
|
||||
self.buttons['attach'].set_icon_widget(image)
|
||||
record = self.screen.current_record
|
||||
self.buttons['attach'].props.sensitive = bool(
|
||||
record.id >= 0 if record else False)
|
||||
|
||||
def sig_note(self, widget=None):
|
||||
record = self.screen.current_record
|
||||
if not record or record.id < 0:
|
||||
return
|
||||
Note(record,
|
||||
lambda: self.update_unread_note(reload=True))
|
||||
lambda: self.refresh_resources(reload=True))
|
||||
|
||||
def update_unread_note(self, reload=False):
|
||||
def refresh_resources(self, reload=False):
|
||||
record = self.screen.current_record
|
||||
if record:
|
||||
unread = record.get_unread_note(reload=reload)
|
||||
else:
|
||||
unread = 0
|
||||
self._unread_note(None, unread)
|
||||
self.update_resources(
|
||||
record.get_resources(reload=reload) if record else None)
|
||||
|
||||
def _unread_note(self, widget, signal_data):
|
||||
label = _('Note(%d)') % signal_data
|
||||
self.buttons['note'].set_label(label)
|
||||
if signal_data:
|
||||
# FIXME
|
||||
icon = 'tryton-note'
|
||||
else:
|
||||
icon = 'tryton-note'
|
||||
image = common.IconFactory.get_image(icon, Gtk.IconSize.LARGE_TOOLBAR)
|
||||
image.show()
|
||||
self.buttons['note'].set_icon_widget(image)
|
||||
def update_resources(self, resources):
|
||||
if not resources:
|
||||
resources = {}
|
||||
record = self.screen.current_record
|
||||
if not record or record.id < 0:
|
||||
sensitive = False
|
||||
sensitive = record.id >= 0 if record else False
|
||||
|
||||
def update(name, label, icon, badge):
|
||||
button = self.buttons[name]
|
||||
button.set_label(label)
|
||||
image = common.IconFactory.get_image(
|
||||
icon, Gtk.IconSize.LARGE_TOOLBAR, badge=badge)
|
||||
image.show()
|
||||
button.set_icon_widget(image)
|
||||
button.props.sensitive = sensitive
|
||||
|
||||
attachment_count = resources.get('attachment_count', 0)
|
||||
badge = 1 if attachment_count else None
|
||||
label = _("Attachment (%s)") % attachment_count
|
||||
update('attach', label, 'tryton-attach', badge)
|
||||
|
||||
note_count = resources.get('note_count', 0)
|
||||
note_unread = resources.get('note_unread', 0)
|
||||
if note_unread:
|
||||
badge = 2
|
||||
elif note_count:
|
||||
badge = 1
|
||||
else:
|
||||
sensitive = True
|
||||
self.buttons['note'].props.sensitive = sensitive
|
||||
badge = None
|
||||
label = _("Note (%d/%d)") % (note_unread, note_count)
|
||||
update('note', label, 'tryton-note', badge)
|
||||
|
||||
def sig_switch(self, widget=None):
|
||||
if not self.modified_save():
|
||||
@@ -498,7 +485,7 @@ class Form(SignalEvent, TabContent):
|
||||
|
||||
def _record_saved(self, screen, signal_data):
|
||||
self.activate_save()
|
||||
self.update_attachment_count()
|
||||
self.refresh_resources()
|
||||
|
||||
def modified_save(self):
|
||||
self.screen.save_tree_state()
|
||||
@@ -711,7 +698,7 @@ class Form(SignalEvent, TabContent):
|
||||
if not record or record.id < 0:
|
||||
return
|
||||
win_attach = Attachment(record,
|
||||
lambda: self.update_attachment_count(reload=True))
|
||||
lambda: self.refresh_resources(reload=True))
|
||||
if info == 0:
|
||||
if selection.get_uris():
|
||||
for uri in selection.get_uris():
|
||||
|
||||
@@ -28,8 +28,7 @@ class Record(SignalEvent):
|
||||
self.state_attrs = {}
|
||||
self.modified_fields = {}
|
||||
self._timestamp = None
|
||||
self.attachment_count = -1
|
||||
self.unread_note = -1
|
||||
self.resources = None
|
||||
self.button_clicks = {}
|
||||
self.next = {} # Used in Group list
|
||||
self.value = {}
|
||||
@@ -602,34 +601,15 @@ class Record(SignalEvent):
|
||||
if context:
|
||||
value.context = self.expr_eval(context)
|
||||
|
||||
def get_attachment_count(self, reload=False):
|
||||
if self.id < 0:
|
||||
return 0
|
||||
if self.attachment_count < 0 or reload:
|
||||
def get_resources(self, reload=False):
|
||||
if self.id >= 0 and (not self.resources or reload):
|
||||
try:
|
||||
self.attachment_count = RPCExecute('model', 'ir.attachment',
|
||||
'search_count', [
|
||||
('resource', '=',
|
||||
'%s,%s' % (self.model_name, self.id)),
|
||||
], context=self.get_context())
|
||||
self.resources = RPCExecute(
|
||||
'model', self.model_name, 'resources', self.id,
|
||||
context=self.get_context())
|
||||
except RPCException:
|
||||
return 0
|
||||
return self.attachment_count
|
||||
|
||||
def get_unread_note(self, reload=False):
|
||||
if self.id < 0:
|
||||
return 0
|
||||
if self.unread_note < 0 or reload:
|
||||
try:
|
||||
self.unread_note = RPCExecute('model', 'ir.note',
|
||||
'search_count', [
|
||||
('resource', '=',
|
||||
'%s,%s' % (self.model_name, self.id)),
|
||||
('unread', '=', True),
|
||||
], context=self.get_context())
|
||||
except RPCException:
|
||||
return 0
|
||||
return self.unread_note
|
||||
pass
|
||||
return self.resources
|
||||
|
||||
def get_button_clicks(self, name):
|
||||
if self.id < 0:
|
||||
|
||||
@@ -436,35 +436,18 @@ class Screen(SignalEvent):
|
||||
pos = 0
|
||||
self.signal('record-message', (pos, len(self.group) + self.offset,
|
||||
self.search_count, record and record.id))
|
||||
attachment_count = 0
|
||||
if record and record.attachment_count > 0:
|
||||
attachment_count = record.attachment_count
|
||||
self.signal('attachment-count', attachment_count)
|
||||
unread_note = 0
|
||||
if record and record.unread_note > 0:
|
||||
unread_note = record.unread_note
|
||||
self.signal('unread-note', unread_note)
|
||||
# update attachment-count after 1 second
|
||||
GLib.timeout_add(1000, self.update_attachment, record)
|
||||
GLib.timeout_add(1000, self.update_note, record)
|
||||
self.signal('resources', record.resources if record else None)
|
||||
# update resources after 1 second
|
||||
GLib.timeout_add(1000, self._update_resources, record)
|
||||
return True
|
||||
|
||||
current_record = property(__get_current_record, __set_current_record)
|
||||
|
||||
def update_attachment(self, record):
|
||||
if record != self.current_record:
|
||||
return False
|
||||
if record and self.signal_connected('attachment-count'):
|
||||
attachment_count = record.get_attachment_count()
|
||||
self.signal('attachment-count', attachment_count)
|
||||
return False
|
||||
|
||||
def update_note(self, record):
|
||||
if record != self.current_record:
|
||||
return False
|
||||
if record and self.signal_connected('unread-note'):
|
||||
unread_note = record.get_unread_note()
|
||||
self.signal('unread-note', unread_note)
|
||||
def _update_resources(self, record):
|
||||
if (record
|
||||
and record == self.current_record
|
||||
and self.signal_connected('resources')):
|
||||
self.signal('resources', record.get_resources())
|
||||
return False
|
||||
|
||||
def destroy(self):
|
||||
|
||||
Reference in new issue
Block a user