Mercurial > libervia-desktop-kivy
changeset 220:24f8ab7c08be
core: implemented showDialog so message/dialogs from QuickFrontend are displayed
author | Goffi <goffi@goffi.org> |
---|---|
date | Tue, 26 Jun 2018 07:11:16 +0200 |
parents | 9faccd140119 |
children | e1a385a791cc |
files | cagou/core/cagou_main.py cagou/core/common.py |
diffstat | 2 files changed, 99 insertions(+), 26 deletions(-) [+] |
line wrap: on
line diff
--- a/cagou/core/cagou_main.py Sun Jun 24 22:26:15 2018 +0200 +++ b/cagou/core/cagou_main.py Tue Jun 26 07:11:16 2018 +0200 @@ -50,7 +50,8 @@ from kivy.uix.label import Label from kivy.uix.boxlayout import BoxLayout from kivy.uix.floatlayout import FloatLayout -from kivy.uix.screenmanager import ScreenManager, Screen, FallOutTransition, RiseInTransition +from kivy.uix.screenmanager import (ScreenManager, Screen, + FallOutTransition, RiseInTransition) from kivy.uix.dropdown import DropDown from kivy.core.window import Window from kivy.animation import Animation @@ -59,6 +60,7 @@ from . import widgets_handler from .common import IconButton from . import menu +from . import dialog from importlib import import_module import os.path import glob @@ -99,13 +101,15 @@ class Note(Label): title = properties.StringProperty() message = properties.StringProperty() - level = properties.OptionProperty(C.XMLUI_DATA_LVL_DEFAULT, options=list(C.XMLUI_DATA_LVLS)) + level = properties.OptionProperty(C.XMLUI_DATA_LVL_DEFAULT, + options=list(C.XMLUI_DATA_LVLS)) class NoteDrop(Label): title = properties.StringProperty() message = properties.StringProperty() - level = properties.OptionProperty(C.XMLUI_DATA_LVL_DEFAULT, options=list(C.XMLUI_DATA_LVLS)) + level = properties.OptionProperty(C.XMLUI_DATA_LVL_DEFAULT, + options=list(C.XMLUI_DATA_LVLS)) class NotesDrop(DropDown): @@ -137,6 +141,11 @@ self.notes_drop = NotesDrop(self.notes) def addNotif(self, callback, *args, **kwargs): + """add a notification with a callback attached + + when notification is pressed, callback is called + @param *args, **kwargs: arguments of callback + """ self.notifs_icon.addNotif(callback, *args, **kwargs) def addNote(self, title, message, level): @@ -149,6 +158,10 @@ def addNotifUI(self, ui): self.notifs_icon.addNotif(ui.show, force=True) + def addNotifWidget(self, widget): + app = App.get_running_app() + self.notifs_icon.addNotif(app.host.showExtraUI, widget=widget) + def _displayNextNote(self, dummy=None): screen = Screen() try: @@ -229,6 +242,9 @@ def addNotifUI(self, ui): self.head_widget.addNotifUI(ui) + def addNotifWidget(self, widget): + self.head_widget.addNotifWidget(widget) + class CagouApp(App): """Kivy App for Cagou""" @@ -269,8 +285,9 @@ def on_start(self): if sys.platform == "android": - # XXX: we use memory map instead of bridge because if we try to call a bridge method - # in on_pause method, the call data is not written before the actual pause + # XXX: we use memory map instead of bridge because if we + # try to call a bridge method in on_pause method, the call data + # is not written before the actual pause # we create a memory map on .cagou_status file with a 1 byte status # status is: # R => running @@ -280,7 +297,8 @@ self.cagou_status_fd = open('.cagou_status', 'wb+') self.cagou_status_fd.write('R') self.cagou_status_fd.flush() - self.cagou_status = mmap.mmap(self.cagou_status_fd.fileno(), 1, prot=mmap.PROT_WRITE) + self.cagou_status = mmap.mmap(self.cagou_status_fd.fileno(), 1, + prot=mmap.PROT_WRITE) def on_pause(self): self.cagou_status[0] = 'P' @@ -347,19 +365,25 @@ sys.exit(3) else: log.debug(u"Loading {} bridge".format(bridge_name)) - super(Cagou, self).__init__(bridge_factory=bridge_module.Bridge, xmlui=xmlui, check_options=quick_utils.check_options, connect_bridge=False) + super(Cagou, self).__init__(bridge_factory=bridge_module.Bridge, + xmlui=xmlui, + check_options=quick_utils.check_options, + connect_bridge=False) self._import_kv() self.app = CagouApp() self.app.host = self - self.media_dir = self.app.media_dir = config.getConfig(main_config, '', 'media_dir') - self.downloads_dir = self.app.downloads_dir = config.getConfig(main_config, '', 'downloads_dir') + self.media_dir = self.app.media_dir = config.getConfig(main_config, '', + 'media_dir') + self.downloads_dir = self.app.downloads_dir = config.getConfig(main_config, '', + 'downloads_dir') if not os.path.exists(self.downloads_dir): try: os.makedirs(self.downloads_dir) except OSError as e: log.warnings(_(u"Can't create downloads dir: {reason}").format(reason=e)) self.app.default_avatar = os.path.join(self.media_dir, "misc/default_avatar.png") - self.app.icon = os.path.join(self.media_dir, "icons/muchoslava/png/cagou_profil_bleu_96.png") + self.app.icon = os.path.join(self.media_dir, + "icons/muchoslava/png/cagou_profil_bleu_96.png") self._plg_wids = [] # main widgets plugins self._plg_wids_transfer = [] # transfer widgets plugins self._import_plugins() @@ -423,7 +447,10 @@ @param profiles(iterable): list of profiles """ main_cls = plugin_info['main'] - return self.widgets.getOrCreateWidget(main_cls, target, on_new_widget=None, profiles=iter(self.profiles)) + return self.widgets.getOrCreateWidget(main_cls, + target, + on_new_widget=None, + profiles=iter(self.profiles)) def _defaultFactoryTransfer(self, plugin_info, callback, cancel_cb, profiles): """default factory used to create transfer widgets instances @@ -463,9 +490,12 @@ self.default_wid = None plugins_path = os.path.dirname(cagou.plugins.__file__) plugin_glob = u"plugin*." + C.PLUGIN_EXT - plug_lst = [os.path.splitext(p)[0] for p in map(os.path.basename, glob.glob(os.path.join(plugins_path, plugin_glob)))] + plug_lst = [os.path.splitext(p)[0] for p in + map(os.path.basename, glob.glob(os.path.join(plugins_path, + plugin_glob)))] - imported_names_main = set() # used to avoid loading 2 times plugin with same import name + imported_names_main = set() # used to avoid loading 2 times + # plugin with same import name imported_names_transfer = set() for plug in plug_lst: plugin_path = 'cagou.plugins.' + plug @@ -485,7 +515,8 @@ imported_names = imported_names_transfer default_factory = self._defaultFactoryTransfer else: - log.error(u"unknown plugin type {type_} for plugin {file_}, skipping".format( + log.error(u"unknown plugin type {type_} for plugin {file_}, skipping" + .format( type_ = plugin_type, file_ = plug )) @@ -503,18 +534,22 @@ if 'platforms' in plugin_info: if sys.platform not in plugin_info['platforms']: - log.info(u"{plugin_file} is not used on this platform, skipping".format(**plugin_info)) + log.info(u"{plugin_file} is not used on this platform, skipping" + .format(**plugin_info)) continue # import name is used to differentiate plugins if 'import_name' not in plugin_info: plugin_info['import_name'] = plug if plugin_info['import_name'] in imported_names: - log.warning(_(u"there is already a plugin named {}, ignoring new one").format(plugin_info['import_name'])) + log.warning(_(u"there is already a plugin named {}, " + u"ignoring new one").format(plugin_info['import_name'])) continue if plugin_info['import_name'] == C.WID_SELECTOR: if plugin_type != C.PLUG_TYPE_WID: - log.error(u"{import_name} import name can only be used with {type_} type, skipping {name}".format(type_=C.PLUG_TYPE_WID, **plugin_info)) + log.error(u"{import_name} import name can only be used with {type_} " + u"type, skipping {name}".format(type_=C.PLUG_TYPE_WID, + **plugin_info)) continue # if WidgetSelector exists, it will be our default widget self.default_wid = plugin_info @@ -634,7 +669,8 @@ break if to_change is None: - raise exceptions.InternalError(u"no CagouWidget found when trying to switch widget") + raise exceptions.InternalError(u"no CagouWidget found when " + u"trying to switch widget") wrapper = to_change.parent while wrapper is not None and not(isinstance(wrapper, widgets_handler.WHWrapper)): @@ -677,7 +713,11 @@ if widget.parent is None: return widget targets = list(widget.targets) - w = self.widgets.getOrCreateWidget(widget.__class__, targets[0], on_new_widget=None, on_existing_widget=C.WIDGET_RECREATE, profiles=widget.profiles) + w = self.widgets.getOrCreateWidget(widget.__class__, + targets[0], + on_new_widget=None, + on_existing_widget=C.WIDGET_RECREATE, + profiles=widget.profiles) for t in targets[1:]: w.addTarget(t) return w @@ -687,7 +727,9 @@ def _menusGetCb(self, backend_menus): main_menu = self.app.root.root_menus self.menus.addMenus(backend_menus) - self.menus.addMenu(C.MENU_GLOBAL, (_(u"Help"), _(u"About")), callback=main_menu.onAbout) + self.menus.addMenu(C.MENU_GLOBAL, + (_(u"Help"), _(u"About")), + callback=main_menu.onAbout) main_menu.update(C.MENU_GLOBAL) ## bridge handlers ## @@ -706,9 +748,11 @@ self.bridge.menusGet("", C.NO_SECURITY_LIMIT, callback=self._menusGetCb) def setPresenceStatus(self, show='', status=None, profile=C.PROF_KEY_NONE): - log.info(u"Profile presence status set to {show}/{status}".format(show=show, status=status)) + log.info(u"Profile presence status set to {show}/{status}".format(show=show, + status=status)) - def errback(self, failure_, title=_('error'), message=_(u'error while processing: {msg}')): + def errback(self, failure_, title=_('error'), + message=_(u'error while processing: {msg}')): self.addNote(title, message.format(msg=failure_), level=C.XMLUI_DATA_LVL_WARNING) def addNote(self, title, message, level=C.XMLUI_DATA_LVL_INFO): @@ -722,6 +766,13 @@ """ self.app.root.addNotifUI(ui) + def addNotifWidget(self, widget): + """add a notification with a Kivy widget attached + + @param widget(kivy.uix.Widget): widget to attach to notification + """ + self.app.root.addNotifWidget(widget) + def showUI(self, ui): """show a XMLUI""" self.app.root.changeWidget(ui, "xmlui") @@ -738,10 +789,31 @@ def getDefaultAvatar(self, entity=None): return self.app.default_avatar + def _dialog_cb(self, cb, *args, **kwargs): + """generic dialog callback + + close dialog then call the callback with given arguments + """ + def callback(): + self.closeUI() + cb(*args, **kwargs) + return callback + def showDialog(self, message, title, type="info", answer_cb=None, answer_data=None): - # TODO - log.info(u"FIXME: showDialog not implemented") - log.info(u"message: {} -- {}".format(title, message)) + if type in ('info', 'warning', 'error'): + self.addNote(title, message, type) + elif type == "yes/no": + wid = dialog.ConfirmDialog(title=title, message=message, + yes_cb=self._dialog_cb(answer_cb, + True, + answer_data), + no_cb=self._dialog_cb(answer_cb, + False, + answer_data) + ) + self.addNotifWidget(wid) + else: + log.warning(_(u"unknown dialog type: {dialog_type}").format(dialog_type=type)) def desktop_notif(self, message, title=u'', duration=5000):
--- a/cagou/core/common.py Sun Jun 24 22:26:15 2018 +0200 +++ b/cagou/core/common.py Tue Jun 26 07:11:16 2018 +0200 @@ -56,7 +56,8 @@ wid.opacity = 0 return "" else: - return host.getAvatar(self.jid, profile=self.profile) or host.getDefaultAvatar(self.jid) + return (host.getAvatar(self.jid, profile=self.profile) + or host.getDefaultAvatar(self.jid)) class JidButton(ButtonBehavior, JidItem):