def _store_recent_changed_cb(self, combobox, *args):
        ''' Called when option "Store recently opened files" was changed. '''
        iter = combobox.get_active_iter()
        if not combobox.get_model().iter_is_valid(iter):
            return

        value = combobox.get_model().get_value(iter, 1)
        last_value = prefs['store recent file info']
        prefs['store recent file info'] = value
        self._window.filehandler.last_read_page.set_enabled(value)

        # If "Never" was selected, ask to purge recent files.
        if (bool(last_value) is True and value is False
                and (self._window.uimanager.recent.count() > 0
                     or self._window.filehandler.last_read_page.count() > 0)):

            dialog = message_dialog.MessageDialog(
                self,
                flags=Gtk.DialogFlags.MODAL,
                message_type=Gtk.MessageType.INFO,
                buttons=Gtk.ButtonsType.YES_NO)
            dialog.set_default_response(Gtk.ResponseType.YES)
            dialog.set_text(
                _('Delete information about recently opened files?'),
                _('This will remove all entries from the "Recent" menu,'
                  ' and clear information about last read pages.'))
            response = dialog.run()

            if response == Gtk.ResponseType.YES:
                self._window.uimanager.recent.remove_all()
                self._window.filehandler.last_read_page.clear_all()
    def show_replace_bookmark_dialog(self, old_bookmarks, new_page):
        """ Present a confirmation dialog to replace old bookmarks.
        @return RESPONSE_YES to create replace bookmarks,
            RESPONSE_NO to create a new bookmark, RESPONSE_CANCEL to abort creating
            a new bookmark. """
        dialog = message_dialog.MessageDialog(None, gtk.DIALOG_MODAL,
                                              gtk.MESSAGE_INFO)
        dialog.add_buttons(gtk.STOCK_YES, gtk.RESPONSE_YES, gtk.STOCK_NO,
                           gtk.RESPONSE_NO, gtk.STOCK_CANCEL,
                           gtk.RESPONSE_CANCEL)
        dialog.set_default_response(gtk.RESPONSE_YES)
        dialog.set_should_remember_choice('replace-existing-bookmark',
                                          (gtk.RESPONSE_YES, gtk.RESPONSE_NO))

        pages = map(str,
                    sorted(map(operator.attrgetter('_page'), old_bookmarks)))
        dialog.set_text(
            i18n.get_translation().ungettext(
                'Replace existing bookmark on page %s?',
                'Replace existing bookmarks on pages %s?', len(pages)) %
            ", ".join(pages),
            _('The current book already contains marked pages. '
              'Do you want to replace them with a new bookmark on page %d? ') %
            new_page + '\n\n' +
            _('Selecting "No" will create a new bookmark without affecting the other bookmarks.'
              ))

        return dialog.run()
Beispiel #3
0
def ask_for_password(archive):
    """ Openes an input dialog to ask for a password. Returns either
    an Unicode string (the password), or None."""
    dialog = message_dialog.MessageDialog(None, gtk.DIALOG_MODAL,
                                          gtk.MESSAGE_QUESTION,
                                          gtk.BUTTONS_OK_CANCEL)
    dialog.set_text(
        _("The archive is password-protected:"),
        archive + '\n\n' + ("Please enter the password to continue:"))
    dialog.set_default_response(gtk.RESPONSE_OK)
    dialog.set_auto_destroy(False)

    password_box = gtk.Entry()
    password_box.set_visibility(False)
    password_box.set_activates_default(True)
    dialog.get_content_area().pack_end(password_box)
    dialog.set_focus(password_box)

    result = dialog.run()
    password = password_box.get_text()
    dialog.destroy()

    if result == gtk.RESPONSE_OK and password:
        return password.decode('utf-8')
    else:
        return None
