def _window_opened_cb(self, screen, window): """Handle the callback for the 'window opened' event. Most activities will register 2 windows during their lifetime: the launcher window, and the 'main' app window. When the main window appears, we send a signal to the launcher window to close. Some activities (notably non-native apps) open several windows during their lifetime, switching from one to the next as the 'main' window. We use a stack to track them. """ if window.get_window_type() == Wnck.WindowType.NORMAL or \ window.get_window_type() == Wnck.WindowType.SPLASHSCREEN: home_activity = None xid = window.get_xid() activity_id = SugarExt.wm_get_activity_id(xid) service_name = SugarExt.wm_get_bundle_id(xid) if service_name: registry = get_registry() activity_info = registry.get_bundle(service_name) else: activity_info = None if activity_id: home_activity = self.get_activity_by_id(activity_id) display = Gdk.Display.get_default() gdk_window = GdkX11.X11Window.foreign_new_for_display(display, xid) gdk_window.set_decorations(0) window.maximize() if not home_activity: logging.debug('first window registered for %s', activity_id) color = self._shared_activities.get(activity_id, None) home_activity = Activity(activity_info, activity_id, color, window) self._add_activity(home_activity) else: logging.debug('window registered for %s', activity_id) home_activity.add_window(window) if window.get_window_type() != Wnck.WindowType.SPLASHSCREEN \ and \ home_activity.get_launch_status() == Activity.LAUNCHING: self.emit('launch-completed', home_activity) startup_time = time.time() - home_activity.get_launch_time() logging.debug('%s launched in %f seconds.', activity_id, startup_time) if self._active_activity is None: self._set_active_activity(home_activity)
def __copy_to_clipboard_cb(self, menu_item): clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD) uid_list = self._get_uid_list_cb() if len(uid_list) == 1: uid = uid_list[0] file_path = model.get_file(uid) if not file_path or not os.path.exists(file_path): logging.warn('Entries without a file cannot be copied.') self.emit('volume-error', _('Entries without a file cannot be copied.'), _('Warning')) return # XXX SL#4307 - until set_with_data bindings are fixed upstream if hasattr(clipboard, 'set_with_data'): clipboard.set_with_data( [Gtk.TargetEntry.new('text/uri-list', 0, 0)], self.__clipboard_get_func_cb, self.__clipboard_clear_func_cb, None) else: SugarExt.clipboard_set_with_data( clipboard, [Gtk.TargetEntry.new('text/uri-list', 0, 0)], self.__clipboard_get_func_cb, self.__clipboard_clear_func_cb, None)
def __realize_cb(self, window): xid = window.get_window().get_xid() SugarExt.wm_set_bundle_id(xid, _BUNDLE_ID) activity_id = activityfactory.create_activity_id() SugarExt.wm_set_activity_id(xid, str(activity_id)) self.disconnect(self._realized_sid) self._realized_sid = None
def __init__(self): GObject.GObject.__init__(self) address = SugarExt.xsmp_init() os.environ['SESSION_MANAGER'] = address SugarExt.xsmp_run() self.session = SugarExt.Session.create_global() self._shell_model = shell.get_model() self._shutdown_tries = 0 self._logout_mode = None
def __realize_cb(self, window): display_name = Gdk.Display.get_default().get_name() if ':' in display_name: # X11 for sure; this only works in X11 xid = window.get_window().get_xid() SugarExt.wm_set_bundle_id(xid, self.get_bundle_id()) SugarExt.wm_set_activity_id(xid, str(self._activity_id)) elif display_name is 'Broadway': # GTK3's HTML5 backend # This is needed so that the window takes the whole browser window self.maximize()
def tearDown(self): client = GConf.Client.get_default() if self._save_view_icons is None: client.unset(_VIEW_KEY) else: SugarExt.gconf_client_set_string_list(client, _VIEW_KEY, self._save_view_icons) if self._save_favorite_icons is None: client.unset(_FAVORITE_KEY) else: SugarExt.gconf_client_set_string_list(client, _FAVORITE_KEY, self._save_favorite_icons)
def _check_gconf_settings(): client = GConf.Client.get_default() # Zendesk client.set_string('/desktop/sugar/services/zendesk/url', 'https://oneedu.zendesk.com') client.set_string('/desktop/sugar/services/zendesk/token', 'eG8tc3VwcG9ydEBsYXB0b3Aub3JnLmF1L3Rva2VuOlZTaWM4' 'TThZbjZBRTJkMWxYNkFGbFhkZzUxSjlJSHFUQ01DYzNjOHY=') try: SugarExt.gconf_client_set_string_list( client, '/desktop/sugar/services/zendesk/fields', ['21891880', '21729904', '21729914']) except Exception as e: _logger.error('Could not set zendesk fields: %s' % e)
def set_option_group(self, option_group): """Sets the supplied option for switching keyboard group""" #XXX: Merge, not overwrite previous options if not option_group: options = [''] elif isinstance(option_group, list): options = option_group else: options = [option_group] # FIXME, gconf_client_set_list not introspectable #681433 # self._gconf_client.set_list(_OPTIONS_KEY, GConf.ValueType.STRING, # options) SugarExt.gconf_client_set_string_list(self._gconf_client, _OPTIONS_KEY, options) self._configrec.set_options(options) self._configrec.activate(self._engine)
def _put_in_clipboard(self): logging.debug('ClipboardIcon._put_in_clipboard') if self._cb_object.get_percent() < 100: raise ValueError('Object is not complete, cannot be put into the' ' clipboard.') targets = self._get_targets() if targets: x_clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD) # XXX SL#4307 - until set_with_data bindings are fixed upstream if hasattr(x_clipboard, 'set_with_data'): stored = x_clipboard.set_with_data(targets, self._clipboard_data_get_cb, self._clipboard_clear_cb, targets) else: stored = SugarExt.clipboard_set_with_data( x_clipboard, targets, self._clipboard_data_get_cb, self._clipboard_clear_cb, targets) if not stored: logging.error('GtkClipboard.set_with_data failed!') else: self.owns_clipboard = True
def __init__(self, frame): self._frame = frame self._key_pressed = None self._keycode_pressed = 0 self._keystate_pressed = 0 self._key_grabber = SugarExt.KeyGrabber() self._key_grabber.connect('key-pressed', self._key_pressed_cb) self._key_grabber.connect('key-released', self._key_released_cb) self._tabbing_handler = TabbingHandler(self._frame, _TABBING_MODIFIER) for f in os.listdir(os.path.join(config.ext_path, 'globalkey')): if f.endswith('.py') and not f.startswith('__'): module_name = f[:-3] try: logging.debug('Loading module %r', module_name) module = __import__('globalkey.' + module_name, globals(), locals(), [module_name]) for key in module.BOUND_KEYS: if key in _actions_table: raise ValueError('Key %r is already bound' % key) _actions_table[key] = module except Exception: logging.exception('Exception while loading extension:') self._key_grabber.grab_keys(list(_actions_table.keys()))
def setup(): '''Cursor tracker: only display the cursor in mouse/trackpad mode We only display the cursor in mouse/trackpad mode, hence when a mouse motion is detected or a button press event. When a touch begin event is received the cursor will be hidden. We only track the incoming events when a touchscreen device is available. ''' global _instance display = Gdk.Display.get_default() device_manager = display.get_device_manager() devices = device_manager.list_devices(Gdk.DeviceType.SLAVE) for device in devices: if device.get_source() == Gdk.InputSource.TOUCHSCREEN: logging.debug('Cursor Tracker: found touchscreen, ' 'will track input.') _instance = SugarExt.CursorTracker() break if not _instance: logging.debug('Cursor Tracker: no touchscreen available, ' 'will not track input.')
def _put_in_clipboard(self): logging.debug('ClipboardIcon._put_in_clipboard') if self._cb_object.get_percent() < 100: raise ValueError('Object is not complete, cannot be put into the' ' clipboard.') targets = self._get_targets() if targets: x_clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD) # XXX SL#4307 - until set_with_data bindings are fixed upstream if hasattr(x_clipboard, 'set_with_data'): stored = x_clipboard.set_with_data( targets, self._clipboard_data_get_cb, self._clipboard_clear_cb, targets) else: stored = SugarExt.clipboard_set_with_data( x_clipboard, targets, self._clipboard_data_get_cb, self._clipboard_clear_cb, targets) if not stored: logging.error('GtkClipboard.set_with_data failed!') else: self.owns_clipboard = True
def set_layouts(self, layouts): """Sets the supplied keyboard layouts (with variants)""" if layouts is None or not layouts: return # FIXME, gconf_client_set_list not introspectable #681433 # self._gconf_client.set_list(_LAYOUTS_KEY, GConf.ValueType.STRING, # layouts) SugarExt.gconf_client_set_string_list(self._gconf_client, _LAYOUTS_KEY, layouts) layouts_list = [] variants_list = [] for layout in layouts: layouts_list.append(layout.split('(')[0]) variants_list.append(layout.split('(')[1][:-1]) self._configrec.set_layouts(layouts_list) self._configrec.set_variants(variants_list) self._configrec.activate(self._engine)
def __init__(self, frame): self._frame = frame self._gesture_grabber = SugarExt.GestureGrabber() self._controller = [] screen = Gdk.Screen.get_default() screen.connect('size-changed', self.__size_changed_cb) self._add_controller()
def table_row_to_clipboard(self, table_dict): """Put the Selected Table Row to the Clipboard""" html_text = self.dad.html_handler.table_export_to_html(table_dict) clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD) stored = SugarExt.clipboard_set_with_data( clipboard, self._targets_names_to_gtk_targets( [TARGET_CTD_TABLE, TARGETS_HTML[0]]), self.get_func, self.clear_func, (None, None, html_text, table_dict)) if not stored: print("! clipboard_set_with_data")
def __init__(self): GObject.GObject.__init__(self) self._xsmp_client = SugarExt.ClientXSMP() self._xsmp_client.connect('quit-requested', self.__sm_quit_requested_cb) self._xsmp_client.connect('quit', self.__sm_quit_cb) self._xsmp_client.startup() self._activities = [] self._will_quit = []
def get_for_file(file_name): if file_name.startswith('file://'): file_name = file_name[7:] file_name = os.path.realpath(file_name) mime_type = SugarExt.mime_get_mime_type_for_file(file_name, None) if mime_type == 'application/octet-stream': if _file_looks_like_text(file_name): return 'text/plain' else: return 'application/octet-stream' return mime_type
def shutdown_completed(self): if self._logout_mode != self.MODE_LOGOUT: bus = dbus.SystemBus() if have_systemd(): try: proxy = bus.get_object('org.freedesktop.login1', '/org/freedesktop/login1') pm = dbus.Interface(proxy, 'org.freedesktop.login1.Manager') if self._logout_mode == self.MODE_SHUTDOWN: pm.PowerOff(False) elif self._logout_mode == self.MODE_REBOOT: pm.Reboot(True) except: logging.exception('Can not stop sugar') self.session.cancel_shutdown() return else: CONSOLEKIT_DBUS_PATH = '/org/freedesktop/ConsoleKit/Manager' try: proxy = bus.get_object('org.freedesktop.ConsoleKit', CONSOLEKIT_DBUS_PATH) pm = dbus.Interface(proxy, 'org.freedesktop.ConsoleKit.Manager') if self._logout_mode == self.MODE_SHUTDOWN: pm.Stop() elif self._logout_mode == self.MODE_REBOOT: pm.Restart() except: logging.exception('Can not stop sugar') self.session.cancel_shutdown() return SugarExt.xsmp_shutdown() Gtk.main_quit()
def _check_gconf_settings(): from gi.repository import GConf client = GConf.Client.get_default() # Training server client.set_string( '/desktop/sugar/services/training/url', 'https://training.one-education.org/training/report ') client.set_string('/desktop/sugar/services/training/api_key', 'SbCeK4nH8dpQJsHNn9djza9g') # Zendesk client.set_string('/desktop/sugar/services/zendesk/url', 'https://oneedu1392860248.zendesk.com') client.set_string('/desktop/sugar/services/zendesk/token', 'eG8tc3VwcG9ydEBsYXB0b3Aub3JnLmF1L3Rva2VuOjdHRkV5' 'STF2MFNRVzJyYmdFVXFFUWRpOE1Cc1I0NGdHVURhTWg2QWU=') try: SugarExt.gconf_client_set_string_list( client, '/desktop/sugar/services/zendesk/fields', ['21765610', '21605694', '21765620']) except Exception as e: _logger.error('Could not set zendesk fields: %s' % e)
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 shutdown_completed(self): SugarExt.xsmp_shutdown()
def selection_to_clipboard(self, text_buffer, sourceview, iter_sel_start, iter_sel_end, num_chars, from_codebox): """Write the Selected Content to the Clipboard""" clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD) pixbuf_target = None if not from_codebox and self.dad.syntax_highlighting == cons.RICH_TEXT_ID and num_chars == 1: anchor = iter_sel_start.get_child_anchor() if anchor: anchor_dir = dir(anchor) if "pixbuf" in anchor_dir: pixbuf_target = anchor.pixbuf elif "liststore" in anchor_dir: table_dict = self.dad.state_machine.table_to_dict(anchor) html_text = self.dad.html_handler.table_export_to_html( table_dict) txt_handler = exports.Export2Txt(self.dad) text_offsets_range = [ iter_sel_start.get_offset(), iter_sel_end.get_offset() ] plain_text = txt_handler.node_export_to_txt( text_buffer, "", sel_range=text_offsets_range, check_link_target=True) stored = SugarExt.clipboard_set_with_data( clipboard, self._targets_names_to_gtk_targets([ TARGET_CTD_TABLE, TARGETS_HTML[0], TARGET_CTD_PLAIN_TEXT ]), self.get_func, self.clear_func, (plain_text, None, html_text, table_dict)) if not stored: print("! clipboard_set_with_data") return elif "sourcebuffer" in anchor_dir: codebox_dict = self.dad.state_machine.codebox_to_dict( anchor, for_print=0) codebox_dict_html = self.dad.state_machine.codebox_to_dict( anchor, for_print=2) html_text = self.dad.html_handler.codebox_export_to_html( codebox_dict_html) txt_handler = exports.Export2Txt(self.dad) text_offsets_range = [ iter_sel_start.get_offset(), iter_sel_end.get_offset() ] plain_text = txt_handler.node_export_to_txt( text_buffer, "", sel_range=text_offsets_range, check_link_target=True) stored = SugarExt.clipboard_set_with_data( clipboard, self._targets_names_to_gtk_targets([ TARGET_CTD_CODEBOX, TARGETS_HTML[0], TARGET_CTD_PLAIN_TEXT ]), self.get_func, self.clear_func, (plain_text, None, html_text, codebox_dict)) if not stored: print("! clipboard_set_with_data") return if not os.path.isdir(cons.TMP_FOLDER): os.mkdir(cons.TMP_FOLDER) html_text = self.dad.html_handler.selection_export_to_html( text_buffer, iter_sel_start, iter_sel_end, self.dad.syntax_highlighting if not from_codebox else cons.PLAIN_TEXT_ID) if not from_codebox and self.dad.syntax_highlighting == cons.RICH_TEXT_ID: txt_handler = exports.Export2Txt(self.dad) text_offsets_range = [ iter_sel_start.get_offset(), iter_sel_end.get_offset() ] plain_text = txt_handler.node_export_to_txt( text_buffer, "", sel_range=text_offsets_range, check_link_target=True) rich_text = self.rich_text_get_from_text_buffer_selection( text_buffer, iter_sel_start, iter_sel_end) if not self.force_plain_text: targets_vector = [ TARGET_CTD_PLAIN_TEXT, TARGET_CTD_RICH_TEXT, TARGETS_HTML[0], TARGETS_HTML[1] ] if pixbuf_target: targets_vector.append(TARGETS_IMAGES[0]) else: targets_vector = [TARGET_CTD_PLAIN_TEXT] stored = SugarExt.clipboard_set_with_data( clipboard, self._targets_names_to_gtk_targets(targets_vector), self.get_func, self.clear_func, (plain_text, rich_text, html_text, pixbuf_target)) if not stored: print("! clipboard_set_with_data") else: plain_text = text_buffer.get_text(iter_sel_start, iter_sel_end, False) if not self.force_plain_text: targets_vector = [ TARGET_CTD_PLAIN_TEXT, TARGETS_HTML[0], TARGETS_HTML[1] ] else: targets_vector = [TARGET_CTD_PLAIN_TEXT] stored = SugarExt.clipboard_set_with_data( clipboard, self._targets_names_to_gtk_targets(targets_vector), self.get_func, self.clear_func, (plain_text, None, html_text, pixbuf_target)) if not stored: print("! clipboard_set_with_data")
def get_mime_parents(mime_type): return SugarExt.mime_list_mime_parents(mime_type)
def get_from_file_name(file_name): return SugarExt.mime_get_mime_type_from_file_name(file_name)
# # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA from gi.repository import GConf from gi.repository import SugarExt from sugar3 import dispatch VOLUME_STEP = 10 muted_changed = dispatch.Signal() volume_changed = dispatch.Signal() _volume = SugarExt.VolumeAlsa() def get_muted(): return _volume.get_mute() def get_volume(): return _volume.get_volume() def set_volume(new_volume): _volume.set_volume(new_volume) volume_changed.send(None) save()
def _write_entry_on_external_device(metadata, file_path, ready_callback=None): """Create and update an entry copied from the DS to an external storage device. Besides copying the associated file a file for the preview and one for the metadata are stored in the hidden directory .Sugar-Metadata. This function handles renames of an entry on the external device and avoids name collisions. Renames are handled failsafe. """ def _ready_cb(): if ready_callback: ready_callback(metadata, file_path, destination_path) def _updated_cb(*args): updated.send(None, object_id=destination_path) _ready_cb() def _splice_cb(*args): created.send(None, object_id=destination_path) _ready_cb() if 'uid' in metadata and os.path.exists(metadata['uid']): file_path = metadata['uid'] if not file_path or not os.path.exists(file_path): raise ValueError('Entries without a file cannot be copied to ' 'removable devices') if not metadata.get('title'): metadata['title'] = _('Untitled') original_file_name = os.path.basename(file_path) original_dir_name = os.path.dirname(file_path) # if is a file in the exernal device or Documents # and the title is equal to the file name don't change it if original_file_name == metadata['title'] and \ original_dir_name.startswith(metadata['mountpoint']): destination_path = file_path file_name = original_file_name else: file_name = metadata['title'] # only change the extension if the title don't have a good extension clean_name, extension = os.path.splitext(file_name) extension = extension.replace('.', '').lower() mime_extensions = mime.get_extensions_by_mimetype( metadata['mime_type']) if extension not in mime_extensions: file_name = get_file_name(metadata['title'], metadata['mime_type']) destination_path = os.path.join(metadata['mountpoint'], file_name) if destination_path != file_path: file_name = get_unique_file_name(metadata['mountpoint'], file_name) destination_path = os.path.join(metadata['mountpoint'], file_name) metadata['title'] = file_name metadata_copy = metadata.copy() metadata_copy.pop('mountpoint', None) metadata_copy.pop('uid', None) metadata_copy.pop('filesize', None) metadata_dir_path = os.path.join(metadata['mountpoint'], JOURNAL_METADATA_DIR) # check if the file is in a subdirectory in Documents or device if original_dir_name.startswith(metadata['mountpoint']) and \ original_dir_name != metadata['mountpoint']: subdir = os.path.relpath(original_dir_name, metadata['mountpoint']) metadata_dir_path = os.path.join(metadata_dir_path, subdir) if not os.path.exists(metadata_dir_path): os.makedirs(metadata_dir_path) # Set the HIDDEN attrib even when the metadata directory already # exists for backward compatibility; but don't set it in ~/Documents if not metadata['mountpoint'] == get_documents_path(): if not SugarExt.fat_set_hidden_attrib(metadata_dir_path): logging.error('Could not set hidden attribute on %s' % (metadata_dir_path)) preview = None if 'preview' in metadata_copy: preview = metadata_copy['preview'] preview_fname = file_name + '.preview' metadata_copy.pop('preview', None) try: metadata_json = json.dumps(metadata_copy) except (UnicodeDecodeError, EnvironmentError): logging.error('Could not convert metadata to json.') else: (fh, fn) = tempfile.mkstemp(dir=metadata['mountpoint']) os.write(fh, metadata_json) os.close(fh) os.rename(fn, os.path.join(metadata_dir_path, file_name + '.metadata')) if preview: (fh, fn) = tempfile.mkstemp(dir=metadata['mountpoint']) os.write(fh, preview) os.close(fh) os.rename(fn, os.path.join(metadata_dir_path, preview_fname)) if not os.path.dirname(destination_path) == os.path.dirname(file_path): input_stream = Gio.File.new_for_path(file_path).read(None) output_stream = Gio.File.new_for_path(destination_path)\ .append_to(Gio.FileCreateFlags.PRIVATE | Gio.FileCreateFlags.REPLACE_DESTINATION, None) # TODO: use Gio.File.copy_async, when implemented output_stream.splice_async( input_stream, Gio.OutputStreamSpliceFlags.CLOSE_SOURCE | Gio.OutputStreamSpliceFlags.CLOSE_TARGET, GLib.PRIORITY_LOW, None, _splice_cb, None) else: _rename_entry_on_external_device(file_path, destination_path, metadata_dir_path) _updated_cb()
class EBookReader(): def __init__(self, (filepath, journal_id, )): self.pages_list = [ MyLibraryTab(self), GetBooksTab(self), ReadTab(self), HowToUseTab(self) ] if not os.path.exists(env.EBOOKREADER_LOCAL_DATA_DIRECTORY): os.makedirs(env.EBOOKREADER_LOCAL_DATA_DIRECTORY) os.chmod(env.EBOOKREADER_LOCAL_DATA_DIRECTORY, 0755) self.window = EBookReaderWindow(self) self._tab_toolbars_list = [] self._toolbar_buttons_list = [] self.window.connect('key-press-event', self.handle_key_press_cb) self._allow_keys_processing = True #if (os.path.isfile('/bin/evtest') or os.path.isfile('/usr/bin/evtest')): # GObject.timeout_add(2000, self.__auto_move_between_normal_and_fullscreen_mode) self.notebook = Notebook() self._last_page = 0 self._full_screen_wait_signal = FullScreenWaitSignal() self._full_screen_wait_signal.set_transient_for(self.window) self._bookmark_widget = BookmarkOverlayWidget() self._process_bookmarks_in_ebook_mode_widget = ProcessBookmarksInEBookModeWidget( self) self._process_bookmarks_in_ebook_mode_widget.set_transient_for( self.window) self._process_zoom_in_ebook_mode_widget = ProcessZoomInEBookModeWidget( self) self._process_zoom_in_ebook_mode_widget.set_transient_for(self.window) self._process_files_in_ebook_mode_widget = ProcessFilesInEBookModeWidget( self) self._process_files_in_ebook_mode_widget.set_transient_for(self.window) self._modes = {} self._modes[constants.MODE_NORMAL] = self.get_reader_tab() self._modes[ constants.MODE_ZOOM] = self._process_zoom_in_ebook_mode_widget self._modes[ constants. MODE_SELECT_FILE] = self._process_files_in_ebook_mode_widget self._current_mode = self._modes[constants.MODE_NORMAL] self._toolbar_box = ToolbarBox() # Remove the horizontal padding, being caused due to upstream # API. self._toolbar_box.props.padding = 0 self.window.set_toolbar_box(self._toolbar_box) self._toolbar_box.toolbar.modify_bg(Gtk.StateType.NORMAL, Gdk.color_parse('#282828')) placeholder = SecondaryToolbarButton(None) placeholder.props.sensitive = False self._toolbar_box._toolbar.insert(placeholder, -1) pagenum = 0 for page in self.pages_list: page.set_main_window(self) page.set_pagenum(pagenum) pagenum = pagenum + 1 self.add_page(page) self.notebook.set_show_tabs(False) # Add the "stop" button, in the top-row. # But before that, put some space, by inserting a dummy widget, # containing only text. label_text = '' for i in range(0, 85): label_text = label_text + ' ' dummy_label = Gtk.Label(label_text) toolitem = Gtk.ToolItem() toolitem.add(dummy_label) self._toolbar_box._toolbar.insert(toolitem, -1) self._stop_button = SecondaryToolbarButton('bookreader-stop', _('Stop'), self.destroy) separador = Gtk.SeparatorToolItem() separador.props.draw = False separador.set_size_request(0, -1) separador.set_expand(True) self._toolbar_box._toolbar.insert(separador, -1) self._toolbar_box._toolbar.insert(self._stop_button, -1) placeholder = SecondaryToolbarButton(None) placeholder.props.sensitive = False self._toolbar_box._toolbar.insert(placeholder, -1) self._toolbar_box.show_all() if (filepath is not None) and (filepath != "") and \ (filepath != '""'): self.load_and_read_book(( filepath, journal_id, )) else: self.notebook.set_current_page(0) self._last_page = 0 self.window.set_canvas(self.notebook) self.window.show_all() self.window.maximize() self.window.show_all() if get_active_desktop() == "Sugar": for i in range(0, len(sys.argv)): if sys.argv[i] == '-a': activity_id = sys.argv[i + 1] break xid = self.window.get_window().get_xid() SugarExt.wm_set_bundle_id(xid, env.SUGAR_BUNDLE_ID) SugarExt.wm_set_activity_id(xid, activity_id)
def test_set_views(self): self.target = _MOCK_LIST with self.run_view("gtk_main"): client = GConf.Client.get_default() SugarExt.gconf_client_set_string_list(client, _VIEW_KEY, _MOCK_LIST)
def _write_entry_on_external_device(metadata, file_path): """Create and update an entry copied from the DS to an external storage device. Besides copying the associated file a file for the preview and one for the metadata are stored in the hidden directory .Sugar-Metadata. This function handles renames of an entry on the external device and avoids name collisions. Renames are handled failsafe. """ if 'uid' in metadata and os.path.exists(metadata['uid']): file_path = metadata['uid'] if not file_path or not os.path.exists(file_path): raise ValueError('Entries without a file cannot be copied to ' 'removable devices') if not metadata.get('title'): metadata['title'] = _('Untitled') file_name = get_file_name(metadata['title'], metadata['mime_type']) destination_path = os.path.join(metadata['mountpoint'], file_name) if destination_path != file_path: file_name = get_unique_file_name(metadata['mountpoint'], file_name) destination_path = os.path.join(metadata['mountpoint'], file_name) clean_name, extension_ = os.path.splitext(file_name) metadata['title'] = clean_name metadata_copy = metadata.copy() metadata_copy.pop('mountpoint', None) metadata_copy.pop('uid', None) metadata_copy.pop('filesize', None) metadata_dir_path = os.path.join(metadata['mountpoint'], JOURNAL_METADATA_DIR) if not os.path.exists(metadata_dir_path): os.mkdir(metadata_dir_path) # Set the HIDDEN attrib even when the metadata directory already # exists for backward compatibility. if not SugarExt.fat_set_hidden_attrib(metadata_dir_path): logging.error('Could not set hidden attribute on %s' % (metadata_dir_path)) preview = None if 'preview' in metadata_copy: preview = metadata_copy['preview'] preview_fname = file_name + '.preview' metadata_copy.pop('preview', None) try: metadata_json = json.dumps(metadata_copy) except (UnicodeDecodeError, EnvironmentError): logging.error('Could not convert metadata to json.') else: (fh, fn) = tempfile.mkstemp(dir=metadata['mountpoint']) os.write(fh, metadata_json) os.close(fh) os.rename(fn, os.path.join(metadata_dir_path, file_name + '.metadata')) if preview: (fh, fn) = tempfile.mkstemp(dir=metadata['mountpoint']) os.write(fh, preview) os.close(fh) os.rename(fn, os.path.join(metadata_dir_path, preview_fname)) if not os.path.dirname(destination_path) == os.path.dirname(file_path): shutil.copy(file_path, destination_path) else: _rename_entry_on_external_device(file_path, destination_path, metadata_dir_path) object_id = destination_path created.send(None, object_id=object_id) return object_id
def _write_entry_on_external_device(metadata, file_path, ready_callback=None): """Create and update an entry copied from the DS to an external storage device. Besides copying the associated file a file for the preview and one for the metadata are stored in the hidden directory .Sugar-Metadata. This function handles renames of an entry on the external device and avoids name collisions. Renames are handled failsafe. """ def _ready_cb(): if ready_callback: ready_callback(metadata, file_path, destination_path) def _splice_cb(*args): created.send(None, object_id=destination_path) _ready_cb() if 'uid' in metadata and os.path.exists(metadata['uid']): file_path = metadata['uid'] if not file_path or not os.path.exists(file_path): raise ValueError('Entries without a file cannot be copied to ' 'removable devices') if not metadata.get('title'): metadata['title'] = _('Untitled') file_name = get_file_name(metadata['title'], metadata['mime_type']) destination_path = os.path.join(metadata['mountpoint'], file_name) if destination_path != file_path: file_name = get_unique_file_name(metadata['mountpoint'], file_name) destination_path = os.path.join(metadata['mountpoint'], file_name) clean_name, extension_ = os.path.splitext(file_name) metadata['title'] = clean_name metadata_copy = metadata.copy() metadata_copy.pop('mountpoint', None) metadata_copy.pop('uid', None) metadata_copy.pop('filesize', None) metadata_dir_path = os.path.join(metadata['mountpoint'], JOURNAL_METADATA_DIR) if not os.path.exists(metadata_dir_path): os.mkdir(metadata_dir_path) # Set the HIDDEN attrib even when the metadata directory already # exists for backward compatibility; but don't set it in ~/Documents if not metadata['mountpoint'] == get_documents_path(): if not SugarExt.fat_set_hidden_attrib(metadata_dir_path): logging.error('Could not set hidden attribute on %s' % (metadata_dir_path)) preview = None if 'preview' in metadata_copy: preview = metadata_copy['preview'] preview_fname = file_name + '.preview' metadata_copy.pop('preview', None) try: metadata_json = json.dumps(metadata_copy) except (UnicodeDecodeError, EnvironmentError): logging.error('Could not convert metadata to json.') else: (fh, fn) = tempfile.mkstemp(dir=metadata['mountpoint']) os.write(fh, metadata_json) os.close(fh) os.rename(fn, os.path.join(metadata_dir_path, file_name + '.metadata')) if preview: (fh, fn) = tempfile.mkstemp(dir=metadata['mountpoint']) os.write(fh, preview) os.close(fh) os.rename(fn, os.path.join(metadata_dir_path, preview_fname)) if not os.path.dirname(destination_path) == os.path.dirname(file_path): input_stream = Gio.File.new_for_path(file_path).read(None) output_stream = Gio.File.new_for_path(destination_path)\ .append_to(Gio.FileCreateFlags.PRIVATE | Gio.FileCreateFlags.REPLACE_DESTINATION, None) # TODO: use Gio.File.copy_async, when implemented output_stream.splice_async( input_stream, Gio.OutputStreamSpliceFlags.CLOSE_SOURCE | Gio.OutputStreamSpliceFlags.CLOSE_TARGET, GLib.PRIORITY_LOW, None, _splice_cb, None) else: _rename_entry_on_external_device(file_path, destination_path, metadata_dir_path) _ready_cb()
def __init__(self): address = SugarExt.xsmp_init() os.environ['SESSION_MANAGER'] = address SugarExt.xsmp_run() self.session = SugarExt.Session.create_global()
def _window_opened_cb(self, screen, window): """Handle the callback for the 'window opened' event. Most activities will register 2 windows during their lifetime: the launcher window, and the 'main' app window. When the main window appears, we send a signal to the launcher window to close. Some activities (notably non-native apps) open several windows during their lifetime, switching from one to the next as the 'main' window. We use a stack to track them. """ if window.get_window_type() == Wnck.WindowType.NORMAL or \ window.get_window_type() == Wnck.WindowType.SPLASHSCREEN: home_activity = None xid = window.get_xid() activity_id = SugarExt.wm_get_activity_id(xid) service_name = SugarExt.wm_get_bundle_id(xid) if service_name: registry = get_registry() activity_info = registry.get_bundle(service_name) else: activity_info = None if activity_id: home_activity = self.get_activity_by_id(activity_id) display = Gdk.Display.get_default() gdk_window = GdkX11.X11Window.foreign_new_for_display( display, xid) gdk_window.set_decorations(0) window.maximize() def is_main_window(window, home_activity): # Check if window is the 'main' app window, not the # launcher window. return window.get_window_type() != \ Wnck.WindowType.SPLASHSCREEN and \ home_activity.get_launch_status() == Activity.LAUNCHING if home_activity is None and \ window.get_window_type() == Wnck.WindowType.NORMAL: # This is a special case for the Journal # We check if is not a splash screen to avoid #4767 logging.debug('first window registered for %s', activity_id) color = self._shared_activities.get(activity_id, None) home_activity = Activity(activity_info, activity_id, color, window) self._add_activity(home_activity) else: logging.debug('window registered for %s', activity_id) home_activity.add_window(window, is_main_window(window, home_activity)) if is_main_window(window, home_activity): self.emit('launch-completed', home_activity) startup_time = time.time() - home_activity.get_launch_time() logging.debug('%s launched in %f seconds.', activity_id, startup_time) if self._active_activity is None: self._set_active_activity(home_activity)
def get_type(self): """Retrieve the activity bundle id for future reference""" if not self._windows: return None else: return SugarExt.wm_get_bundle_id(self._windows[0].get_xid())
def __realize_cb(self, widget): SugarExt.wm_set_activity_id(widget.get_window().get_xid(), str(self._activity_id))
def __realize_cb(self, window): xid = window.get_window().get_xid() SugarExt.wm_set_bundle_id(xid, self.get_bundle_id()) SugarExt.wm_set_activity_id(xid, str(self._activity_id))
def _realize_cb(self, window): xid = window.get_window().get_xid() SugarExt.wm_set_bundle_id(xid, self._bundle_id) SugarExt.wm_set_activity_id(xid, str(self._activity_id))