コード例 #1
0
class JournalActivity(JournalWindow):
    def __init__(self):
        logging.debug('STARTUP: Loading the journal')
        JournalWindow.__init__(self)

        self.set_title(_('Journal'))

        self._main_view = None
        self._secondary_view = None
        self._list_view = None
        self._detail_view = None
        self._main_toolbox = None
        self._detail_toolbox = None
        self._volumes_toolbar = None

        self._setup_main_view()
        self._setup_secondary_view()

        self.add_events(gtk.gdk.ALL_EVENTS_MASK
                        | gtk.gdk.VISIBILITY_NOTIFY_MASK)
        self._realized_sid = self.connect('realize', self.__realize_cb)
        self.connect('visibility-notify-event',
                     self.__visibility_notify_event_cb)
        self.connect('window-state-event', self.__window_state_event_cb)
        self.connect('key-press-event', self._key_press_event_cb)
        self.connect('focus-in-event', self._focus_in_event_cb)

        model.created.connect(self.__model_created_cb)
        model.updated.connect(self.__model_updated_cb)
        model.deleted.connect(self.__model_deleted_cb)

        self._dbus_service = JournalActivityDBusService(self)

        self.iconify()

        self._critical_space_alert = None
        self._check_available_space()

    def __volume_error_cb(self, gobject, message, severity):
        alert = ErrorAlert(title=severity, msg=message)
        alert.connect('response', self.__alert_response_cb)
        self.add_alert(alert)
        alert.show()

    def __alert_response_cb(self, alert, response_id):
        self.remove_alert(alert)

    def __realize_cb(self, window):
        wm.set_bundle_id(window.window, _BUNDLE_ID)
        activity_id = activityfactory.create_activity_id()
        wm.set_activity_id(window.window, str(activity_id))
        self.disconnect(self._realized_sid)
        self._realized_sid = None

    def can_close(self):
        return False

    def _setup_main_view(self):
        self._main_toolbox = MainToolbox()
        self._main_view = gtk.VBox()

        self._list_view = ListView()
        self._list_view.connect('detail-clicked', self.__detail_clicked_cb)
        self._list_view.connect('clear-clicked', self.__clear_clicked_cb)
        self._list_view.connect('volume-error', self.__volume_error_cb)
        self._main_view.pack_start(self._list_view)
        self._list_view.show()

        self._volumes_toolbar = VolumesToolbar()
        self._volumes_toolbar.connect('volume-changed',
                                      self.__volume_changed_cb)
        self._volumes_toolbar.connect('volume-error', self.__volume_error_cb)
        self._main_view.pack_start(self._volumes_toolbar, expand=False)

        search_toolbar = self._main_toolbox.search_toolbar
        search_toolbar.connect('query-changed', self._query_changed_cb)
        search_toolbar.set_mount_point('/')

    def _setup_secondary_view(self):
        self._secondary_view = gtk.VBox()

        self._detail_toolbox = DetailToolbox()
        self._detail_toolbox.entry_toolbar.connect('volume-error',
                                                   self.__volume_error_cb)

        self._detail_view = DetailView()
        self._detail_view.connect('go-back-clicked', self.__go_back_clicked_cb)
        self._secondary_view.pack_end(self._detail_view)
        self._detail_view.show()

    def _key_press_event_cb(self, widget, event):
        keyname = gtk.gdk.keyval_name(event.keyval)
        if keyname == 'Escape':
            self.show_main_view()

    def __detail_clicked_cb(self, list_view, object_id):
        self._show_secondary_view(object_id)

    def __clear_clicked_cb(self, list_view):
        self._main_toolbox.search_toolbar.clear_query()

    def __go_back_clicked_cb(self, detail_view):
        self.show_main_view()

    def _query_changed_cb(self, toolbar, query):
        self._list_view.update_with_query(query)
        self.show_main_view()

    def show_main_view(self):
        if self.toolbar_box != self._main_toolbox:
            self.set_toolbar_box(self._main_toolbox)
            self._main_toolbox.show()

        if self.canvas != self._main_view:
            self.set_canvas(self._main_view)
            self._main_view.show()

    def _show_secondary_view(self, object_id):
        metadata = model.get(object_id)
        try:
            self._detail_toolbox.entry_toolbar.set_metadata(metadata)
        except Exception:
            logging.exception('Exception while displaying entry:')

        self.set_toolbar_box(self._detail_toolbox)
        self._detail_toolbox.show()

        try:
            self._detail_view.props.metadata = metadata
        except Exception:
            logging.exception('Exception while displaying entry:')

        self.set_canvas(self._secondary_view)
        self._secondary_view.show()

    def show_object(self, object_id):
        metadata = model.get(object_id)
        if metadata is None:
            return False
        else:
            self._show_secondary_view(object_id)
            return True

    def __volume_changed_cb(self, volume_toolbar, mount_point):
        logging.debug('Selected volume: %r.', mount_point)
        self._main_toolbox.search_toolbar.set_mount_point(mount_point)
        self._main_toolbox.set_current_toolbar(0)

    def __model_created_cb(self, sender, **kwargs):
        self._check_for_bundle(kwargs['object_id'])
        self._main_toolbox.search_toolbar.refresh_filters()
        self._check_available_space()

    def __model_updated_cb(self, sender, **kwargs):
        self._check_for_bundle(kwargs['object_id'])

        if self.canvas == self._secondary_view and \
                kwargs['object_id'] == self._detail_view.props.metadata['uid']:
            self._detail_view.refresh()

        self._check_available_space()

    def __model_deleted_cb(self, sender, **kwargs):
        if self.canvas == self._secondary_view and \
                kwargs['object_id'] == self._detail_view.props.metadata['uid']:
            self.show_main_view()

    def _focus_in_event_cb(self, window, event):
        self.search_grab_focus()
        self._list_view.update_dates()

    def _check_for_bundle(self, object_id):
        registry = bundleregistry.get_registry()

        metadata = model.get(object_id)
        if metadata.get('progress', '').isdigit():
            if int(metadata['progress']) < 100:
                return

        bundle = misc.get_bundle(metadata)
        if bundle is None:
            return

        if registry.is_installed(bundle):
            logging.debug('_check_for_bundle bundle already installed')
            return

        if metadata['mime_type'] == JournalEntryBundle.MIME_TYPE:
            # JournalEntryBundle code takes over the datastore entry and
            # transforms it into the journal entry from the bundle -- we have
            # nothing more to do.
            try:
                registry.install(bundle, metadata['uid'])
            except (ZipExtractException, RegistrationException):
                logging.exception('Could not install bundle %s',
                                  bundle.get_path())
            return

        try:
            registry.install(bundle)
        except (ZipExtractException, RegistrationException):
            logging.exception('Could not install bundle %s', bundle.get_path())
            return

        metadata['bundle_id'] = bundle.get_bundle_id()
        model.write(metadata)

    def search_grab_focus(self):
        search_toolbar = self._main_toolbox.search_toolbar
        search_toolbar.give_entry_focus()

    def __window_state_event_cb(self, window, event):
        logging.debug('window_state_event_cb %r', self)
        if event.changed_mask & gtk.gdk.WINDOW_STATE_ICONIFIED:
            state = event.new_window_state
            visible = not state & gtk.gdk.WINDOW_STATE_ICONIFIED
            self._list_view.set_is_visible(visible)

    def __visibility_notify_event_cb(self, window, event):
        logging.debug('visibility_notify_event_cb %r', self)
        visible = event.state != gtk.gdk.VISIBILITY_FULLY_OBSCURED
        self._list_view.set_is_visible(visible)

    def _check_available_space(self):
        """Check available space on device

            If the available space is below 50MB an alert will be
            shown which encourages to delete old journal entries.
        """

        if self._critical_space_alert:
            return
        stat = os.statvfs(env.get_profile_path())
        free_space = stat[statvfs.F_BSIZE] * stat[statvfs.F_BAVAIL]
        if free_space < _SPACE_TRESHOLD:
            self._critical_space_alert = ModalAlert()
            self._critical_space_alert.connect('destroy',
                                               self.__alert_closed_cb)
            self._critical_space_alert.show()

    def __alert_closed_cb(self, data):
        self.show_main_view()
        self.reveal()
        self._critical_space_alert = None

    def set_active_volume(self, mount):
        self._volumes_toolbar.set_active_volume(mount)

    def focus_search(self):
        """Become visible and give focus to the search entry
        """
        self.reveal()
        self.show_main_view()
        self.search_grab_focus()