Beispiel #4
0
    def add_collection(self, *args):
        """Add a new collection to the library, through a dialog."""
        add_dialog = message_dialog.MessageDialog(self._library, 0,
                                                  Gtk.MessageType.INFO,
                                                  Gtk.ButtonsType.OK_CANCEL)
        add_dialog.set_auto_destroy(False)
        add_dialog.set_default_response(Gtk.ResponseType.OK)
        add_dialog.set_text(_('Add new collection?'),
                            _('Please enter a name for the new collection.'))

        box = Gtk.HBox()  # To get nice line-ups with the padding.
        add_dialog.vbox.pack_start(box, True, True, 0)
        entry = Gtk.Entry()
        entry.set_activates_default(True)
        box.pack_start(entry, True, True, 6)
        box.show_all()

        response = add_dialog.run()
        name = entry.get_text().decode('utf-8')
        add_dialog.destroy()
        if response == Gtk.ResponseType.OK and name:
            if self._library.backend.add_collection(name):
                collection = self._library.backend.get_collection_by_name(name)
                prefs['last library collection'] = collection.id
                self._library.collection_area.display_collections()
            else:
                message = _("Could not add a new collection called '%s'.") % (
                    name)
                if (self._library.backend.get_collection_by_name(name)
                        is not None):
                    message = '%s %s' % (
                        message,
                        _('A collection by that name already exists.'))
                self._library.set_status_message(message)
Beispiel #5
0
    def show_replace_bookmark_dialog(self, old_bookmarks, new_page):
        ''' Present a confirmation dialog to replace old bookmarks.
        @return RESPONSE_YES to create replace bookmarks,
            RESPONSE_NO to create a new bookmark, RESPONSE_CANCEL to abort creating
            a new bookmark. '''
        dialog = message_dialog.MessageDialog(
            self._window,
            flags=Gtk.DialogFlags.MODAL,
            message_type=Gtk.MessageType.INFO,
            buttons=Gtk.ButtonsType.NONE)
        dialog.add_buttons(Gtk.STOCK_YES, Gtk.ResponseType.YES, Gtk.STOCK_NO,
                           Gtk.ResponseType.NO, Gtk.STOCK_CANCEL,
                           Gtk.ResponseType.CANCEL)
        dialog.set_default_response(Gtk.ResponseType.YES)
        dialog.set_should_remember_choice(
            'replace-existing-bookmark',
            (Gtk.ResponseType.YES, Gtk.ResponseType.NO))

        pages = map(str,
                    sorted(map(operator.attrgetter('_page'), old_bookmarks)))
        dialog.set_text(
            i18n.get_translation().ngettext(
                'Replace existing bookmark on page %s?',
                'Replace existing bookmarks on pages %s?', len(list(pages))) %
            ', '.join(pages),
            _('The current book already contains marked pages. '
              'Do you want to replace them with a new bookmark on page %d? ') %
            new_page + '\n\n' +
            _('Selecting "No" will create a new bookmark without affecting the other bookmarks.'
              ))

        return dialog.run()
Beispiel #6
0
    def _ask_goto_last_read_page(self, path, last_read_page):
        """ If the user read an archive previously, ask to continue from
        that time, or from page 1. This method returns a page index, that is,
        index + 1. """

        read_date = self.last_read_page.get_date(path)

        dialog = message_dialog.MessageDialog(self._window, gtk.DIALOG_MODAL,
                                              gtk.MESSAGE_INFO,
                                              gtk.BUTTONS_YES_NO)
        dialog.set_default_response(gtk.RESPONSE_YES)
        dialog.set_should_remember_choice('resume-from-last-read-page',
                                          (gtk.RESPONSE_YES, gtk.RESPONSE_NO))
        dialog.set_text(
            (_('Continue reading from page %d?') % last_read_page),
            _('You stopped reading here on %(date)s, %(time)s. '
              'If you choose "Yes", reading will resume on page %(page)d. Otherwise, '
              'the first page will be loaded.') % {
                  'date': read_date.date().strftime("%x"),
                  'time': read_date.time().strftime("%X"),
                  'page': last_read_page
              })
        result = dialog.run()

        return result == gtk.RESPONSE_YES
