def _create_timed_alert(self, title, msg, timeout=10): alert = NotifyAlert(timeout) alert.props.title = title alert.props.msg = msg alert.connect('response', self._alert_cancel_cb) self.add_alert(alert)
def _alert(self, title, msg=None): a = NotifyAlert() a.props.title = title a.props.msg = msg self.activity.add_alert(a) a.connect('response', lambda a, r: self.activity.remove_alert(a)) a.show()
def _load_project(self, button): chooser = ObjectChooser(parent=self) result = chooser.run() if result == Gtk.ResponseType.ACCEPT: dsobject = chooser.get_selected_object() file_path = dsobject.get_file_path() try: f = open(file_path, 'r') # Test if the file is valid project. json.loads(f.read()) f.close() self.read_file(file_path) self.game.run(True) except: title = _('Load project from journal') msg = _( 'Error: Cannot open Physics project from this file.') alert = NotifyAlert(5) alert.props.title = title alert.props.msg = msg alert.connect( 'response', lambda alert, response: self.remove_alert(alert)) self.add_alert(alert) chooser.destroy()
def action(alert, response): self.remove_alert(alert) if not response is Gtk.ResponseType.OK: return try: f = open(file_path, 'r') # Test if the file is valid project. json.loads(f.read()) f.close() self.read_file(file_path) self.game.run(True) except: title = _('Load project from journal') if not journal: title = _('Load example') msg = _( 'Error: Cannot open Physics project from this file.') alert = NotifyAlert(5) alert.props.title = title alert.props.msg = msg alert.connect( 'response', lambda alert, response: self.remove_alert(alert)) self.add_alert(alert)
def save_to_gsettings(self, icon=False, name=False): gsettings = Gio.Settings(_DESKTOP_CONF_DIR) homeviews = [] for button in self._view_buttons: homeview = {'layout': 'ring-layout', 'view-icon': self._view_icons[button], 'favorite-icon': self._favorite_icons[button], 'view-label': self._favorite_names[button]} homeviews.append(homeview) variant = GLib.Variant('aa{ss}', homeviews) gsettings.set_value(_HOMEVIEWS_KEY, variant) if icon: for x in self.activity._alerts: self.activity.remove_alert(x) alert = NotifyAlert(5) alert.props.title = _('Icon') alert.props.msg = _('For see icons, restart sugar is needed.') self.activity.add_alert(alert) alert.connect('response', lambda x, y: self.activity.remove_alert(x)) if name: for x in self.activity._alerts: self.activity.remove_alert(x) alert = NotifyAlert(5) alert.props.title = _('View Name') alert.props.msg = _('For seeing View name changes, ' 'restarting Sugar is required.') self.activity.add_alert(alert) alert.connect('response', lambda x, y: self.activity.remove_alert(x))
def _alert(self, title, text=None): alert = NotifyAlert(timeout=20) alert.props.title = title alert.props.msg = text self.add_alert(alert) alert.connect('response', self._alert_cancel_cb) alert.show()
class _SharedJournalEntry(SharedJournalEntry): __gsignals__ = { 'transfer-state-changed': (GObject.SignalFlags.RUN_FIRST, None, ([str, str])), } def __init__(self, account): self._account = account self._alert = None def get_share_menu(self, get_uid_list): menu = _ShareMenu(self._account, get_uid_list, True) self._connect_transfer_signals(menu) return menu def __display_alert_cb(self, widget, title, message): if self._alert is None: self._alert = NotifyAlert() self._alert.connect('response', self.__alert_response_cb) journalwindow.get_journal_window().add_alert(self._alert) self._alert.show() self._alert.props.title = title self._alert.props.msg = message def __alert_response_cb(self, alert, response_id): journalwindow.get_journal_window().remove_alert(alert) self._alert = None def _connect_transfer_signals(self, transfer_widget): transfer_widget.connect('transfer-state-changed', self.__display_alert_cb)
class _SharedJournalEntry(account.SharedJournalEntry): __gsignals__ = { 'transfer-state-changed': (GObject.SignalFlags.RUN_FIRST, None, ([str])), } def __init__(self, account): self._account = account self._alert = None def get_share_menu(self, get_uid_list): menu = _ShareMenu(self._account, get_uid_list, True) self._connect_transfer_signals(menu) return menu def _connect_transfer_signals(self, transfer_widget): transfer_widget.connect('transfer-state-changed', self.__display_alert_cb) def __display_alert_cb(self, widget, message): if self._alert is None: self._alert = NotifyAlert() self._alert.props.title = ACCOUNT_NAME self._alert.connect('response', self.__alert_response_cb) journalwindow.get_journal_window().add_alert(self._alert) self._alert.show() self._alert.props.msg = message def __alert_response_cb(self, alert, response_id): journalwindow.get_journal_window().remove_alert(alert) self._alert = None
def _alert(self, title, msg=None): a = NotifyAlert() a.props.title = title a.props.msg = msg self.activity.add_alert(a) a.connect('response', lambda a, r: self.activity.remove_alert(a)) a.show()
def remove_confirmation(self, alert, response_id, path, cp_path, vbox, title): print cp_path, title if response_id == Gtk.ResponseType.OK: try: shutil.rmtree(path) shutil.rmtree(os.path.join(cp_path, title)) alert_ = NotifyAlert(5) alert_.props.title = _('Removed') alert_.props.msg = _('Extension removed.' ' Please restart sugar for see efects') alert_.connect('response', lambda x, y: self.activity.remove_alert(x)) self.activity.add_alert(alert_) self.remove(vbox) except: alert_ = NotifyAlert(5) alert_.props.title = _('Error') alert_.props.msg = _('Error removing extension.') alert_.connect('response', lambda x, y: self.activity.remove_alert(x)) self.activity.add_alert(alert_) else: pass self.activity.remove_alert(alert)
def add_view(self, widget): if len(self._view_icons) >= 5: for x in self.activity._alerts: self.activity.remove_alert(x) alert = NotifyAlert(10) alert.props.title = _('Limit reached') alert.props.msg = _('You have reached the maximum limit of ' 'favorites views, please delete some before ' 'continuing.') self.activity.add_alert(alert) alert.connect('response', lambda x, y: self.activity.remove_alert(x)) return current = len(self._view_buttons) + 1 label = _('Favorites view %d') % current button = ToolbarButton(label=label, icon_name='view-radial') page = FavoritePage(button, self, 'view-radial', 'emblem-favorite', label) button.set_page(page) self._view_icons[button] = 'view-radial' self._favorite_icons[button] = 'emblem-favorite' self._view_buttons[button] = button self._favorite_names[button] = label self.insert(button, -1) self.save_to_gsettings() self.show_all()
def add_view(self, widget): if len(self._view_icons) >= 5: for x in self.activity._alerts: self.activity.remove_alert(x) alert = NotifyAlert(10) alert.props.title = _('Limit reached') alert.props.msg = _('You have reached the maximum limit of ' 'favorites views, please delete some before ' 'continuing.') self.activity.add_alert(alert) alert.connect('response', lambda x, y: self.activity.remove_alert(x)) return current = len(self._view_buttons) + 1 label = _('Favorites view %d') % current button = ToolbarButton(label=label, icon_name='view-radial') page = FavoritePage(button, self, 'view-radial', 'emblem-favorite', label) button.set_page(page) self._view_icons[button] = 'view-radial' self._favorite_icons[button] = 'emblem-favorite' self._view_buttons[button] = button if self.favorite_names_enabled: self._favorite_names[button] = label self.insert(button, -1) self.save_to_gconf() self.show_all()
def action(alert, response): self.remove_alert(alert) if response is not Gtk.ResponseType.OK: return try: f = open(file_path, 'r') # Test if the file is valid project. json.loads(f.read()) f.close() self.read_file(file_path) self.game.run(True) except: title = _('Load project from journal') if not journal: title = _('Load example') msg = _( 'Error: Cannot open Physics project from this file.') alert = NotifyAlert(5) alert.props.title = title alert.props.msg = msg alert.connect( 'response', lambda alert, response: self.remove_alert(alert)) self.add_alert(alert)
def alert(self, title, text=None, timeout=5): if text != None: alert = NotifyAlert(timeout=timeout) alert.props.title = title alert.props.msg = text self.add_alert(alert) alert.connect('response', self.alert_cancel_cb) alert.show()
def alert(self, title, text=None, timeout=5): if text != None: alert = NotifyAlert(timeout=timeout) alert.props.title = title alert.props.msg = text self.add_alert(alert) alert.connect('response', self.cancel_alert) alert.show()
class FacebookAccount(account.Account): ACCESS_TOKEN_KEY = "/desktop/sugar/collaboration/facebook_access_token" ACCESS_TOKEN_KEY_EXPIRATION_DATE = \ "/desktop/sugar/collaboration/facebook_access_token_expiration_date" def __init__(self): self._client = GConf.Client.get_default() facebook.FbAccount.set_access_token(self._access_token()) self._alert = None def get_description(self): return ACCOUNT_NAME def is_configured(self): return self._access_token() is not None def is_active(self): expiration_date = \ self._client.get_int(self.ACCESS_TOKEN_KEY_EXPIRATION_DATE) return expiration_date != 0 and expiration_date > time.time() def get_share_menu(self, journal_entry_metadata): fb_share_menu = _FacebookShareMenu(journal_entry_metadata, self.is_active()) self._connect_transfer_signals(fb_share_menu) return fb_share_menu def get_refresh_menu(self): fb_refresh_menu = _FacebookRefreshMenu(self.is_active()) self._connect_transfer_signals(fb_refresh_menu) return fb_refresh_menu def _connect_transfer_signals(self, transfer_widget): transfer_widget.connect('transfer-state-changed', self._transfer_state_changed_cb) def _transfer_state_changed_cb(self, widget, state_message): logging.debug('_transfer_state_changed_cb') # First, remove any existing alert if self._alert is None: logging.debug('creating new alert') self._alert = NotifyAlert() self._alert.props.title = ACCOUNT_NAME self._alert.connect('response', self._alert_response_cb) journalwindow.get_journal_window().add_alert(self._alert) self._alert.show() logging.debug(state_message) self._alert.props.msg = state_message def _alert_response_cb(self, alert, response_id): journalwindow.get_journal_window().remove_alert(alert) self._alert = None def _access_token(self): return self._client.get_string(self.ACCESS_TOKEN_KEY)
def _alert(self, title, text=None): alert = NotifyAlert(timeout=5) alert.props.title = title alert.props.msg = text self.add_alert(alert) alert.connect('response', self._alert_cancel_cb) alert.show() self._has_alert = True self._fixed_resize_cb()
def _alert(self, title, text=None): alert = NotifyAlert(timeout=5) alert.props.title = title alert.props.msg = text self.add_alert(alert) alert.connect('response', self._alert_cancel_cb) alert.show() self._has_alert = True self._fixed_resize_cb()
def alert_time(self): def _alert_response_cb(alert, response_id): self.remove_alert(alert) alert = NotifyAlert() alert.props.title = _('Time Up!') alert.props.msg = _('Your time is up.') alert.connect('response', _alert_response_cb) alert.show() self.add_alert(alert)
def notify_alert(self, title, msg): """Raise standard notify alert""" alert = NotifyAlert(title=title, msg=msg) def response(alert, response_id, self): self.remove_alert(alert) alert.connect('response', response, self) alert.show_all() self.add_alert(alert)
def alert_reset(self, mode): def _alert_response_cb(alert, response_id): self.remove_alert(alert) alert = NotifyAlert() alert.props.title = _('Time Reset') alert.props.msg = _('The timer mode was reset to %s' % mode) alert.connect('response', _alert_response_cb) alert.show() self.add_alert(alert)
def get_alert(self, title, text): """ Show an alert above the activity. """ alert = NotifyAlert(timeout=5) alert.props.title = title alert.props.msg = text self.add_alert(alert) alert.connect('response', self.__alert_cancel_cb) alert.show()
def notify_alert(self): alert = NotifyAlert() alert.props.title = _('Saving icon...') msg = _('A restart is required before your new icon will appear.') alert.props.msg = msg def remove_alert(alert, response_id): self.remove_alert(alert) alert.connect('response', remove_alert) self.add_alert(alert)
def internal_callback(): try: urllib.urlretrieve(link, self.file_path, reporthook=self.progress_changed) except Exception, info: alert = NotifyAlert(5) alert.props.title = _('Error') alert.props.msg = info alert.connect('response', lambda x, y: self.activity.remove_alert(x)) self.activity.add_alert(alert)
def notify_alert(self): alert = NotifyAlert() alert.props.title = _('Saving icon...') msg = _('A restart is required before your new icon will appear.') alert.props.msg = msg def remove_alert(alert, response_id): self.remove_alert(alert) alert.connect('response', remove_alert) self.add_alert(alert)
def _delete_log_cb(self, widget): if self.viewer.active_log: logfile = self.viewer.active_log.logfile try: os.remove(logfile) except OSError, err: notify = NotifyAlert() notify.props.title = _('Error') notify.props.msg = _('%(error)s when deleting %(file)s') % \ {'error': err.strerror, 'file': logfile} notify.connect('response', _notify_response_cb, self) self.add_alert(notify)
def _delete_log_cb(self, widget): if self.viewer.active_log: logfile = self.viewer.active_log.logfile try: os.remove(logfile) except OSError as err: notify = NotifyAlert() notify.props.title = _('Error') notify.props.msg = _('%(error)s when deleting %(file)s') % \ {'error': err.strerror, 'file': logfile} notify.connect('response', _notify_response_cb, self) self.add_alert(notify)
def _notify_new_game(self, prompt): ''' Called from New Game button since loading a new game can be slooow!! ''' alert = NotifyAlert(3) alert.props.title = prompt alert.props.msg = _('A new game is loading.') def _notification_alert_response_cb(alert, response_id, self): self.remove_alert(alert) alert.connect('response', _notification_alert_response_cb, self) self.add_alert(alert) alert.show()
def _confirm_save(self): color1 = self.colors[0].upper() color2 = self.colors[1].upper() settings = Gio.Settings("org.sugarlabs.user") settings.set_string("color", "%s,%s" % (color1, color2)) alert = NotifyAlert() alert.props.title = _('Saving colors') alert.props.msg = _( 'A restart is required before your new colors will appear.') alert.connect("response", self._notify_response_cb) self.add_alert(alert) alert.show_all()
def _notify_alert(self, title='', msg='', action=None): def _notification_alert_response_cb(alert, response_id, self, action): self.remove_alert(alert) if action is not None: action() self._restore_cursor() alert = NotifyAlert() alert.props.title = title alert.connect('response', _notification_alert_response_cb, self, action) alert.props.msg = msg self.add_alert(alert) alert.show()
def _confirm_save(self): ''' Called from confirmation alert ''' client.set_string('/desktop/sugar/user/color', '%s,%s' % ( self._game.colors[0], self._game.colors[1])) alert = NotifyAlert() alert.props.title = _('Saving colors') alert.props.msg = _('A restart is required before your new colors ' 'will appear.') def _notification_alert_response_cb(alert, response_id, self): self.remove_alert(alert) alert.connect('response', _notification_alert_response_cb, self) self.add_alert(alert) alert.show()
def _notify_alert(self, title='', msg='', action=None): ''' Notify user when xfer is completed ''' def _notification_alert_response_cb(alert, response_id, self, action): self.remove_alert(alert) if action is not None: action() alert = NotifyAlert() alert.props.title = title alert.connect('response', _notification_alert_response_cb, self, action) alert.props.msg = msg self.add_alert(alert) alert.show()
def _create_image(self, text): fd = open('/tmp/cloud_data.txt', 'w') data = json_dump({ 'repeat': self._repeat_tags, 'layout': self._layout, 'font': self._font_name, 'colors': self._color_scheme }) fd.write(data) fd.close() fd = open('/tmp/cloud_text.txt', 'w') fd.write(text) fd.close() path = os.path.join('/tmp/cloud_large.png') try: subprocess.check_call( [os.path.join(activity.get_bundle_path(), 'wordcloud.py')]) except subprocess.CalledProcessError as e: self.get_window().set_cursor( Gdk.Cursor.new(Gdk.CursorType.LEFT_PTR)) alert = NotifyAlert(5) alert.props.title = _('WordCloud error') logging.error(e) logging.error(e.returncode) if e.returncode == 255: logging.error('STOP WORD ERROR') MESSAGE = _('All of your words are "stop words."' ' Please try adding more words.') else: logging.error('MEMORY ERROR') MESSAGE = _('Oops. There was a problem. Please try again.') alert.props.msg = MESSAGE alert.connect('response', self._remove_alert_cb) self.add_alert(alert) return self.get_window().set_cursor(Gdk.Cursor.new(Gdk.CursorType.LEFT_PTR)) self._show_image(path) dsobject = datastore.create() dsobject.metadata['title'] = _('Word Cloud') dsobject.metadata['icon-color'] = profile.get_color().to_string() dsobject.metadata['mime_type'] = 'image/png' dsobject.set_file_path(path) datastore.write(dsobject) dsobject.destroy()
class _SharedJournalEntry(account.SharedJournalEntry): __gsignals__ = { 'transfer-state-changed': (GObject.SignalFlags.RUN_FIRST, None, ([str])), } def __init__(self, fbaccount): self._account = fbaccount self._alert = None def get_share_menu(self, journal_entry_metadata): menu = _ShareMenu( self._account.facebook, journal_entry_metadata, self._account.get_token_state() == self._account.STATE_VALID) self._connect_transfer_signals(menu) return menu def get_refresh_menu(self): menu = _RefreshMenu( self._account.facebook, self._account.get_token_state() == self._account.STATE_VALID) self._connect_transfer_signals(menu) return menu def _connect_transfer_signals(self, transfer_widget): transfer_widget.connect('transfer-state-changed', self._transfer_state_changed_cb) def _transfer_state_changed_cb(self, widget, state_message): logging.debug('_transfer_state_changed_cb') # First, remove any existing alert if self._alert is None: self._alert = NotifyAlert() self._alert.props.title = ACCOUNT_NAME self._alert.connect('response', self._alert_response_cb) journalwindow.get_journal_window().add_alert(self._alert) self._alert.show() logging.debug(state_message) self._alert.props.msg = state_message def _alert_response_cb(self, alert, response_id): journalwindow.get_journal_window().remove_alert(alert) self._alert = None
def _on_send_button_clicked_cb(self, button): window = self._activity.get_window() old_cursor = window.get_cursor() window.set_cursor(Gdk.Cursor.new(Gdk.CursorType.WATCH)) Gdk.flush() identifier = str(int(time.time())) filename = '%s.zip' % identifier filepath = os.path.join(activity.get_activity_root(), filename) success = True # FIXME: subprocess or thread try: self._collector.write_logs(archive=filepath, logbytes=0) except: success = False self.popdown(True) if not success: title = _('Logs not captured') msg = _('The logs could not be captured.') notify = NotifyAlert() notify.props.title = title notify.props.msg = msg notify.connect('response', _notify_response_cb, self._activity) self._activity.add_alert(notify) jobject = datastore.create() metadata = { 'title': _('log-%s') % filename, 'title_set_by_user': '******', 'suggested_filename': filename, 'mime_type': 'application/zip', } for k, v in metadata.items(): jobject.metadata[k] = v jobject.file_path = filepath datastore.write(jobject) self._last_log = jobject.object_id jobject.destroy() activity.show_object_in_journal(self._last_log) os.remove(filepath) window.set_cursor(old_cursor) Gdk.flush()
def _on_send_button_clicked_cb(self, button): window = self._activity.get_window() old_cursor = window.get_cursor() window.set_cursor(Gdk.Cursor.new(Gdk.CursorType.WATCH)) Gdk.flush() identifier = str(int(time.time())) filename = '%s.zip' % identifier filepath = os.path.join(activity.get_activity_root(), filename) success = True # FIXME: subprocess or thread try: self._collector.write_logs(archive=filepath, logbytes=0) except BaseException: success = False self.popdown(True) if not success: title = _('Logs not captured') msg = _('The logs could not be captured.') notify = NotifyAlert() notify.props.title = title notify.props.msg = msg notify.connect('response', _notify_response_cb, self._activity) self._activity.add_alert(notify) jobject = datastore.create() metadata = { 'title': _('log-%s') % filename, 'title_set_by_user': '******', 'suggested_filename': filename, 'mime_type': 'application/zip', } for k, v in list(metadata.items()): jobject.metadata[k] = v jobject.file_path = filepath datastore.write(jobject) self._last_log = jobject.object_id jobject.destroy() activity.show_object_in_journal(self._last_log) os.remove(filepath) window.set_cursor(old_cursor) Gdk.flush()
def _confirm_save(self): ''' Called from confirmation alert ''' client.set_string( '/desktop/sugar/user/color', '%s,%s' % (self._game.colors[0], self._game.colors[1])) alert = NotifyAlert() alert.props.title = _('Saving colors') alert.props.msg = _( 'A restart is required before your new colors will appear.') def _notification_alert_response_cb(alert, response_id, self): self.remove_alert(alert) alert.connect('response', _notification_alert_response_cb, self) self.add_alert(alert) alert.show()
def _create_image(self, text): fd = open('/tmp/cloud_data.txt', 'w') data = json_dump({'repeat': self._repeat_tags, 'layout': self._layout, 'font': self._font_name, 'colors': self._color_scheme}) fd.write(data) fd.close() fd = open('/tmp/cloud_text.txt', 'w') fd.write(text) fd.close() path = os.path.join('/tmp/cloud_large.png') try: subprocess.check_call( [os.path.join(activity.get_bundle_path(), 'wordcloud.py')]) except subprocess.CalledProcessError as e: self.get_window().set_cursor( Gdk.Cursor.new(Gdk.CursorType.LEFT_PTR)) alert = NotifyAlert(5) alert.props.title = _('WordCloud error') logging.error(e) logging.error(e.returncode) if e.returncode == 255: logging.error('STOP WORD ERROR') MESSAGE = _('All of your words are "stop words."' ' Please try adding more words.') else: logging.error('MEMORY ERROR') MESSAGE = _('Oops. There was a problem. Please try again.') alert.props.msg = MESSAGE alert.connect('response', self._remove_alert_cb) self.add_alert(alert) return self.get_window().set_cursor(Gdk.Cursor.new(Gdk.CursorType.LEFT_PTR)) self._show_image(path) dsobject = datastore.create() dsobject.metadata['title'] = _('Word Cloud') dsobject.metadata['icon-color'] = profile.get_color().to_string() dsobject.metadata['mime_type'] = 'image/png' dsobject.set_file_path(path) datastore.write(dsobject) dsobject.destroy()
def save_to_gconf(self, icon=False, name=False): view_icons = [] favorite_icons = [] favorite_names = [] for button in self._view_buttons: view_icons.append(self._view_icons[button]) favorite_icons.append(self._favorite_icons[button]) if self.favorite_names_enabled: favorite_names.append(self._favorite_names[button]) client = GConf.Client.get_default() SugarExt.gconf_client_set_string_list(client, _FAVORITE_KEY, favorite_icons) SugarExt.gconf_client_set_string_list(client, _VIEW_KEY, view_icons) if self.favorite_names_enabled: SugarExt.gconf_client_set_string_list(client, _FAVORITE_NAME_KEY, favorite_names) if icon: for x in self.activity._alerts: self.activity.remove_alert(x) alert = NotifyAlert(5) alert.props.title = _('Icon') alert.props.msg = _('For see icons, restart sugar is needed.') self.activity.add_alert(alert) alert.connect('response', lambda x, y: self.activity.remove_alert(x)) if name: for x in self.activity._alerts: self.activity.remove_alert(x) alert = NotifyAlert(5) alert.props.title = _('View Name') alert.props.msg = _('For seeing View name changes, ' 'restarting Sugar is required.') self.activity.add_alert(alert) alert.connect('response', lambda x, y: self.activity.remove_alert(x))
def async_copy_activity_tree(): try: shutil.copytree(self._document_path, os.path.join(user_activities_path, new_basename), symlinks=True) customizebundle.generate_bundle(nick, new_basename) if copy_alert: self.get_toplevel().remove_alert(copy_alert) alert = NotifyAlert(10) alert.props.title = _('Duplicated') alert.props.msg = _('The activity has been duplicated') alert.connect('response', self.__alert_response_cb) self.get_toplevel().add_alert(alert) finally: self.__set_busy_cursor(False)
def __copy_to_home_cb(self, menu_item, copy_alert=None): """Make a local copy of the activity bundle in user_activities_path""" user_activities_path = get_user_activities_path() nick = customizebundle.generate_unique_id() new_basename = '%s_copy_of_%s' % ( nick, os.path.basename(self._document_path)) if not os.path.exists(os.path.join(user_activities_path, new_basename)): self.__set_busy_cursor(True) def async_copy_activity_tree(): try: shutil.copytree(self._document_path, os.path.join( user_activities_path, new_basename), symlinks=True) customizebundle.generate_bundle(nick, new_basename) if copy_alert: self.get_toplevel().remove_alert(copy_alert) alert = NotifyAlert(10) alert.props.title = _('Duplicated') alert.props.msg = _('The activity has been duplicated') alert.connect('response', self.__alert_response_cb) self.get_toplevel().add_alert(alert) finally: self.__set_busy_cursor(False) GLib.idle_add(async_copy_activity_tree) else: if copy_alert: self.get_toplevel().remove_alert(copy_alert) self.__set_busy_cursor(False) alert = NotifyAlert(10) alert.props.title = _('Duplicated activity already exists') alert.props.msg = _('Delete your copy before trying to duplicate' ' the activity again') alert.connect('response', self.__alert_response_cb) self.get_toplevel().add_alert(alert)
def __copy_to_home_cb(self, menu_item, copy_alert=None): """Make a local copy of the activity bundle in user_activities_path""" user_activities_path = get_user_activities_path() nick = customizebundle.generate_unique_id() new_basename = '%s_copy_of_%s' % ( nick, os.path.basename(self._document_path)) if not os.path.exists(os.path.join(user_activities_path, new_basename)): self.__set_busy_cursor(True) def async_copy_activity_tree(): try: shutil.copytree(self._document_path, os.path.join( user_activities_path, new_basename), symlinks=True) customizebundle.generate_bundle(nick, new_basename) if copy_alert: self.get_toplevel().remove_alert(copy_alert) alert = NotifyAlert(10) alert.props.title = _('Duplicated') alert.props.msg = _('The activity has been duplicated') alert.connect('response', self.__alert_response_cb) self.get_toplevel().add_alert(alert) finally: self.__set_busy_cursor(False) GLib.idle_add(async_copy_activity_tree) else: if copy_alert: self.get_toplevel().remove_alert(copy_alert) self.__set_busy_cursor(False) alert = NotifyAlert(10) alert.props.title = _('Duplicated activity already exists') alert.props.msg = _('Delete your copy before trying to duplicate' ' the activity again') alert.connect('response', self.__alert_response_cb) self.get_toplevel().add_alert(alert)
def async_copy_activity_tree(): try: shutil.copytree(self._document_path, os.path.join( user_activities_path, new_basename), symlinks=True) customizebundle.generate_bundle(nick, new_basename) if copy_alert: self.get_toplevel().remove_alert(copy_alert) alert = NotifyAlert(10) alert.props.title = _('Duplicated') alert.props.msg = _('The activity has been duplicated') alert.connect('response', self.__alert_response_cb) self.get_toplevel().add_alert(alert) finally: self.__set_busy_cursor(False)
def check_md5sum(self): md5sum = commands.getoutput('md5sum %s' % self.file_path) md5sum = md5sum.split()[0] if md5sum == self.md5sum: alert = NotifyAlert(10) alert.props.title = _('Downloaded') alert.props.msg = _('The extension has been downloaded' ' and installed.') for alert_ in self.activity._alerts: self.activity.remove_alert(alert_) alert.connect('response', lambda x, y: self.activity.remove_alert(x)) self.activity.add_alert(alert) os.chdir(os.path.join(env.get_profile_path())) os.system('tar -xf %s' % self.file_path) window = self.get_window() window.set_cursor(None) GObject.source_remove(self.gobject_id) return True
def open_from_journal(self): chooser = ObjectChooser() result = chooser.run() alert = NotifyAlert(5) if result == Gtk.ResponseType.ACCEPT: jobject = chooser.get_selected_object() if jobject and jobject.file_path: os.chdir(env.get_profile_path()) output = commands.getoutput('tar -xf %s' % jobject.file_path) if 'end' in output or 'error' in output: alert.props.title = _('Error') alert.props.msg = _('Error extracting the extension.') else: alert.props.title = _('Sucess') alert.props.msg = _('The extension has been installed.') else: alert.props.title = _('Error') alert.props.msg = _('Error extracting the extension.') self.add_alert(alert) alert.connect('response', lambda x, y: self.remove_alert(x))
def publish(activity, force=False): if not [i for i in book.custom.index if i['ready']]: alert = NotifyAlert(5) alert.props.title = _('Nothing to publish') alert.props.msg = _('Mark arcticles from "Custom" ' 'panel and try again.') alert.connect('response', __alert_notify_response_cb, activity) activity.add_alert(alert) alert.show() return title = activity.metadata['title'] jobject = datastore.find({ 'activity_id': activity.get_id(), 'activity': book.custom.uid })[0] or None logger.debug('publish: title=%s jobject=%s force=%s' \ % (title, jobject and jobject[0].metadata['activity'], force)) if jobject: if force: jobject = jobject[0] else: alert = ConfirmationAlert() alert.props.title = _('Overwrite existed bundle?') alert.props.msg = _( 'A bundle for current object was already created. ' 'Click "OK" to overwrite it.') alert.connect('response', __alert_response_cb, activity, True) activity.add_alert(alert) alert.show() jobject[0].destroy() return else: jobject = datastore.create() jobject.metadata['activity_id'] = activity.get_id() jobject.metadata['activity'] = book.custom.uid jobject.metadata['mime_type'] = 'application/vnd.olpc-content' jobject.metadata['description'] = \ 'This is a bundle containing articles on %s.\n' \ 'To view these articles, open the \'Browse\' Activity.\n' \ 'Go to \'Books\', and select \'%s\'.' % (title, title) book.custom.sync_article() book.custom.revision += 1 jobject.metadata['title'] = title _publish(title, jobject) jobject.destroy() book.custom.sync_index() alert = NotifyAlert() alert.props.title = _('Book published to your Journal') alert.props.msg = _('You can read the book in Browse or ' 'access the .xol file from your Journal') alert.connect('response', __alert_notify_response_cb, activity) activity.add_alert(alert) alert.show()
def publish(activity, force=False): if not [i for i in book.custom.index if i['ready']]: alert = NotifyAlert(5) alert.props.title = _('Nothing to publish') alert.props.msg = _('Mark arcticles from "Custom" ' 'panel and try again.') alert.connect('response', __alert_notify_response_cb, activity) activity.add_alert(alert) alert.show() return title = activity.metadata['title'] jobject = datastore.find({ 'activity_id': activity.get_id(), 'activity' : book.custom.uid})[0] or None logger.debug('publish: title=%s jobject=%s force=%s' \ % (title, jobject and jobject[0].metadata['activity'], force)) if jobject: if force: jobject = jobject[0] else: alert = ConfirmationAlert() alert.props.title = _('Overwrite existed bundle?') alert.props.msg = _('A bundle for current object was already created. ' 'Click "OK" to overwrite it.') alert.connect('response', __alert_response_cb, activity, True) activity.add_alert(alert) alert.show() jobject[0].destroy() return else: jobject = datastore.create() jobject.metadata['activity_id'] = activity.get_id() jobject.metadata['activity'] = book.custom.uid jobject.metadata['mime_type'] = 'application/vnd.olpc-content' jobject.metadata['description'] = \ 'This is a bundle containing articles on %s.\n' \ 'To view these articles, open the \'Browse\' Activity.\n' \ 'Go to \'Books\', and select \'%s\'.' % (title, title) book.custom.sync_article() book.custom.revision += 1 jobject.metadata['title'] = title _publish(title, jobject) jobject.destroy() book.custom.sync_index() alert = NotifyAlert() alert.props.title = _('Book published to your Journal') alert.props.msg = _('You can read the book in Browse or ' 'access the .xol file from your Journal') alert.connect('response', __alert_notify_response_cb, activity) activity.add_alert(alert) alert.show()
def _save_ogg_eos_cb(self, bus, message, pipe): bus.remove_signal_watch() pipe.set_state(Gst.State.NULL) title = '%s saved as audio' % self.metadata['title'] jobject = datastore.create() jobject.metadata['title'] = title jobject.metadata['keep'] = '0' jobject.metadata['mime_type'] = 'audio/ogg' jobject.file_path = self._ogg_tempfile.name datastore.write(jobject) self._wav_tempfile.close() self._ogg_tempfile.close() alert = NotifyAlert(10) alert.props.title = _('Audio recorded') alert.props.msg = _('The audio file was saved in the Journal') alert.connect('response', self.__alert_response_cb) self.add_alert(alert) return False
def _save_ogg_eos_cb(self, bus, message, pipe): bus.remove_signal_watch() pipe.set_state(Gst.State.NULL) title = '%s saved as audio' % self.metadata['title'] jobject = datastore.create() jobject.metadata['title'] = title jobject.metadata['keep'] = '0' jobject.metadata['mime_type'] = 'audio/ogg' jobject.file_path = self._ogg_tempfile.name datastore.write(jobject) self._wav_tempfile.close() self._ogg_tempfile.close() alert = NotifyAlert(10) alert.props.title = _('Audio recorded') alert.props.msg = _('The audio file was saved in the Journal') alert.connect('response', self.__alert_response_cb) self.add_alert(alert) return False
class _SharedJournalEntry(account.SharedJournalEntry): __gsignals__ = { 'transfer-state-changed': (GObject.SignalFlags.RUN_FIRST, None, ([str])), } def __init__(self, webaccount): self._account = webaccount self._alert = None def get_share_menu(self, get_uid_list): menu = _ShareMenu(self._account, get_uid_list, True) self._connect_transfer_signals(menu) logging.debug('url cache: %s' % (self._account.url_cache)) return menu def get_refresh_menu(self): menu = _RefreshMenu(self._account, False) self._connect_transfer_signals(menu) return menu def _connect_transfer_signals(self, transfer_widget): transfer_widget.connect('transfer-state-changed', self.__display_alert_cb) def __display_alert_cb(self, widget, message): if self._alert is None: self._alert = NotifyAlert() self._alert.props.title = ACCOUNT_NAME self._alert.connect('response', self.__alert_response_cb) journalwindow.get_journal_window().add_alert(self._alert) self._alert.show() self._alert.props.msg = message def __alert_response_cb(self, alert, response_id): journalwindow.get_journal_window().remove_alert(alert) self._alert = None
def check_image_qr(self, path): myCode = QR(filename=path) if myCode.decode(): self.qr_link = myCode.data_to_string() self.copy_link.set_sensitive(True) alert = NotifyAlert(10) alert.props.title = _("Code found") alert.props.msg = _("Click on toolbar button for " "copy link to clipboard.") alert.connect("response", lambda x, y: self.activity.remove_alert(x)) self.activity.add_alert(alert) else: self.qr_link = None self.copy_link.set_sensitive(False) alert = NotifyAlert(10) alert.props.title = _("Code not found") alert.props.msg = _("Try again, please focus the Qr " "Code in the camera.") alert.connect("response", lambda x, y: self.activity.remove_alert(x)) self.activity.add_alert(alert) self.stop_play.set_sensitive(False)
def check_image_qr(self, path): myCode = QR(filename=path) if myCode.decode(): self.qr_link = myCode.data_to_string() self.copy_link.set_sensitive(True) alert = NotifyAlert(10) alert.props.title = _("Code found") alert.props.msg = _("Click on toolbar button for " "copy link to clipboard.") alert.connect("response", lambda x, y: self.activity.remove_alert(x)) self.activity.add_alert(alert) else: self.qr_link = None self.copy_link.set_sensitive(False) alert = NotifyAlert(10) alert.props.title = _("Code not found") alert.props.msg = _("Try again, please focus the Qr " "Code in the camera.") alert.connect("response", lambda x, y: self.activity.remove_alert(x)) self.activity.add_alert(alert) self.stop_play.set_sensitive(False)
class Account(account.Account): def __init__(self): self.upload = accountsmanager.get_service('sugargdrive') self._shared_journal_entry = None self._journal = None self._model = None self._alert = None self._listview = None self._volume_button = None def get_description(self): return ACCOUNT_DESCRIPTION def add_journal_button(self): if not self._journal: palette = ExtensionPalette() self._journal = get_journal() self._listview = self._journal.get_list_view() self._volumes_toolbar = self._journal.get_volumes_toolbar() self._volume_button = ExtensionButton(ACCOUNT_ICON, ICONS_PATH) self._volume_button.connect('toggled', self._journal_toggled) self._volume_button.connect('load-files', self._load_files) self._volume_button.connect('data-upload', self._upload_file) self._volumes_toolbar.add_extension_button(self._volume_button, ACCOUNT_NAME, palette) palette.set_item_cb(self.update_files) def get_token_state(self): return self.STATE_VALID def get_shared_journal_entry(self): if self._shared_journal_entry is None: self._shared_journal_entry = _SharedJournalEntry(self) return self._shared_journal_entry def _journal_toggled(self, widget): self._journal.get_window().set_cursor(None) option = widget.props.active if option: new_option = False else: new_option = True self._listview.use_options(new_option) def _load_files(self, *kwargs): if not self._model: journal_button = self._volumes_toolbar._volume_buttons[0] self._model = FilesModel(self.upload, self._display_alert_cb, self._load_files, journal_button, self._listview) self._model.clear() self._listview.tree_view.set_model(self._model) def internal_callback(): files = [] if os.path.exists(USER_FILES): f = open(USER_FILES, 'r') try: data = json.load(f) except: files = [] os.remove(USER_FILES) self._journal.get_window().set_cursor(None) f.close() data = [] isdict = False if isinstance(data, dict): isdict = True if isdict: data = data['items'] for userfile in data: txt = '<span weight="bold">%s</span>' % ( GLib.markup_escape_text(userfile['title'])) icon_name = _get_icon_for_mime(userfile['mimeType']) link = userfile['alternateLink'] itter = self._model.insert(-1, [ '', False, icon_name, profile.get_color(), txt, '', '', 50, profile.get_color(), profile.get_color(), profile.get_color(), True, link, userfile['mimeType'], userfile['id'], userfile['title']]) files.append(itter) if len(files) == 0 or not os.path.exists(USER_FILES): self._listview._show_message(_('No files in your ' 'account, please update your file list ' 'clicking in the toolbar menu option.'), icon_name=ACCOUNT_ICON) else: self._listview._clear_message() self._journal.get_window().set_cursor(None) self._listview._show_message(_('Loading files...'), icon_name=ACCOUNT_ICON) cursor = Gdk.Cursor.new(Gdk.CursorType.WATCH) self._journal.get_window().set_cursor(cursor) GObject.idle_add(internal_callback) def _upload_file(self, widget, metadata): account = self._shared_journal_entry._menu account.connect('transfer-state-changed', self._display_alert_cb) account.upload_file(None, metadata) def _display_alert_cb(self, widget, title, message): if self._alert is None: self._alert = NotifyAlert() self._alert.connect('response', self.__alert_response_cb) journalwindow.get_journal_window().add_alert(self._alert) self._alert.show() self._alert.props.title = title self._alert.props.msg = message def __alert_response_cb(self, alert, response_id): journalwindow.get_journal_window().remove_alert(alert) self._alert = None def update_files(self, widget): self._listview._show_message(_('Updating file list...'), icon_name=ACCOUNT_ICON) cursor = Gdk.Cursor.new(Gdk.CursorType.WATCH) self._journal.get_window().set_cursor(cursor) if not self._volume_button.props.active: self._volume_button.set_active(True) self._journal_toggled(self._volume_button) def internal_callback(): inst = self.upload.Upload() inst.update_files(self._display_alert_cb, self._load_files) self._listview._clear_message() self._journal.get_window().set_cursor(None) GObject.idle_add(internal_callback)
class TwitterAccount(account.Account): CONSUMER_TOKEN_KEY = "/desktop/sugar/collaboration/twitter_consumer_token" CONSUMER_SECRET_KEY = "/desktop/sugar/collaboration/twitter_consumer_secret" ACCESS_TOKEN_KEY = "/desktop/sugar/collaboration/twitter_access_token" ACCESS_SECRET_KEY = "/desktop/sugar/collaboration/twitter_access_secret" def __init__(self): self._client = GConf.Client.get_default() ctoken, csecret, atoken, asecret = self._access_tokens() TwrAccount.set_secrets(ctoken, csecret, atoken, asecret) self._alert = None def get_description(self): return ACCOUNT_NAME def is_configured(self): return None not in self._access_tokens() def is_active(self): # No expiration date return None not in self._access_tokens() def get_share_menu(self, journal_entry_metadata): twr_share_menu = _TwitterShareMenu(journal_entry_metadata, self.is_active()) self._connect_transfer_signals(twr_share_menu) return twr_share_menu def get_refresh_menu(self): twr_refresh_menu = _TwitterRefreshMenu(self.is_active()) self._connect_transfer_signals(twr_refresh_menu) return twr_refresh_menu def _connect_transfer_signals(self, transfer_widget): transfer_widget.connect('transfer-state-changed', self._transfer_state_changed_cb) def _transfer_state_changed_cb(self, widget, state_message): logging.debug('_transfer_state_changed_cb') # First, remove any existing alert if self._alert is None: self._alert = NotifyAlert() self._alert.props.title = ACCOUNT_NAME self._alert.connect('response', self._alert_response_cb) journalwindow.get_journal_window().add_alert(self._alert) self._alert.show() logging.debug(state_message) self._alert.props.msg = state_message def _alert_response_cb(self, alert, response_id): journalwindow.get_journal_window().remove_alert(alert) self._alert = None def _access_tokens(self): return (self._client.get_string(self.CONSUMER_TOKEN_KEY), self._client.get_string(self.CONSUMER_SECRET_KEY), self._client.get_string(self.ACCESS_TOKEN_KEY), self._client.get_string(self.ACCESS_SECRET_KEY))
class FractionBounceActivity(activity.Activity): def __init__(self, handle): ''' Initiate activity. ''' super(FractionBounceActivity, self).__init__(handle) self.nick = profile.get_nick_name() if profile.get_color() is not None: self._colors = profile.get_color().to_string().split(',') else: self._colors = ['#A0FFA0', '#FF8080'] self.max_participants = 4 # sharing self._playing = True self._setup_toolbars() self._setup_dispatch_table() canvas = self._setup_canvas() # Read any custom fractions from the project metadata if 'custom' in self.metadata: custom = self.metadata['custom'] else: custom = None self._current_ball = 'soccerball' self._toolbar_was_expanded = False # Initialize the canvas self._bounce_window = Bounce(canvas, activity.get_bundle_path(), self) Gdk.Screen.get_default().connect('size-changed', self._configure_cb) # Restore any custom fractions if custom is not None: fractions = custom.split(',') for f in fractions: self._bounce_window.add_fraction(f) if self.shared_activity: # We're joining if not self.get_shared(): xocolors = XoColor(profile.get_color().to_string()) share_icon = Icon(icon_name='zoom-neighborhood', xo_color=xocolors) self._joined_alert = NotifyAlert() self._joined_alert.props.icon = share_icon self._joined_alert.props.title = _('Please wait') self._joined_alert.props.msg = _('Starting connection...') self._joined_alert.connect('response', self._alert_cancel_cb) self.add_alert(self._joined_alert) self._label.set_label(_('Wait for the sharer to start.')) # Wait for joined signal self.connect("joined", self._joined_cb) self._setup_sharing() def _configure_cb(self, event): if Gdk.Screen.width() < 1024: self._label.set_size_request(275, -1) self._label.set_label('') self._separator.set_expand(False) else: self._label.set_size_request(500, -1) self._separator.set_expand(True) self._bounce_window.configure_cb(event) if self._toolbar_expanded(): self._bounce_window.bar.bump_bars('up') self._bounce_window.ball.ball.move_relative( (0, -style.GRID_CELL_SIZE)) def _toolbar_expanded(self): if self._activity_button.is_expanded(): return True elif self._custom_toolbar_button.is_expanded(): return True return False def _update_graphics(self, widget): # We need to catch opening and closing of toolbars and ignore # switching between open toolbars. if self._toolbar_expanded(): if not self._toolbar_was_expanded: self._bounce_window.bar.bump_bars('up') self._bounce_window.ball.ball.move_relative( (0, -style.GRID_CELL_SIZE)) self._toolbar_was_expanded = True else: if self._toolbar_was_expanded: self._bounce_window.bar.bump_bars('down') self._bounce_window.ball.ball.move_relative( (0, style.GRID_CELL_SIZE)) self._toolbar_was_expanded = False def _setup_toolbars(self): custom_toolbar = Gtk.Toolbar() toolbox = ToolbarBox() self._toolbar = toolbox.toolbar self._activity_button = ActivityToolbarButton(self) self._activity_button.connect('clicked', self._update_graphics) self._toolbar.insert(self._activity_button, 0) self._activity_button.show() self._custom_toolbar_button = ToolbarButton( label=_('Custom'), page=custom_toolbar, icon_name='view-source') self._custom_toolbar_button.connect('clicked', self._update_graphics) custom_toolbar.show() self._toolbar.insert(self._custom_toolbar_button, -1) self._custom_toolbar_button.show() self._load_standard_buttons(self._toolbar) self._separator = Gtk.SeparatorToolItem() self._separator.props.draw = False self._separator.set_expand(True) self._toolbar.insert(self._separator, -1) self._separator.show() stop_button = StopButton(self) stop_button.props.accelerator = _('<Ctrl>Q') self._toolbar.insert(stop_button, -1) stop_button.show() self.set_toolbar_box(toolbox) toolbox.show() self._load_custom_buttons(custom_toolbar) def _load_standard_buttons(self, toolbar): fraction_button = RadioToolButton(group=None) fraction_button.set_icon_name('fraction') fraction_button.set_tooltip(_('fractions')) fraction_button.connect('clicked', self._fraction_cb) toolbar.insert(fraction_button, -1) fraction_button.show() sector_button = RadioToolButton(group=fraction_button) sector_button.set_icon_name('sector') sector_button.set_tooltip(_('sectors')) sector_button.connect('clicked', self._sector_cb) toolbar.insert(sector_button, -1) sector_button.show() percent_button = RadioToolButton(group=fraction_button) percent_button.set_icon_name('percent') percent_button.set_tooltip(_('percents')) percent_button.connect('clicked', self._percent_cb) toolbar.insert(percent_button, -1) percent_button.show() self._player = Gtk.Image() self._player.set_from_pixbuf(svg_str_to_pixbuf( generate_xo_svg(scale=0.8, colors=['#282828', '#282828']))) self._player.set_tooltip_text(self.nick) toolitem = Gtk.ToolItem() toolitem.add(self._player) self._player.show() toolbar.insert(toolitem, -1) toolitem.show() self._label = Gtk.Label(_("Click the ball to start.")) self._label.set_line_wrap(True) if Gdk.Screen.width() < 1024: self._label.set_size_request(275, -1) else: self._label.set_size_request(500, -1) self.toolitem = Gtk.ToolItem() self.toolitem.add(self._label) self._label.show() toolbar.insert(self.toolitem, -1) self.toolitem.show() def _load_custom_buttons(self, toolbar): self.numerator = Gtk.Entry() self.numerator.set_text('') self.numerator.set_tooltip_text(_('numerator')) self.numerator.set_width_chars(3) toolitem = Gtk.ToolItem() toolitem.add(self.numerator) self.numerator.show() toolbar.insert(toolitem, -1) toolitem.show() label = Gtk.Label(' / ') toolitem = Gtk.ToolItem() toolitem.add(label) label.show() toolbar.insert(toolitem, -1) toolitem.show() self.denominator = Gtk.Entry() self.denominator.set_text('') self.denominator.set_tooltip_text(_('denominator')) self.denominator.set_width_chars(3) toolitem = Gtk.ToolItem() toolitem.add(self.denominator) self.denominator.show() toolbar.insert(toolitem, -1) toolitem.show() button = ToolButton('list-add') button.set_tooltip(_('add new fraction')) button.props.sensitive = True button.props.accelerator = 'Return' button.connect('clicked', self._add_fraction_cb) toolbar.insert(button, -1) button.show() separator = Gtk.SeparatorToolItem() separator.props.draw = False separator.set_expand(False) toolbar.insert(separator, -1) separator.show() button = ToolButton('soccerball') button.set_tooltip(_('choose a ball')) button.props.sensitive = True button.connect('clicked', self._button_palette_cb) toolbar.insert(button, -1) button.show() self._ball_palette = button.get_palette() button_grid = Gtk.Grid() row = 0 for ball in BALLDICT.keys(): if ball == 'custom': button = ToolButton('view-source') else: button = ToolButton(ball) button.connect('clicked', self._load_ball_cb, None, ball) eventbox = Gtk.EventBox() eventbox.connect('button_press_event', self._load_ball_cb, ball) label = Gtk.Label(BALLDICT[ball][0]) eventbox.add(label) label.show() button_grid.attach(button, 0, row, 1, 1) button.show() button_grid.attach(eventbox, 1, row, 1, 1) eventbox.show() row += 1 self._ball_palette.set_content(button_grid) button_grid.show() button = ToolButton('insert-picture') button.set_tooltip(_('choose a background')) button.props.sensitive = True button.connect('clicked', self._button_palette_cb) toolbar.insert(button, -1) button.show() self._bg_palette = button.get_palette() button_grid = Gtk.Grid() row = 0 for bg in BGDICT.keys(): if bg == 'custom': button = ToolButton('view-source') else: button = ToolButton(bg) button.connect('clicked', self._load_bg_cb, None, bg) eventbox = Gtk.EventBox() eventbox.connect('button_press_event', self._load_bg_cb, bg) label = Gtk.Label(BGDICT[bg][0]) eventbox.add(label) label.show() button_grid.attach(button, 0, row, 1, 1) button.show() button_grid.attach(eventbox, 1, row, 1, 1) eventbox.show() row += 1 self._bg_palette.set_content(button_grid) button_grid.show() def _button_palette_cb(self, button): palette = button.get_palette() if palette: if not palette.is_up(): palette.popup(immediate=True, state=palette.SECONDARY) else: palette.popdown(immediate=True) def can_close(self): # Let everyone know we are leaving... if hasattr(self, '_bounce_window') and \ self._bounce_window.we_are_sharing(): self._playing = False self.send_event('l', {"data": (json_dump([self.nick]))}) return True def _setup_canvas(self): canvas = Gtk.DrawingArea() canvas.set_size_request(Gdk.Screen.width(), Gdk.Screen.height()) self.set_canvas(canvas) canvas.show() return canvas def _load_bg_cb(self, widget, event, bg): if bg == 'custom': chooser(self, 'Image', self._new_background_from_journal) else: self._bounce_window.set_background(BGDICT[bg][1]) def _load_ball_cb(self, widget, event, ball): if ball == 'custom': chooser(self, 'Image', self._new_ball_from_journal) else: self._bounce_window.ball.new_ball(os.path.join( activity.get_bundle_path(), 'images', ball + '.svg')) self._bounce_window.set_background(BGDICT[BALLDICT[ball][1]][1]) self._current_ball = ball def _reset_ball(self): ''' If we switch back from sector mode, we need to restore the ball ''' if self._bounce_window.mode != 'sectors': return if self._current_ball == 'custom': # TODO: Reload custom ball self._current_ball = 'soccerball' self._bounce_window.ball.new_ball(os.path.join( activity.get_bundle_path(), 'images', self._current_ball + '.svg')) def _new_ball_from_journal(self, dsobject): ''' Load an image from the Journal. ''' self._bounce_window.ball.new_ball_from_image( dsobject.file_path, os.path.join(activity.get_activity_root(), 'tmp', 'custom.png')) def _new_background_from_journal(self, dsobject): ''' Load an image from the Journal. ''' self._bounce_window.new_background_from_image(None, dsobject=dsobject) def _fraction_cb(self, arg=None): ''' Set fraction mode ''' self._reset_ball() self._bounce_window.mode = 'fractions' def _percent_cb(self, arg=None): ''' Set percent mode ''' self._reset_ball() self._bounce_window.mode = 'percents' def _sector_cb(self, arg=None): ''' Set sector mode ''' self._bounce_window.mode = 'sectors' def _add_fraction_cb(self, arg=None): ''' Read entries and add a fraction to the list ''' try: numerator = int(self.numerator.get_text().strip()) except ValueError: self.numerator.set_text('NAN') numerator = 0 try: denominator = int(self.denominator.get_text().strip()) except ValueError: self.denominator.set_text('NAN') denominator = 1 if denominator == 0: self.denominator.set_text('ZDE') if numerator > denominator: numerator = 0 if numerator > 0 and denominator > 1: fraction = '%d/%d' % (numerator, denominator) self._bounce_window.add_fraction(fraction) if 'custom' in self.metadata: # Save to Journal self.metadata['custom'] = '%s,%s' % ( self.metadata['custom'], fraction) else: self.metadata['custom'] = fraction self.alert( _('New fraction'), _('Your fraction, %s, has been added to the program' % (fraction))) def reset_label(self, label): ''' update the challenge label ''' self._label.set_label(label) def alert(self, title, text=None): alert = NotifyAlert(timeout=5) alert.props.title = title alert.props.msg = text self.add_alert(alert) alert.connect('response', self._alert_cancel_cb) alert.show() def _alert_cancel_cb(self, alert, response_id): self.remove_alert(alert) # Collaboration-related methods def _setup_sharing(self): ''' Setup the Presence Service. ''' self.pservice = presenceservice.get_instance() self.initiating = None # sharing (True) or joining (False) owner = self.pservice.get_owner() self.owner = owner self._bounce_window.buddies.append(self.nick) self._player_colors = [self._colors] self._player_pixbufs = [ svg_str_to_pixbuf(generate_xo_svg(scale=0.8, colors=self._colors)) ] self._share = '' self.connect('shared', self._shared_cb) self.connect('joined', self._joined_cb) def _shared_cb(self, activity): ''' Either set up initial share...''' self._new_tube_common(True) def _joined_cb(self, activity): ''' ...or join an exisiting share. ''' self._new_tube_common(False) def _new_tube_common(self, sharer): ''' Joining and sharing are mostly the same... ''' if self.shared_activity is None: _logger.debug('Error: Failed to share or join activity ... \ shared_activity is null in _shared_cb()') return self.initiating = sharer self.waiting_for_fraction = not sharer self.conn = self.shared_activity.telepathy_conn self.tubes_chan = self.shared_activity.telepathy_tubes_chan self.text_chan = self.shared_activity.telepathy_text_chan self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES].connect_to_signal( 'NewTube', self._new_tube_cb) if sharer: _logger.debug('This is my activity: making a tube...') id = self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES].OfferDBusTube( SERVICE, {}) self._label.set_label(_('Wait for others to join.')) else: _logger.debug('I am joining an activity: waiting for a tube...') self.tubes_chan[telepathy.CHANNEL_TYPE_TUBES].ListTubes( reply_handler=self._list_tubes_reply_cb, error_handler=self._list_tubes_error_cb) # display your XO on the toolbar self._player.set_from_pixbuf(self._player_pixbufs[0]) def _list_tubes_reply_cb(self, tubes): ''' Reply to a list request. ''' for tube_info in tubes: self._new_tube_cb(*tube_info) def _list_tubes_error_cb(self, e): ''' Log errors. ''' _logger.debug('Error: ListTubes() failed: %s', e) def _new_tube_cb(self, id, initiator, type, service, params, state): ''' Create a new tube. ''' _logger.debug( 'Newtube: ID=%d initator=%d type=%d service=%s params=%r state=%d', id, initiator, type, service, params, state) if (type == telepathy.TUBE_TYPE_DBUS and service == SERVICE): if state == telepathy.TUBE_STATE_LOCAL_PENDING: self.tubes_chan[ \ telepathy.CHANNEL_TYPE_TUBES].AcceptDBusTube(id) self.collab = CollabWrapper(self) self.collab.message.connect(self.event_received_cb) self.collab.setup() # Let the sharer know a new joiner has arrived. if self.waiting_for_fraction: self.send_event('j', {"data": (json_dump([self.nick, self._colors]))}) def _setup_dispatch_table(self): self._processing_methods = { 'j': [self._new_joiner, 'new joiner'], 'b': [self._buddy_list, 'buddy list'], 'f': [self._receive_a_fraction, 'receive a fraction'], 't': [self._take_a_turn, 'take a turn'], 'l': [self._buddy_left, 'buddy left'] } def event_received_cb(self, event_message): ''' Data from a tube has arrived. ''' if len(event_message) == 0: return try: command, payload = event_message.split('|', 2) except ValueError: _logger.debug('Could not split event message %s', event_message) return _logger.debug('received an event %s|%s', command, payload) if self._playing: self._processing_methods[command][0](payload) def _buddy_left(self, payload): [nick] = json_load(payload) self._label.set_label(nick + ' ' + _('has left.')) if self.initiating: self._remove_player(nick) payload = json_dump([self._bounce_window.buddies, self._player_colors]) self.send_event('b', {"data": payload}) # Restart from sharer's turn self._bounce_window.its_my_turn() def _new_joiner(self, payload): ''' Someone has joined; sharer adds them to the buddy list. ''' [nick, colors] = json_load(payload) self._label.set_label(nick + ' ' + _('has joined.')) if self.initiating: self._append_player(nick, colors) payload = json_dump([self._bounce_window.buddies, self._player_colors]) self.send_event('b', {"data": payload}) if self._bounce_window.count == 0: # Haven't started yet... self._bounce_window.its_my_turn() def _remove_player(self, nick): if nick in self._bounce_window.buddies: i = self._bounce_window.buddies.index(nick) self._bounce_window.buddies.remove(nick) self._player_colors.remove(self._player_colors[i]) self._player_pixbufs.remove(self._player_pixbufs[i]) def _append_player(self, nick, colors): ''' Keep a list of players, their colors, and an XO pixbuf ''' if not nick in self._bounce_window.buddies: _logger.debug('appending %s to the buddy list', nick) self._bounce_window.buddies.append(nick) self._player_colors.append([str(colors[0]), str(colors[1])]) self._player_pixbufs.append(svg_str_to_pixbuf( generate_xo_svg(scale=0.8, colors=self._player_colors[-1]))) def _buddy_list(self, payload): '''Sharer sent the updated buddy list, so regenerate internal lists''' if not self.initiating: [buddies, colors] = json_load(payload) self._bounce_window.buddies = buddies[:] self._player_colors = colors[:] self._player_pixbufs = [] for colors in self._player_colors: self._player_pixbufs.append(svg_str_to_pixbuf( generate_xo_svg(scale=0.8, colors=[str(colors[0]), str(colors[1])]))) def send_a_fraction(self, fraction): ''' Send a fraction to other players. ''' payload = json_dump(fraction) self.send_event('f', {"data": payload}) def _receive_a_fraction(self, payload): ''' Receive a fraction from another player. ''' fraction = json_load(payload) self._bounce_window.play_a_fraction(fraction) def _take_a_turn(self, nick): ''' If it is your turn, take it, otherwise, wait. ''' if nick == self.nick: self._bounce_window.its_my_turn() else: self._bounce_window.its_their_turn(nick) def send_event(self, command, data): ''' Send event through the tube. ''' _logger.debug('sending event: %s', command) if hasattr(self, 'collab') and self.collab is not None: data["command"] = command self.collab.post(data) def set_player_on_toolbar(self, nick): ''' Display the XO icon of the player whose turn it is. ''' self._player.set_from_pixbuf(self._player_pixbufs[ self._bounce_window.buddies.index(nick)]) self._player.set_tooltip_text(nick)
class MazeActivity(activity.Activity): def __init__(self, handle): """Set up the Maze activity.""" activity.Activity.__init__(self, handle) self._busy_count = 0 self._unbusy_idle_sid = None self.build_toolbar() self.pservice = PresenceService() self.owner = self.pservice.get_owner() state = None if 'state' in self.metadata: state = json.loads(self.metadata['state']) self.game = game.MazeGame(self, self.owner, state) self.set_canvas(self.game) self.game.show() self.connect("key_press_event", self.game.key_press_cb) self.text_channel = None self.my_key = profile.get_pubkey() self._alert = None if self.shared_activity: # we are joining the activity self._add_alert(_('Joining a maze'), _('Connecting...')) self.connect('joined', self._joined_cb) if self.get_shared(): # we have already joined self._joined_cb() else: # we are creating the activity self.connect('shared', self._shared_cb) def busy(self): if self._busy_count == 0: if self._unbusy_idle_sid is not None: GLib.source_remove(self._unbusy_idle_sid) self._unbusy_idle_sid = None self._old_cursor = self.get_window().get_cursor() self._set_cursor(Gdk.Cursor.new(Gdk.CursorType.WATCH)) self._busy_count += 1 def unbusy(self): self._unbusy_idle_sid = GLib.idle_add(self._unbusy_idle_cb) def _unbusy_idle_cb(self): self._unbusy_idle_sid = None self._busy_count -= 1 if self._busy_count == 0: self._set_cursor(self._old_cursor) def _set_cursor(self, cursor): self.get_window().set_cursor(cursor) Gdk.flush() def build_toolbar(self): """Build our Activity toolbar for the Sugar system.""" toolbar_box = ToolbarBox() activity_button = ActivityToolbarButton(self) toolbar_box.toolbar.insert(activity_button, 0) activity_button.show() separator = Gtk.SeparatorToolItem() toolbar_box.toolbar.insert(separator, -1) separator.show() easier_button = ToolButton('create-easier') easier_button.set_tooltip(_('Easier level')) easier_button.connect('clicked', self._easier_button_cb) toolbar_box.toolbar.insert(easier_button, -1) harder_button = ToolButton('create-harder') harder_button.set_tooltip(_('Harder level')) harder_button.connect('clicked', self._harder_button_cb) toolbar_box.toolbar.insert(harder_button, -1) separator = Gtk.SeparatorToolItem() toolbar_box.toolbar.insert(separator, -1) separator.show() self.show_trail_button = ToggleToolButton('show-trail') self.show_trail_button.set_tooltip(_('Show trail')) self.show_trail_button.set_active(True) self.show_trail_button.connect('toggled', self._toggled_show_trail_cb) toolbar_box.toolbar.insert(self.show_trail_button, -1) separator = Gtk.SeparatorToolItem() separator.props.draw = False separator.set_size_request(0, -1) separator.set_expand(True) toolbar_box.toolbar.insert(separator, -1) separator.show() stop_button = StopButton(self) toolbar_box.toolbar.insert(stop_button, -1) stop_button.show() self.set_toolbar_box(toolbar_box) toolbar_box.show_all() return toolbar_box def _easier_button_cb(self, button): self.game.easier() def _harder_button_cb(self, button): self.game.harder() def _toggled_show_trail_cb(self, button): if self.game.set_show_trail(button.get_active()): self.broadcast_msg('show_trail:%s' % str(button.get_active())) def _shared_cb(self, activity): logging.debug('Maze was shared') self._add_alert(_('Sharing'), _('This maze is shared.')) self._setup() def _joined_cb(self, activity): """Joined a shared activity.""" if not self.shared_activity: return logging.debug('Joined a shared chat') for buddy in self.shared_activity.get_joined_buddies(): self._buddy_already_exists(buddy) self._setup() # request maze data self.broadcast_msg('req_maze') def _setup(self): self.text_channel = TextChannelWrapper( self.shared_activity.telepathy_text_chan, self.shared_activity.telepathy_conn, self.pservice) self.text_channel.set_received_callback(self._received_cb) self.shared_activity.connect('buddy-joined', self._buddy_joined_cb) self.shared_activity.connect('buddy-left', self._buddy_left_cb) def _received_cb(self, buddy, text): if buddy == self.owner: return self.game.msg_received(buddy, text) def _add_alert(self, title, text=None): self.grab_focus() self._alert = ErrorAlert() self._alert.props.title = title self._alert.props.msg = text self.add_alert(self._alert) self._alert.connect('response', self._alert_cancel_cb) self._alert.show() def _alert_cancel_cb(self, alert, response_id): self.remove_alert(alert) self._alert = None def update_alert(self, title, text=None): if self._alert is not None: self._alert.props.title = title self._alert.props.msg = text def show_accelerator_alert(self): self.grab_focus() self._alert = NotifyAlert() self._alert.props.title = _('Tablet mode detected.') self._alert.props.msg = _('Hold your XO flat and tilt to play!') self.add_alert(self._alert) self._alert.connect('response', self._alert_cancel_cb) self._alert.show() def _buddy_joined_cb(self, activity, buddy): """Show a buddy who joined""" logging.debug('buddy joined') if buddy == self.owner: logging.debug('its me, exit!') return self.game.buddy_joined(buddy) def _buddy_left_cb(self, activity, buddy): self.game.buddy_left(buddy) def _buddy_already_exists(self, buddy): """Show a buddy already in the chat.""" if buddy == self.owner: return self.game.buddy_joined(buddy) def broadcast_msg(self, message): if self.text_channel: # FIXME: can't identify the sender at the other end, # add the pubkey to the text message self.text_channel.send('%s|%s' % (self.my_key, message)) def write_file(self, file_path): logging.debug('Saving the state of the game...') data = {'seed': self.game.maze.seed, 'width': self.game.maze.width, 'height': self.game.maze.height, 'finish_time': self.game.finish_time} logging.debug('Saving data: %s', data) self.metadata['state'] = json.dumps(data) def can_close(self): self.game.close_finish_window() return True def read_file(self, file_path): pass
def _create_custom_food_cb(self, button): def _notification_alert_response_cb(alert, response_id, self): self.remove_alert(alert) name = self.name_entry.get_text() try: calories = int(self.calories_entry.get_text()) except: _logger.debug(self.calories_entry.get_text) calories = None pyramid = self.food_spinner.get_active() if name == '' or name == _('food name'): alert = NotifyAlert() alert.props.title = _('Add a new food item.') alert.connect('response', _notification_alert_response_cb, self) alert.props.msg = _('You must enter a name for the new food item.') self.add_alert(alert) alert.show() return elif calories is None or calories < 0: alert = NotifyAlert() alert.props.title = _('Add a new food item.') alert.connect('response', _notification_alert_response_cb, self) alert.props.msg = _('You must enter calories for the new food \ item.') self.add_alert(alert) alert.show() return elif self._custom_food_jobject is None: alert = NotifyAlert() alert.props.title = _('Add a new food item.') alert.connect('response', _notification_alert_response_cb, self) alert.props.msg = _('You must load an image for the new food \ item.') self.add_alert(alert) alert.show() return _logger.debug(self._custom_food_jobject.file_path) FOOD.append([name, calories, pyramid, 'apple.png']) self._game.word_card_append(self._game.food_cards, self._game.pixbuf) self._game.food_cards[-1].type = len(FOOD) - 1 self._game.food_cards[-1].set_label(name) self._game.picture_append(self._custom_food_jobject.file_path) self._game.small_picture_append(self._custom_food_jobject.file_path) alert = NotifyAlert() alert.props.title = _('Add a new food item.') alert.connect('response', _notification_alert_response_cb, self) alert.props.msg = _('%s has been loaded.') % (name) self.add_alert(alert) alert.show() self.name_entry.set_text(_('food name')) self.calories_entry.set_text(_('calories')) self._custom_food_image_path = None self._game.build_food_groups() self._game.new_game() self.metadata['name-%d' % (self._custom_food_counter)] = name self.metadata['calories-%d' % (self._custom_food_counter)] = \ str(calories) self.metadata['pyramid-%d' % (self._custom_food_counter)] = str(pyramid) self.metadata['jobject-%d' % (self._custom_food_counter)] = \ self._custom_food_jobject.object_id self._custom_food_counter += 1 _logger.debug('writing %d to counter' % (self._custom_food_counter)) self.metadata['counter'] = str(self._custom_food_counter) return