コード例 #2
0
class JournalActivity(JournalWindow):
    def __init__(self):
        logging.debug("STARTUP: Loading the journal")
        JournalWindow.__init__(self)

        self.set_title(_("Journal"))

        self._main_view = None
        self._secondary_view = None
        self._list_view = None
        self._detail_view = None
        self._main_toolbox = None
        self._detail_toolbox = None
        self._volumes_toolbar = None

        self._setup_main_view()
        self._setup_secondary_view()

        self.add_events(gtk.gdk.ALL_EVENTS_MASK | gtk.gdk.VISIBILITY_NOTIFY_MASK)
        self._realized_sid = self.connect("realize", self.__realize_cb)
        self.connect("visibility-notify-event", self.__visibility_notify_event_cb)
        self.connect("window-state-event", self.__window_state_event_cb)
        self.connect("key-press-event", self._key_press_event_cb)
        self.connect("focus-in-event", self._focus_in_event_cb)

        model.created.connect(self.__model_created_cb)
        model.updated.connect(self.__model_updated_cb)
        model.deleted.connect(self.__model_deleted_cb)

        self._dbus_service = JournalActivityDBusService(self)

        self.iconify()

        self._critical_space_alert = None
        self._check_available_space()

    def __volume_error_cb(self, gobject, message, severity):
        alert = ErrorAlert(title=severity, msg=message)
        alert.connect("response", self.__alert_response_cb)
        self.add_alert(alert)
        alert.show()

    def __alert_response_cb(self, alert, response_id):
        self.remove_alert(alert)

    def __realize_cb(self, window):
        wm.set_bundle_id(window.window, _BUNDLE_ID)
        activity_id = activityfactory.create_activity_id()
        wm.set_activity_id(window.window, str(activity_id))
        self.disconnect(self._realized_sid)
        self._realized_sid = None

    def can_close(self):
        return False

    def _setup_main_view(self):
        self._main_toolbox = MainToolbox()
        self._main_view = gtk.VBox()

        self._list_view = ListView()
        self._list_view.connect("detail-clicked", self.__detail_clicked_cb)
        self._list_view.connect("clear-clicked", self.__clear_clicked_cb)
        self._list_view.connect("volume-error", self.__volume_error_cb)
        self._main_view.pack_start(self._list_view)
        self._list_view.show()

        self._volumes_toolbar = VolumesToolbar()
        self._volumes_toolbar.connect("volume-changed", self.__volume_changed_cb)
        self._volumes_toolbar.connect("volume-error", self.__volume_error_cb)
        self._main_view.pack_start(self._volumes_toolbar, expand=False)

        search_toolbar = self._main_toolbox.search_toolbar
        search_toolbar.connect("query-changed", self._query_changed_cb)
        search_toolbar.set_mount_point("/")

    def _setup_secondary_view(self):
        self._secondary_view = gtk.VBox()

        self._detail_toolbox = DetailToolbox()
        self._detail_toolbox.entry_toolbar.connect("volume-error", self.__volume_error_cb)

        self._detail_view = DetailView()
        self._detail_view.connect("go-back-clicked", self.__go_back_clicked_cb)
        self._secondary_view.pack_end(self._detail_view)
        self._detail_view.show()

    def _key_press_event_cb(self, widget, event):
        keyname = gtk.gdk.keyval_name(event.keyval)
        if keyname == "Escape":
            self.show_main_view()

    def __detail_clicked_cb(self, list_view, object_id):
        self._show_secondary_view(object_id)

    def __clear_clicked_cb(self, list_view):
        self._main_toolbox.search_toolbar.clear_query()

    def __go_back_clicked_cb(self, detail_view):
        self.show_main_view()

    def _query_changed_cb(self, toolbar, query):
        self._list_view.update_with_query(query)
        self.show_main_view()

    def show_main_view(self):
        if self.toolbar_box != self._main_toolbox:
            self.set_toolbar_box(self._main_toolbox)
            self._main_toolbox.show()

        if self.canvas != self._main_view:
            self.set_canvas(self._main_view)
            self._main_view.show()

    def _show_secondary_view(self, object_id):
        metadata = model.get(object_id)
        try:
            self._detail_toolbox.entry_toolbar.set_metadata(metadata)
        except Exception:
            logging.exception("Exception while displaying entry:")

        self.set_toolbar_box(self._detail_toolbox)
        self._detail_toolbox.show()

        try:
            self._detail_view.props.metadata = metadata
        except Exception:
            logging.exception("Exception while displaying entry:")

        self.set_canvas(self._secondary_view)
        self._secondary_view.show()

    def show_object(self, object_id):
        metadata = model.get(object_id)
        if metadata is None:
            return False
        else:
            self._show_secondary_view(object_id)
            return True

    def __volume_changed_cb(self, volume_toolbar, mount_point):
        logging.debug("Selected volume: %r.", mount_point)
        self._main_toolbox.search_toolbar.set_mount_point(mount_point)
        self._main_toolbox.set_current_toolbar(0)

    def __model_created_cb(self, sender, **kwargs):
        self._check_for_bundle(kwargs["object_id"])
        self._main_toolbox.search_toolbar.refresh_filters()
        self._check_available_space()

    def __model_updated_cb(self, sender, **kwargs):
        self._check_for_bundle(kwargs["object_id"])

        if self.canvas == self._secondary_view and kwargs["object_id"] == self._detail_view.props.metadata["uid"]:
            self._detail_view.refresh()

        self._check_available_space()

    def __model_deleted_cb(self, sender, **kwargs):
        if self.canvas == self._secondary_view and kwargs["object_id"] == self._detail_view.props.metadata["uid"]:
            self.show_main_view()

    def _focus_in_event_cb(self, window, event):
        self.search_grab_focus()
        self._list_view.update_dates()

    def _check_for_bundle(self, object_id):
        registry = bundleregistry.get_registry()

        metadata = model.get(object_id)
        if metadata.get("progress", "").isdigit():
            if int(metadata["progress"]) < 100:
                return

        bundle = misc.get_bundle(metadata)
        if bundle is None:
            return

        if registry.is_installed(bundle):
            logging.debug("_check_for_bundle bundle already installed")
            return

        if metadata["mime_type"] == JournalEntryBundle.MIME_TYPE:
            # JournalEntryBundle code takes over the datastore entry and
            # transforms it into the journal entry from the bundle -- we have
            # nothing more to do.
            try:
                registry.install(bundle, metadata["uid"])
            except (ZipExtractException, RegistrationException):
                logging.exception("Could not install bundle %s", bundle.get_path())
            return

        try:
            registry.install(bundle)
        except (ZipExtractException, RegistrationException):
            logging.exception("Could not install bundle %s", bundle.get_path())
            return

        metadata["bundle_id"] = bundle.get_bundle_id()
        model.write(metadata)

    def search_grab_focus(self):
        search_toolbar = self._main_toolbox.search_toolbar
        search_toolbar.give_entry_focus()

    def __window_state_event_cb(self, window, event):
        logging.debug("window_state_event_cb %r", self)
        if event.changed_mask & gtk.gdk.WINDOW_STATE_ICONIFIED:
            state = event.new_window_state
            visible = not state & gtk.gdk.WINDOW_STATE_ICONIFIED
            self._list_view.set_is_visible(visible)

    def __visibility_notify_event_cb(self, window, event):
        logging.debug("visibility_notify_event_cb %r", self)
        visible = event.state != gtk.gdk.VISIBILITY_FULLY_OBSCURED
        self._list_view.set_is_visible(visible)

    def _check_available_space(self):
        """Check available space on device

            If the available space is below 50MB an alert will be
            shown which encourages to delete old journal entries.
        """

        if self._critical_space_alert:
            return
        stat = os.statvfs(env.get_profile_path())
        free_space = stat[statvfs.F_BSIZE] * stat[statvfs.F_BAVAIL]
        if free_space < _SPACE_TRESHOLD:
            self._critical_space_alert = ModalAlert()
            self._critical_space_alert.connect("destroy", self.__alert_closed_cb)
            self._critical_space_alert.show()

    def __alert_closed_cb(self, data):
        self.show_main_view()
        self.reveal()
        self._critical_space_alert = None

    def set_active_volume(self, mount):
        self._volumes_toolbar.set_active_volume(mount)

    def focus_search(self):
        """Become visible and give focus to the search entry
        """
        self.reveal()
        self.show_main_view()
        self.search_grab_focus()