Beispiel #7
0
def ask_for_password(archive):
    if not tools.use_gui():
        return None
    """ Openes an input dialog to ask for a password. Returns either
    an Unicode string (the password), or None."""
    dialog = message_dialog.MessageDialog(
        main.main_window(),
        flags=Gtk.DialogFlags.MODAL,
        message_type=Gtk.MessageType.QUESTION,
        buttons=Gtk.ButtonsType.OK_CANCEL)
    dialog.set_text(
        _("The archive is password-protected:"),
        archive + '\n\n' +
        ("Please enter the password to continue:"))
    dialog.set_default_response(Gtk.ResponseType.OK)
    dialog.set_auto_destroy(False)

    password_box = Gtk.Entry()
    password_box.set_visibility(False)
    password_box.set_activates_default(True)
    dialog.get_content_area().pack_end(password_box, True, True, 0)
    dialog.set_focus(password_box)

    result = dialog.run()
    password = password_box.get_text()
    dialog.destroy()

    if result == Gtk.ResponseType.OK and password:
        return password
    else:
        return None
    def _ask_goto_last_read_page(self, path, last_read_page):
        ''' If the user read an archive previously, ask to continue from
        that time, or from page 1. This method returns a page index, that is,
        index + 1. '''

        read_date = self.last_read_page.get_date(path)

        dialog = message_dialog.MessageDialog(
            self._window,
            flags=Gtk.DialogFlags.MODAL,
            message_type=Gtk.MessageType.INFO,
            buttons=Gtk.ButtonsType.YES_NO)
        dialog.set_default_response(Gtk.ResponseType.YES)
        dialog.set_should_remember_choice(
            'resume-from-last-read-page',
            (Gtk.ResponseType.YES, Gtk.ResponseType.NO))
        dialog.set_text(
            (_('Continue reading from page %d?') % last_read_page),
            _('You stopped reading here on %(date)s, %(time)s. '
              'If you choose "Yes", reading will resume on page %(page)d. Otherwise, '
              'the first page will be loaded.') % {
                  'date': read_date.date().strftime("%x"),
                  'time': read_date.time().strftime('%X'),
                  'page': last_read_page
              })
        result = dialog.run()

        return result == Gtk.ResponseType.YES
    def _response(self, widget, response):
        '''Return a list of the paths of the chosen files, or None if the
        event only changed the current directory.
        '''
        if response == Gtk.ResponseType.OK:
            if not self.filechooser.get_filenames():
                return

            # Collect files, if necessary also from subdirectories
            filter = self.filechooser.get_filter()
            paths = []
            for path in self.filechooser.get_filenames():

                if os.path.isdir(path):
                    subdir_files = list(
                        self.collect_files_from_subdir(
                            path, filter, self.should_open_recursive()))
                    file_provider.FileProvider.sort_files(subdir_files)
                    paths.extend(subdir_files)
                else:
                    paths.append(path)

            # FileChooser.set_do_overwrite_confirmation() doesn't seem to
            # work on our custom dialog, so we use a simple alternative.
            first_path = self.filechooser.get_filenames()[0]
            if (self._action == Gtk.FileChooserAction.SAVE
                    and not os.path.isdir(first_path)
                    and os.path.exists(first_path)):

                overwrite_dialog = message_dialog.MessageDialog(
                    self,
                    flags=0,
                    message_type=Gtk.MessageType.QUESTION,
                    buttons=Gtk.ButtonsType.OK_CANCEL)
                overwrite_dialog.set_text(
                    _('A file named "%s" already exists. Do you want to replace it?'
                      ) % os.path.basename(first_path),
                    _('Replacing it will overwrite its contents.'))
                response = overwrite_dialog.run()

                if response != Gtk.ResponseType.OK:
                    self.stop_emission_by_name('response')
                    return

            # Do not store path if the user chose not to keep a file history
            if prefs['store recent file info']:
                prefs['path of last browsed in filechooser'] = \
                    self.filechooser.get_current_folder()
            else:
                prefs['path of last browsed in filechooser'] = \
                    constants.HOME_DIR

            self.__class__._last_activated_file = first_path
            self.files_chosen(paths)

        else:
            self.files_chosen([])

        self._destroyed = True
