Ejemplo n.º 1
0
    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)
Ejemplo n.º 2
0
    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)
Ejemplo n.º 3
0
 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
Ejemplo n.º 4
0
    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)
Ejemplo n.º 5
0
 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
Ejemplo n.º 6
0
    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
Ejemplo n.º 7
0
 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()
Ejemplo n.º 8
0
    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
Ejemplo n.º 9
0
 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)
Ejemplo n.º 10
0
 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)
Ejemplo n.º 11
0
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)
Ejemplo n.º 12
0
 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)
Ejemplo n.º 13
0
    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
Ejemplo n.º 14
0
    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()))
Ejemplo n.º 15
0
 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)
Ejemplo n.º 16
0
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.')
Ejemplo n.º 17
0
    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
Ejemplo n.º 18
0
 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)
Ejemplo n.º 19
0
 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)
Ejemplo n.º 20
0
    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()
Ejemplo n.º 21
0
 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")
Ejemplo n.º 22
0
    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 = []
Ejemplo n.º 23
0
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
Ejemplo n.º 24
0
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
Ejemplo n.º 25
0
    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()
Ejemplo n.º 26
0
    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()
Ejemplo n.º 27
0
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)
Ejemplo n.º 28
0
    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))
Ejemplo n.º 29
0
 def shutdown_completed(self):
     SugarExt.xsmp_shutdown()
Ejemplo n.º 30
0
 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")
Ejemplo n.º 31
0
def get_mime_parents(mime_type):
    return SugarExt.mime_list_mime_parents(mime_type)
Ejemplo n.º 32
0
def get_from_file_name(file_name):
    return SugarExt.mime_get_mime_type_from_file_name(file_name)
Ejemplo n.º 33
0
def get_from_file_name(file_name):
    return SugarExt.mime_get_mime_type_from_file_name(file_name)
Ejemplo n.º 34
0
#
# 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()
Ejemplo n.º 35
0
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()
Ejemplo n.º 36
0
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)
Ejemplo n.º 37
0
 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)
Ejemplo n.º 38
0
 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)
Ejemplo n.º 39
0
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
Ejemplo n.º 40
0
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()
Ejemplo n.º 41
0
    def __init__(self):
        address = SugarExt.xsmp_init()
        os.environ['SESSION_MANAGER'] = address
        SugarExt.xsmp_run()

        self.session = SugarExt.Session.create_global()
Ejemplo n.º 42
0
    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)
Ejemplo n.º 43
0
 def shutdown_completed(self):
     SugarExt.xsmp_shutdown()
Ejemplo n.º 44
0
 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())
Ejemplo n.º 45
0
 def __realize_cb(self, widget):
     SugarExt.wm_set_activity_id(widget.get_window().get_xid(),
                                 str(self._activity_id))
Ejemplo n.º 46
0
def get_mime_parents(mime_type):
    return SugarExt.mime_list_mime_parents(mime_type)
Ejemplo n.º 47
0
 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))
Ejemplo n.º 48
0
 def __realize_cb(self, widget):
     SugarExt.wm_set_activity_id(widget.get_window().get_xid(),
                                 str(self._activity_id))
Ejemplo n.º 49
0
 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())
Ejemplo n.º 50
0
    def __init__(self):
        address = SugarExt.xsmp_init()
        os.environ['SESSION_MANAGER'] = address
        SugarExt.xsmp_run()

        self.session = SugarExt.Session.create_global()
Ejemplo n.º 51
0
 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))
Ejemplo n.º 52
0
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