Beispiel #10
0
    def _pack_archive(self, archive_path):
        """Create a new archive with the chosen files."""
        self.set_sensitive(False)
        self._window.set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH))

        while gtk.events_pending():
            gtk.main_iteration_do(False)

        image_files = self._image_area.get_file_listing()
        comment_files = self._comment_area.get_file_listing()

        try:
            fd, tmp_path = tempfile.mkstemp(
                suffix='.%s' % os.path.basename(archive_path),
                prefix='tmp.', dir=os.path.dirname(archive_path))
            # Close open tempfile handle (writing is handled by the packer)
            os.close(fd)
            fail = False

        except:
            fail = True

        if not fail:
            packer = archive_packer.Packer(image_files, comment_files, tmp_path,
                os.path.splitext(os.path.basename(archive_path))[0])
            packer.pack()
            packing_success = packer.wait()

            if packing_success:
                # Preserve permissions if currently edited files come from an archive
                if (self._window.filehandler.archive_type is not None and
                    os.path.exists(self._window.filehandler.get_path_to_base())):
                    mode = os.stat(self._window.filehandler.get_path_to_base()).st_mode
                else:
                    mode = os.stat(tmp_path).st_mode

                # Remove existing file (Win32 fails on rename otherwise)
                if os.path.exists(archive_path):
                    os.unlink(archive_path)

                os.rename(tmp_path, archive_path)
                os.chmod(archive_path, mode)

                _close_dialog()
            else:
                fail = True
        
        self._window.set_cursor(None)
        if fail:
            dialog = message_dialog.MessageDialog(self._window, 0, gtk.MESSAGE_ERROR,
                gtk.BUTTONS_CLOSE)
            dialog.set_text(
                _("The new archive could not be saved!"),
                _("The original files have not been removed."))
            dialog.run()

            self.set_sensitive(True)
Beispiel #11
0
    def _response(self, widget, response):
        """Return a list of the paths of the chosen files, or None if the
        event only changed the current directory.
        """
        if response == gtk.RESPONSE_OK:
            if not self.filechooser.get_filenames():
                return

            # Collect files, if necessary also from subdirectories
            filter = self.filechooser.get_filter()
            paths = []
            for path in self.filechooser.get_filenames():
                path = path.decode('utf-8')

                if os.path.isdir(path):
                    subdir_files = list(
                        self.collect_files_from_subdir(
                            path, filter, self.should_open_recursive()))
                    file_provider.FileProvider.sort_files(subdir_files)
                    paths.extend(subdir_files)
                else:
                    paths.append(path)

            # FileChooser.set_do_overwrite_confirmation() doesn't seem to
            # work on our custom dialog, so we use a simple alternative.
            first_path = self.filechooser.get_filenames()[0].decode('utf-8')
            if (self._action == gtk.FILE_CHOOSER_ACTION_SAVE
                    and not os.path.isdir(first_path)
                    and os.path.exists(first_path)):

                overwrite_dialog = message_dialog.MessageDialog(
                    None, 0, gtk.MESSAGE_QUESTION, gtk.BUTTONS_OK_CANCEL)
                overwrite_dialog.set_text(
                    _("A file named '%s' already exists. Do you want to replace it?"
                      ) % os.path.basename(first_path),
                    _('Replacing it will overwrite its contents.'))
                response = overwrite_dialog.run()

                if response != gtk.RESPONSE_OK:
                    self.emit_stop_by_name('response')
                    return

            # Do not store path if the user chose not to keep a file history
            if prefs['store recent file info']:
                prefs['path of last browsed in filechooser'] = \
                    self.filechooser.get_current_folder()
            else:
                prefs['path of last browsed in filechooser'] = \
                    constants.HOME_DIR

            self.__class__._last_activated_file = first_path
            self.files_chosen(paths)

        else:
            self.files_chosen([])

        self._destroyed = True
Beispiel #12
0
    def _book_size_changed(self, old, current):
        ''' Called when library cover size changes. '''
        old_size = prefs['library cover size']
        name = current.get_name()
        if name == 'huge':
            prefs['library cover size'] = constants.SIZE_HUGE
        elif name == 'large':
            prefs['library cover size'] = constants.SIZE_LARGE
        elif name == 'normal':
            prefs['library cover size'] = constants.SIZE_NORMAL
        elif name == 'small':
            prefs['library cover size'] = constants.SIZE_SMALL
        elif name == 'tiny':
            prefs['library cover size'] = constants.SIZE_TINY
        elif name == 'custom':
            dialog = message_dialog.MessageDialog(
                self._library,
                flags=Gtk.DialogFlags.DESTROY_WITH_PARENT,
                message_type=Gtk.MessageType.INFO,
                buttons=Gtk.ButtonsType.OK)
            dialog.set_auto_destroy(False)
            dialog.set_text(_('Set library cover size'))

            # Add adjustment scale
            adjustment = Gtk.Adjustment(value=prefs['library cover size'],
                                        lower=20,
                                        upper=constants.MAX_LIBRARY_COVER_SIZE,
                                        step_increment=10,
                                        page_increment=25)
            cover_size_scale = Gtk.HScale(adjustment=adjustment)
            cover_size_scale.set_size_request(200, -1)
            cover_size_scale.set_digits(0)
            cover_size_scale.set_draw_value(True)
            cover_size_scale.set_value_pos(Gtk.PositionType.LEFT)
            for mark in (constants.SIZE_HUGE, constants.SIZE_LARGE,
                         constants.SIZE_NORMAL, constants.SIZE_SMALL,
                         constants.SIZE_TINY):
                cover_size_scale.add_mark(mark, Gtk.PositionType.TOP, None)

            dialog.get_message_area().pack_end(cover_size_scale, True, True, 0)
            response = dialog.run()
            size = int(adjustment.get_value())
            dialog.destroy()

            if response == Gtk.ResponseType.OK:
                prefs['library cover size'] = size

        if prefs['library cover size'] != old_size:
            self._cache.clear()
            collection = self._library.collection_area.get_current_collection()
            GLib.idle_add(self.display_covers, collection)
Beispiel #13
0
    def delete(self, *args):
        ''' The currently opened file/archive will be deleted after showing
        a confirmation dialog. '''

        current_file = self.imagehandler.get_real_path()
        dialog = message_dialog.MessageDialog(
            parent=self,
            flags=Gtk.DialogFlags.MODAL,
            message_type=Gtk.MessageType.QUESTION,
            buttons=Gtk.ButtonsType.NONE)
        dialog.add_buttons(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
                           Gtk.STOCK_DELETE, Gtk.ResponseType.OK)
        dialog.set_default_response(Gtk.ResponseType.OK)
        dialog.set_should_remember_choice('delete-opend-file',
                                          (Gtk.ResponseType.OK, ))
        dialog.set_text(
            _('Delete "%s"?') % os.path.basename(current_file),
            _('The file will be permanently deleted from your drive.'))
        result = dialog.run()

        if result == Gtk.ResponseType.OK:
            # Go to next page/archive, and delete current file
            if self.filehandler.archive_type is not None:
                self.filehandler.last_read_page.clear_page(current_file)

                next_opened = self.filehandler._open_next_archive()
                if not next_opened:
                    next_opened = self.filehandler._open_previous_archive()
                if not next_opened:
                    self.filehandler.close_file()

                if os.path.isfile(current_file):
                    os.unlink(current_file)
            else:
                if self.imagehandler.get_number_of_pages() > 1:
                    # Open the next/previous file
                    if self.imagehandler.get_current_page(
                    ) >= self.imagehandler.get_number_of_pages():
                        self.flip_page(-1)
                    else:
                        self.flip_page(+1)
                    # Unlink the desired file
                    if os.path.isfile(current_file):
                        os.unlink(current_file)
                    # Refresh the directory
                    self.filehandler.refresh_file()
                else:
                    self.filehandler.close_file()
                    if os.path.isfile(current_file):
                        os.unlink(current_file)
Beispiel #14
0
    def _book_size_changed(self, old, current):
        """ Called when library cover size changes. """
        old_size = prefs['library cover size']
        name = current.get_name()
        if name == 'huge':
            prefs['library cover size'] = constants.SIZE_HUGE
        elif name == 'large':
            prefs['library cover size'] = constants.SIZE_LARGE
        elif name == 'normal':
            prefs['library cover size'] = constants.SIZE_NORMAL
        elif name == 'small':
            prefs['library cover size'] = constants.SIZE_SMALL
        elif name == 'tiny':
            prefs['library cover size'] = constants.SIZE_TINY
        elif name == 'custom':
            dialog = message_dialog.MessageDialog(
                self._library,
                gtk.DIALOG_DESTROY_WITH_PARENT,
                gtk.MESSAGE_INFO,
                buttons=gtk.BUTTONS_OK)
            dialog.set_auto_destroy(False)
            dialog.set_text(_('Set library cover size'))

            # Add adjustment scale
            adjustment = gtk.Adjustment(prefs['library cover size'], 20,
                                        constants.MAX_LIBRARY_COVER_SIZE, 10,
                                        25, 0)
            cover_size_scale = gtk.HScale(adjustment)
            cover_size_scale.set_size_request(200, -1)
            cover_size_scale.set_digits(0)
            cover_size_scale.set_draw_value(True)
            cover_size_scale.set_value_pos(gtk.POS_LEFT)
            for mark in (constants.SIZE_HUGE, constants.SIZE_LARGE,
                         constants.SIZE_NORMAL, constants.SIZE_SMALL,
                         constants.SIZE_TINY):
                cover_size_scale.add_mark(mark, gtk.POS_TOP, None)

            dialog.get_message_area().pack_end(cover_size_scale)
            response = dialog.run()
            size = int(adjustment.get_value())
            dialog.destroy()

            if response == gtk.RESPONSE_OK:
                prefs['library cover size'] = size

        if prefs['library cover size'] != old_size:
            self._cache.invalidate_all()
            collection = self._library.collection_area.get_current_collection()
            gobject.idle_add(self.display_covers, collection)
Beispiel #15
0
    def _completely_remove_book(self, request_response=True, *args):
        '''Remove the currently selected books from the library and the
        hard drive.
        '''

        if request_response:

            choice_dialog = message_dialog.MessageDialog(
                self._library,
                flags=Gtk.DialogFlags.MODAL,
                message_type=Gtk.MessageType.QUESTION,
                buttons=Gtk.ButtonsType.NONE)
            choice_dialog.add_buttons(Gtk.STOCK_CANCEL,
                                      Gtk.ResponseType.CANCEL,
                                      Gtk.STOCK_DELETE, Gtk.ResponseType.OK)
            choice_dialog.set_default_response(Gtk.ResponseType.OK)
            choice_dialog.set_should_remember_choice(
                'library-remove-book-from-disk', (Gtk.ResponseType.OK, ))
            choice_dialog.set_text(
                _('Delete selected books?'),
                _('The selected books will be permanently deleted from your drive.'
                  ))
            response = choice_dialog.run()

        # if no request is needed or the user has told us they definitely want to delete the book
        if not request_response or (request_response
                                    and response == Gtk.ResponseType.OK):

            # get the array of currently selected books in the book window
            selected_books = self._iconview.get_selected_items()
            book_ids = [self.get_book_at_path(book) for book in selected_books]
            paths = [
                self._library.backend.get_book_path(book_id)
                for book_id in book_ids
            ]

            # Remove books from library
            self._remove_books_from_library()

            # Remove from the harddisk
            for book_path in paths:
                try:
                    # try to delete the book.
                    # this can throw an exception if the path points to folder instead
                    # of a single file
                    os.remove(book_path)
                except Exception:
                    log.error(_('! Could not remove file "%s"'), book_path)
Beispiel #16
0
    def delete(self, *args):
        """ The currently opened file/archive will be deleted after showing
        a confirmation dialog. """

        current_file = self.imagehandler.get_real_path()
        dialog = message_dialog.MessageDialog(None, gtk.DIALOG_MODAL,
                                              gtk.MESSAGE_QUESTION,
                                              gtk.BUTTONS_NONE)
        dialog.set_should_remember_choice('delete-opend-file',
                                          (gtk.RESPONSE_OK, ))
        dialog.set_text(
            _('Delete "%s"?') % os.path.basename(current_file),
            _('The file will be deleted from your harddisk.'))
        dialog.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)
        dialog.add_button(gtk.STOCK_DELETE, gtk.RESPONSE_OK)
        dialog.set_default_response(gtk.RESPONSE_OK)
        result = dialog.run()

        if result == gtk.RESPONSE_OK:
            # Go to next page/archive, and delete current file
            if self.filehandler.archive_type is not None:
                self.filehandler.last_read_page.clear_page(current_file)

                next_opened = self.filehandler._open_next_archive()
                if not next_opened:
                    next_opened = self.filehandler._open_previous_archive()
                if not next_opened:
                    self.filehandler.close_file()

                if os.path.isfile(current_file):
                    os.unlink(current_file)
            else:
                if self.imagehandler.get_number_of_pages() > 1:
                    # Open the next/previous file
                    if self.imagehandler.get_current_page(
                    ) >= self.imagehandler.get_number_of_pages():
                        self.previous_page()
                    else:
                        self.next_page()
                    # Unlink the desired file
                    if os.path.isfile(current_file):
                        os.unlink(current_file)
                    # Refresh the directory
                    self.filehandler.refresh_file()
                else:
                    self.filehandler.close_file()
                    if os.path.isfile(current_file):
                        os.unlink(current_file)
Beispiel #17
0
    def _completely_remove_book(self, request_response=True, *args):
        """Remove the currently selected books from the library and the
        hard drive.
        """

        if request_response:

            choice_dialog = message_dialog.MessageDialog(
                self._library, 0, Gtk.MessageType.QUESTION,
                Gtk.ButtonsType.YES_NO)
            choice_dialog.set_default_response(Gtk.ResponseType.YES)
            choice_dialog.set_should_remember_choice(
                'library-remove-book-from-disk', (Gtk.ResponseType.YES, ))
            choice_dialog.set_text(
                _('Remove books from the library?'),
                _('The selected books will be removed from the library and '
                  'permanently deleted. Are you sure that you want to continue?'
                  ))
            response = choice_dialog.run()

        # if no request is needed or the user has told us they definitely want to delete the book
        if not request_response or (request_response
                                    and response == Gtk.ResponseType.YES):

            # get the array of currently selected books in the book window
            selected_books = self._iconview.get_selected_items()
            book_ids = [self.get_book_at_path(book) for book in selected_books]
            paths = [
                self._library.backend.get_book_path(book_id)
                for book_id in book_ids
            ]

            # Remove books from library
            self._remove_books_from_library()

            # Remove from the harddisk
            for book_path in paths:
                try:
                    # try to delete the book.
                    # this can throw an exception if the path points to folder instead
                    # of a single file
                    os.remove(book_path)
                except Exception:
                    log.error(_('! Could not remove file "%s"'), book_path)
Beispiel #18
0
    def _response(self, dialog, response):
        if response == Gtk.ResponseType.ACCEPT:
            # The Save button is only enabled if all commands are valid
            self.save()
            self.hide()
        else:
            if self._changed:
                confirm_diag = message_dialog.MessageDialog(
                    self, Gtk.DialogFlags.MODAL, Gtk.MessageType.INFO,
                    Gtk.ButtonsType.YES_NO)
                confirm_diag.set_text(
                    _('Save changes to commands?'),
                    _('You have made changes to the list of external commands that '
                      'have not been saved yet. Press "Yes" to save all changes, '
                      'or "No" to discard them.'))
                response = confirm_diag.run()

                if response == Gtk.ResponseType.YES:
                    self.save()
Beispiel #19
0
    def _response(self, dialog, response):
        if response == gtk.RESPONSE_ACCEPT:
            # The Save button is only enabled if all commands are valid
            self.save()
            self.hide_all()
        else:
            if self._changed:
                confirm_diag = message_dialog.MessageDialog(
                    self, gtk.DIALOG_MODAL, gtk.MESSAGE_INFO,
                    gtk.BUTTONS_YES_NO)
                confirm_diag.set_text(
                    _('Save changes to commands?'),
                    _('You have made changes to the list of external commands that '
                      'have not been saved yet. Press "Yes" to save all changes, '
                      'or "No" to discard them.'))
                response = confirm_diag.run()

                if response == gtk.RESPONSE_YES:
                    self.save()
Beispiel #20
0
    def _rename_collection(self, action):
        '''Rename the currently selected collection, using a dialog.'''
        collection = self.get_current_collection()
        try:
            old_name = self._library.backend.get_collection_name(collection)
        except Exception:
            return
        rename_dialog = message_dialog.MessageDialog(
            self._library,
            flags=0,
            message_type=Gtk.MessageType.INFO,
            buttons=Gtk.ButtonsType.OK_CANCEL)
        rename_dialog.set_auto_destroy(False)
        rename_dialog.set_text(
            _('Rename collection?'),
            _('Please enter a new name for the selected collection.'))
        rename_dialog.set_default_response(Gtk.ResponseType.OK)

        box = Gtk.HBox()  # To get nice line-ups with the padding.
        rename_dialog.vbox.pack_start(box, True, True, 0)
        entry = Gtk.Entry()
        entry.set_text(old_name)
        entry.set_activates_default(True)
        box.pack_start(entry, True, True, 6)
        box.show_all()

        response = rename_dialog.run()
        new_name = entry.get_text()
        rename_dialog.destroy()
        if response == Gtk.ResponseType.OK and new_name:
            if self._library.backend.rename_collection(collection, new_name):
                self.display_collections()
            else:
                message = _('Could not change the name to "%s".') % new_name
                if (self._library.backend.get_collection_by_name(new_name)
                        is not None):
                    message = '%s %s' % (
                        message,
                        _('A collection by that name already exists.'))
                self._library.set_status_message(message)
Beispiel #21
0
    def _get_last_read_page(self, path):
        """ If the user read an archive previously, ask to continue from
        that time, or from page 1. This method returns a page index, that is,
        index + 1. """
        if (isinstance(path, list) and len(path) > 0
                and isinstance(path[0], (str, unicode))):
            path = path[0]

        last_read_page = self.last_read_page.get_page(path)
        if last_read_page is not None:
            read_date = self.last_read_page.get_date(path)

            dialog = message_dialog.MessageDialog(self._window,
                                                  gtk.DIALOG_MODAL,
                                                  gtk.MESSAGE_INFO,
                                                  gtk.BUTTONS_YES_NO)
            dialog.set_should_remember_choice(
                'resume-from-last-read-page',
                (gtk.RESPONSE_YES, gtk.RESPONSE_NO))
            dialog.set_text(
                (_('Continue reading from page %d?') % last_read_page),
                _('You stopped reading here on %(date)s, %(time)s. '
                  'If you choose "Yes", reading will resume on page %(page)d. Otherwise, '
                  'the first page will be loaded.') % {
                      'date': read_date.date().strftime("%x"),
                      'time': read_date.time().strftime("%X"),
                      'page': last_read_page
                  })
            result = dialog.run()

            self._must_call_draw = True

            if result == gtk.RESPONSE_YES:
                return last_read_page
            else:
                return 1
        else:
            return 1
Beispiel #22
0
    def _rename_collection(self, action):
        """Rename the currently selected collection, using a dialog."""
        collection = self.get_current_collection()
        try:
            old_name = self._library.backend.get_collection_name(collection)
        except Exception:
            return
        rename_dialog = message_dialog.MessageDialog(self._library, 0,
                                                     gtk.MESSAGE_INFO,
                                                     gtk.BUTTONS_OK_CANCEL)
        rename_dialog.set_auto_destroy(False)
        rename_dialog.set_text(
            _('Rename collection?'),
            _('Please enter a new name for the selected collection.'))
        rename_dialog.set_default_response(gtk.RESPONSE_OK)

        box = gtk.HBox()  # To get nice line-ups with the padding.
        rename_dialog.vbox.pack_start(box)
        entry = gtk.Entry()
        entry.set_text(old_name)
        entry.set_activates_default(True)
        box.pack_start(entry, True, True, 6)
        box.show_all()

        response = rename_dialog.run()
        new_name = entry.get_text()
        rename_dialog.destroy()
        if response == gtk.RESPONSE_OK and new_name:
            if self._library.backend.rename_collection(collection, new_name):
                self.display_collections()
            else:
                message = _("Could not change the name to '%s'.") % new_name
                if (self._library.backend.get_collection_by_name(new_name)
                        is not None):
                    message = '%s %s' % (
                        message,
                        _('A collection by that name already exists.'))
                self._library.set_status_message(message)