def __get_file_filter(self, files): """ Determines what kind of files should be filtered in the given list of <files>. Returns either a filter accepting only images, or only archives, depending on what type of file is found first in the list. """ for file in files: if os.path.isfile(file) and image_tools.is_image_file(file): return lambda file: \ image_tools.is_image_file(file) elif os.path.isfile(file) and constants.SUPPORTED_ARCHIVE_REGEX.search(file, re.I) is not None: return lambda file: \ constants.SUPPORTED_ARCHIVE_REGEX.search(file, re.I) is not None # Default filter only accepts images. return lambda file: image_tools.is_image_file(file)
def list_files(self, mode=FileProvider.IMAGES): """ Lists all files in the current directory. Returns a list of absolute paths, already sorted. """ if mode == FileProvider.IMAGES: should_accept = lambda file: image_tools.is_image_file(file) elif mode == FileProvider.ARCHIVES: should_accept = lambda file: \ archive_tools.get_supported_archive_regex().search(file, re.I) is not None else: should_accept = lambda file: True try: files = [ os.path.join(self.base_dir, filename) for filename in # Explicitly convert all files to Unicode, even when # os.listdir returns a mixture of byte/unicode strings. # (MComix bug #3424405) [i18n.to_unicode(fn) for fn in os.listdir(self.base_dir)] if should_accept(os.path.join(self.base_dir, filename)) ] FileProvider.sort_files(files) return files except OSError: log.warning(u'! ' + _('Could not open %s: Permission denied.'), self.base_dir) return []
def _guess_cover(self, files): '''Return the filename within <files> that is the most likely to be the cover of an archive using some simple heuristics. ''' # Ignore MacOSX meta files. files = filter( lambda filename: '__MACOSX' not in os.path.normpath(filename). split(os.sep), files) # Ignore credit files if possible. files = filter( lambda filename: 'credit' not in os.path.split(filename)[1].lower( ), files) images = [f for f in files if image_tools.is_image_file(f)] tools.alphanumeric_sort(images) front_re = re.compile('(cover|front)', re.I) candidates = filter(front_re.search, images) candidates = [c for c in candidates if 'back' not in c.lower()] if candidates: return candidates[0] if images: return images[0] return None
def list_files(self, mode=FileProvider.IMAGES): """ Lists all files in the current directory. Returns a list of absolute paths, already sorted. """ if mode == FileProvider.IMAGES: should_accept = lambda file: image_tools.is_image_file(file) elif mode == FileProvider.ARCHIVES: should_accept = lambda file: \ archive_tools.get_supported_archive_regex().search(file, re.I) is not None else: should_accept = lambda file: True try: files = [ os.path.join(self.base_dir, filename) for filename in # Explicitly convert all files to Unicode, even when # os.listdir returns a mixture of byte/unicode strings. # (MComix bug #3424405) [ i18n.to_unicode(fn) for fn in os.listdir(self.base_dir) ] if should_accept(os.path.join(self.base_dir, filename)) ] FileProvider.sort_files(files) return files except OSError: log.warning(u'! ' + _('Could not open %s: Permission denied.'), self.base_dir) return []
def _listed_contents(self, archive, files): if not self.file_loading: return self.file_loading = False files = self._extractor.get_files() archive_images = [ image for image in files if image_tools.is_image_file(image) # Remove MacOS meta files from image list and not '__MACOSX' in os.path.normpath(image).split(os.sep) ] self._sort_archive_images(archive_images) image_files = [os.path.join(self._tmp_dir, f) for f in archive_images] comment_files = list(filter(self._comment_re.search, files)) tools.alphanumeric_sort(comment_files) self._comment_files = [ os.path.join(self._tmp_dir, f) for f in comment_files ] self._name_table = dict(zip(image_files, archive_images)) self._name_table.update(zip(self._comment_files, comment_files)) self._extractor.set_files(archive_images + comment_files) self._archive_opened(image_files)
def _listed_contents(self, archive, files): if not self.file_loading: return self.file_loading = False files = self._extractor.get_files() archive_images = [image for image in files if image_tools.is_image_file(image) # Remove MacOS meta files from image list and not u'__MACOSX' in os.path.normpath(image).split(os.sep)] self._sort_archive_images(archive_images) image_files = [ os.path.join(self._tmp_dir, f) for f in archive_images ] comment_files = filter(self._comment_re.search, files) tools.alphanumeric_sort(comment_files) self._comment_files = [ os.path.join(self._tmp_dir, f) for f in comment_files ] self._name_table = dict(zip(image_files, archive_images)) self._name_table.update(zip(self._comment_files, comment_files)) self._extractor.set_files(archive_images + comment_files) self._archive_opened(image_files)
def __get_file_filter(self, files): """ Determines what kind of files should be filtered in the given list of <files>. Returns either a filter accepting only images, or only archives, depending on what type of file is found first in the list. """ for file in files: if os.path.isfile(file) and image_tools.is_image_file(file): return lambda file: \ image_tools.is_image_file(file) elif (os.path.isfile(file) and archive_tools.get_supported_archive_regex().search(file, re.I) is not None): return lambda file: \ archive_tools.get_supported_archive_regex().search(file, re.I) is not None # Default filter only accepts images. return lambda file: image_tools.is_image_file(file)
def __get_file_filter(self, files): """ Determines what kind of files should be filtered in the given list of <files>. Returns either a filter accepting only images, or only archives, depending on what type of file is found first in the list. """ for file in files: if os.path.isfile(file) and image_tools.is_image_file(file): return lambda file: \ image_tools.is_image_file(file) elif (os.path.isfile(file) and archive_tools.get_supported_archive_regex().search( file, re.I) is not None): return lambda file: \ archive_tools.get_supported_archive_regex().search(file, re.I) is not None # Default filter only accepts images. return lambda file: image_tools.is_image_file(file)
def __get_file_filter(self, files): """ Determines what kind of files should be filtered in the given list of <files>. Returns either a filter accepting only images, or only archives, depending on what type of file is found first in the list. """ for file in files: if os.path.isfile(file) and image_tools.is_image_file(file): return lambda file: \ image_tools.is_image_file(file) elif os.path.isfile( file) and constants.SUPPORTED_ARCHIVE_REGEX.search( file, re.I) is not None: return lambda file: \ constants.SUPPORTED_ARCHIVE_REGEX.search(file, re.I) is not None # Default filter only accepts images. return lambda file: image_tools.is_image_file(file)
def _create_thumbnail_pixbuf(self, filepath): """ Creates a thumbnail pixbuf from <filepath>, and returns it as a tuple along with a file metadata dictionary: (pixbuf, tEXt_data) """ if archive_tools.archive_mime_type(filepath) is not None: extractor = archive_extractor.Extractor() tmpdir = tempfile.mkdtemp(prefix=u'mcomix_archive_thumb.') condition = extractor.setup(filepath, tmpdir) files = extractor.get_files() wanted = self._guess_cover(files) if wanted: extractor.set_files([wanted]) extractor.extract() image_path = os.path.join(tmpdir, wanted) condition.acquire() while not extractor.is_ready(wanted): condition.wait() condition.release() if not os.path.isfile(image_path): return None, None pixbuf = image_tools.load_pixbuf_size(image_path, self.width, self.height) tEXt_data = self._get_text_data(image_path) # Use the archive's mTime instead of the extracted file's mtime tEXt_data['tEXt::Thumb::MTime'] = str(long(os.stat(filepath).st_mtime)) shutil.rmtree(tmpdir, True) return pixbuf, tEXt_data else: # Then check for subarchives by file extension and # extract only the first... subs = filter(constants.SUPPORTED_ARCHIVE_REGEX.search, files) if subs: extractor.set_files([subs[0]]) extractor.extract() condition.acquire() while not extractor.is_ready(subs[0]): condition.wait() condition.release() subpath = os.path.join(tmpdir, subs[0]) # Recursively try to find an image to use as cover return self._create_thumbnail_pixbuf(subpath) shutil.rmtree(tmpdir, True) return None, None elif image_tools.is_image_file(filepath): pixbuf = image_tools.load_pixbuf_size(filepath, self.width, self.height) tEXt_data = self._get_text_data(filepath) return pixbuf, tEXt_data else: return None, None
def _create_thumbnail_pixbuf(self, filepath): """ Creates a thumbnail pixbuf from <filepath>, and returns it as a tuple along with a file metadata dictionary: (pixbuf, tEXt_data) """ if self.archive_support: mime = archive_tools.archive_mime_type(filepath) else: mime = None if mime is not None: cleanup = [] try: tmpdir = tempfile.mkdtemp(prefix=u'mcomix_archive_thumb.') cleanup.append(lambda: shutil.rmtree(tmpdir, True)) archive = archive_tools.get_recursive_archive_handler( filepath, tmpdir, type=mime) if archive is None: return None, None cleanup.append(archive.close) files = archive.list_contents() wanted = self._guess_cover(files) if wanted is None: return None, None archive.extract(wanted, tmpdir) image_path = os.path.join(tmpdir, wanted) if not os.path.isfile(image_path): return None, None pixbuf = image_tools.load_pixbuf_size(image_path, self.width, self.height) if self.store_on_disk: tEXt_data = self._get_text_data(image_path) # Use the archive's mTime instead of the extracted file's mtime tEXt_data['tEXt::Thumb::MTime'] = str( long(os.stat(filepath).st_mtime)) else: tEXt_data = None return pixbuf, tEXt_data finally: for fn in reversed(cleanup): fn() elif image_tools.is_image_file(filepath): pixbuf = image_tools.load_pixbuf_size(filepath, self.width, self.height) if self.store_on_disk: tEXt_data = self._get_text_data(filepath) else: tEXt_data = None return pixbuf, tEXt_data else: return None, None
def _create_thumbnail_pixbuf(self, filepath): """ Creates a thumbnail pixbuf from <filepath>, and returns it as a tuple along with a file metadata dictionary: (pixbuf, tEXt_data) """ if self.archive_support: mime = archive_tools.archive_mime_type(filepath) else: mime = None if mime is not None: cleanup = [] try: tmpdir = tempfile.mkdtemp(prefix=u'mcomix_archive_thumb.') cleanup.append(lambda: shutil.rmtree(tmpdir, True)) archive = archive_tools.get_recursive_archive_handler(filepath, tmpdir, type=mime) if archive is None: return None, None cleanup.append(archive.close) files = archive.list_contents() wanted = self._guess_cover(files) if wanted is None: return None, None archive.extract(wanted, tmpdir) image_path = os.path.join(tmpdir, wanted) if not os.path.isfile(image_path): return None, None pixbuf = image_tools.load_pixbuf_size(image_path, self.width, self.height) if self.store_on_disk: tEXt_data = self._get_text_data(image_path) # Use the archive's mTime instead of the extracted file's mtime tEXt_data['tEXt::Thumb::MTime'] = str(long(os.stat(filepath).st_mtime)) else: tEXt_data = None return pixbuf, tEXt_data finally: for fn in reversed(cleanup): fn() elif image_tools.is_image_file(filepath): pixbuf = image_tools.load_pixbuf_size(filepath, self.width, self.height) if self.store_on_disk: tEXt_data = self._get_text_data(filepath) else: tEXt_data = None return pixbuf, tEXt_data else: return None, None
def _create_thumbnail_pixbuf(self, filepath): ''' Creates a thumbnail pixbuf from <filepath>, and returns it as a tuple along with a file metadata dictionary: (pixbuf, tEXt_data) ''' if self.archive_support: mime = archive_tools.archive_mime_type(filepath) else: mime = None if mime is not None: if not archive_tools.is_archive_file(filepath): return None, None with archive_tools.get_recursive_archive_handler( filepath, type=mime, prefix='mcomix_archive_thumb.') as archive: if archive is None: return None, None if archive.is_encrypted: image_path = tools.pkg_path('images', 'encrypted-book.png') else: files = archive.list_contents(decrypt=False) wanted = self._guess_cover(files) if wanted is None: return None, None image_path = archive.extract(wanted) if not os.path.isfile(image_path): return None, None pixbuf = image_tools.load_pixbuf_size(image_path, self.width, self.height) if self.store_on_disk: tEXt_data = self._get_text_data(image_path) # Use the archive's mTime instead of the extracted file's mtime tEXt_data['tEXt::Thumb::MTime'] = str( os.stat(filepath).st_mtime) else: tEXt_data = None return pixbuf, tEXt_data elif image_tools.is_image_file(filepath, check_mimetype=True): pixbuf = image_tools.load_pixbuf_size(filepath, self.width, self.height) if self.store_on_disk: tEXt_data = self._get_text_data(filepath) else: tEXt_data = None return pixbuf, tEXt_data else: return None, None
def __get_file_filter(self, files): """ Determines what kind of files should be filtered in the given list of <files>. Returns either a filter accepting only images, or only archives, depending on what type of file is found first in the list. """ for file in files: if os.path.isfile(file): if image_tools.is_image_file(file): return image_tools.is_image_file if archive_tools.is_archive_file(file): return archive_tools.is_archive_file # Default filter only accepts images. return image_tools.is_image_file
def _create_thumbnail_pixbuf(self, filepath): """ Creates a thumbnail pixbuf from <filepath>, and returns it as a tuple along with a file metadata dictionary: (pixbuf, tEXt_data) """ if self.archive_support: mime = archive_tools.archive_mime_type(filepath) else: mime = None if mime is not None: with tempfile.TemporaryDirectory( prefix='mcomix_archive_thumb.') as tmpdir: archive = archive_tools.get_recursive_archive_handler( filepath, tmpdir, type=mime) if archive is None: return None, None files = archive.list_contents() wanted = self._guess_cover(files) if wanted is None: return None, None archive.extract(wanted, tmpdir) image_path = os.path.join(tmpdir, wanted) if not os.path.isfile(image_path): return None, None pixbuf = image_tools.load_pixbuf_size(image_path, self.width, self.height) if self.store_on_disk: tEXt_data = self._get_text_data(image_path) # Use the archive's mTime instead of the extracted file's mtime tEXt_data['tEXt::Thumb::MTime'] = str( os.stat(filepath).st_mtime) else: tEXt_data = None return pixbuf, tEXt_data elif image_tools.is_image_file(filepath): pixbuf = image_tools.load_pixbuf_size(filepath, self.width, self.height) if self.store_on_disk: tEXt_data = self._get_text_data(filepath) else: tEXt_data = None return pixbuf, tEXt_data else: return None, None
def get_archive_info(path): '''Return a tuple (mime, num_pages, size) with info about the archive at <path>, or None if <path> doesn't point to a supported ''' mime = archive_mime_type(path) with get_recursive_archive_handler( path, type=mime, prefix='mcomix_archive_info.') as archive: if archive is None: return None files = archive.list_contents(decrypt=False) num_pages = sum([image_tools.is_image_file(f) for f in files]) size = os.stat(path).st_size return (mime, num_pages, size)
def set_directory(self, file_or_directory): """ Sets the base directory. """ if os.path.isdir(file_or_directory): self.base_dir = os.path.abspath(file_or_directory) self.mode = OrderedFileProvider.IMAGES elif os.path.isfile(file_or_directory): self.base_dir = os.path.abspath(os.path.dirname(file_or_directory)) if image_tools.is_image_file(file_or_directory): self.mode = OrderedFileProvider.IMAGES elif archive_tools.archive_mime_type(file_or_directory) is not None: self.mode = OrderedFileProvider.ARCHIVES else: self.mode = OrderedFileProvider.IMAGES else: # Passed file doesn't exist raise ValueError(_("Invalid path: '%s'") % file_or_directory)
def set_directory(self, file_or_directory): """ Sets the base directory. """ if os.path.isdir(file_or_directory): self.base_dir = os.path.abspath(file_or_directory) self.mode = OrderedFileProvider.IMAGES elif os.path.isfile(file_or_directory): self.base_dir = os.path.abspath(os.path.dirname(file_or_directory)) if image_tools.is_image_file(file_or_directory): self.mode = OrderedFileProvider.IMAGES elif archive_tools.archive_mime_type( file_or_directory) is not None: self.mode = OrderedFileProvider.ARCHIVES else: self.mode = OrderedFileProvider.IMAGES else: # Passed file doesn't exist raise ValueError(_("Invalid path: '%s'") % file_or_directory)
def list_files(self, mode=FileProvider.IMAGES): """ Lists all files in the current directory. Returns a list of absolute paths, already sorted. """ if mode == FileProvider.IMAGES: should_accept = lambda file: image_tools.is_image_file(file) elif mode == FileProvider.ARCHIVES: should_accept = lambda file: \ constants.SUPPORTED_ARCHIVE_REGEX.search(file, re.I) is not None else: should_accept = lambda file: True try: files = [ os.path.join(self.base_dir, filename) for filename in # Explicitly convert all files to Unicode, even when # os.listdir returns a mixture of byte/unicode strings. # (MComix bug #3424405) [i18n.to_unicode(fn) for fn in os.listdir(self.base_dir)] if should_accept(os.path.join(self.base_dir, filename)) ] if preferences.prefs['sort by'] == constants.SORT_NAME: tools.alphanumeric_sort(files) elif preferences.prefs['sort by'] == constants.SORT_LAST_MODIFIED: # Most recently modified file first files.sort( key=lambda filename: os.path.getmtime(filename) * -1) elif preferences.prefs['sort by'] == constants.SORT_SIZE: # Smallest file first files.sort(key=lambda filename: os.stat(filename).st_size) # else: don't sort at all: use OS ordering. # Default is ascending. if preferences.prefs['sort order'] == constants.SORT_DESCENDING: files.reverse() return files except OSError: log.warning(u'! ' + _('Could not open %s: Permission denied.'), self.base_dir) return []
def list_files(self, mode=FileProvider.IMAGES): """ Lists all files in the current directory. Returns a list of absolute paths, already sorted. """ if mode == FileProvider.IMAGES: should_accept = lambda file: image_tools.is_image_file(file) elif mode == FileProvider.ARCHIVES: should_accept = lambda file: \ constants.SUPPORTED_ARCHIVE_REGEX.search(file, re.I) is not None else: should_accept = lambda file: True try: files = [ os.path.join(self.base_dir, filename) for filename in # Explicitly convert all files to Unicode, even when # os.listdir returns a mixture of byte/unicode strings. # (MComix bug #3424405) [ i18n.to_unicode(fn) for fn in os.listdir(self.base_dir) ] if should_accept(os.path.join(self.base_dir, filename)) ] if preferences.prefs['sort by'] == constants.SORT_NAME: tools.alphanumeric_sort(files) elif preferences.prefs['sort by'] == constants.SORT_LAST_MODIFIED: # Most recently modified file first files.sort(key=lambda filename: os.path.getmtime(filename)*-1) elif preferences.prefs['sort by'] == constants.SORT_SIZE: # Smallest file first files.sort(key=lambda filename: os.stat(filename).st_size) # else: don't sort at all: use OS ordering. # Default is ascending. if preferences.prefs['sort order'] == constants.SORT_DESCENDING: files.reverse() return files except OSError: log.warning(u'! ' + _('Could not open %s: Permission denied.'), self.base_dir) return []
def _check_for_error_message(self, path, filelist, archive_type): """ Checks for various error that could occur when opening C{path}. @param path: Path to file that should be opened. @param filelist: List of files in the directory of C{path}. @param archive_type: Archive type, if C{path} is an archive. @return: An appropriate error string, or C{None} if no error was found. """ if not os.path.exists(path): return _('Could not open %s: No such file.') % path elif not os.access(path, os.R_OK): return _('Could not open %s: Permission denied.') % path elif archive_type is None and len(filelist) == 0: return _("No images in '%s'") % path elif (archive_type is None and not image_tools.is_image_file(path) and len(filelist) == 0): return _('Could not open %s: Unknown file type.') % path else: return None
def _response(self, dialog, response): if response == constants.RESPONSE_SAVE_AS: dialog = file_chooser_simple_dialog.SimpleFileChooserDialog( gtk.FILE_CHOOSER_ACTION_SAVE) src_path = self.file_handler.get_path_to_base() dialog.set_current_directory(os.path.dirname(src_path)) dialog.set_save_name( '%s.cbz' % os.path.splitext(os.path.basename(src_path))[0]) dialog.filechooser.set_extra_widget( gtk.Label(_('Archives are stored as ZIP files.'))) dialog.run() paths = dialog.get_paths() dialog.destroy() if paths: self._pack_archive(paths[0]) elif response == constants.RESPONSE_IMPORT: dialog = file_chooser_simple_dialog.SimpleFileChooserDialog() dialog.run() paths = dialog.get_paths() dialog.destroy() exts = '|'.join(prefs['comment extensions']) comment_re = re.compile(r'\.(%s)\s*$' % exts, re.I) for path in paths: if image_tools.is_image_file(path): self._imported_files.append(path) self._image_area.add_extra_image(path) elif os.path.isfile(path): if comment_re.search(path): self._imported_files.append(path) self._comment_area.add_extra_file(path) elif response == gtk.RESPONSE_APPLY: old_image_array = self._window.imagehandler._image_files treeiter = self._image_area._liststore.get_iter_root() new_image_array = [] while treeiter is not None: path = self._image_area._liststore.get_value(treeiter, 2) new_image_array.append(path) treeiter = self._image_area._liststore.iter_next(treeiter) new_positions = [] end_index = len(old_image_array) - 1 for image_path in old_image_array: try: new_position = new_image_array.index(image_path) new_positions.append(new_position) except ValueError: # the path was not found in the new array so that means it was deleted new_positions.append(end_index) end_index -= 1 self._window.imagehandler._image_files = new_image_array self._window.imagehandler._raw_pixbufs = {} self._window.imagehandler.do_cacheing() self._window.thumbnailsidebar.clear() self._window.thumbnailsidebar.load_thumbnails() while self._window.imagehandler.is_cacheing and \ not self._window.thumbnailsidebar._is_loading: while gtk.events_pending(): gtk.main_iteration(False) self._window.set_page(1) self._window.thumbnailsidebar._selection_is_forced = False else: _close_dialog() self.kill = True
def _response(self, dialog, response): if response == constants.RESPONSE_SAVE_AS: dialog = file_chooser_simple_dialog.SimpleFileChooserDialog( gtk.FILE_CHOOSER_ACTION_SAVE) src_path = self.file_handler.get_path_to_base() dialog.set_current_directory(os.path.dirname(src_path)) dialog.set_save_name('%s.cbz' % os.path.splitext( os.path.basename(src_path))[0]) dialog.filechooser.set_extra_widget(gtk.Label( _('Archives are stored as ZIP files.'))) dialog.run() paths = dialog.get_paths() dialog.destroy() if paths: self._pack_archive(paths[0]) elif response == constants.RESPONSE_IMPORT: dialog = file_chooser_simple_dialog.SimpleFileChooserDialog() dialog.run() paths = dialog.get_paths() dialog.destroy() exts = '|'.join(prefs['comment extensions']) comment_re = re.compile(r'\.(%s)\s*$' % exts, re.I) for path in paths: if image_tools.is_image_file(path): self._imported_files.append( path ) self._image_area.add_extra_image(path) elif os.path.isfile(path): if comment_re.search( path ): self._imported_files.append( path ) self._comment_area.add_extra_file(path) elif response == gtk.RESPONSE_APPLY: old_image_array = self._window.imagehandler._image_files treeiter = self._image_area._liststore.get_iter_root() new_image_array = [] while treeiter is not None: path = self._image_area._liststore.get_value(treeiter, 2) new_image_array.append(path) treeiter = self._image_area._liststore.iter_next(treeiter) new_positions = [] end_index = len(old_image_array) - 1 for image_path in old_image_array: try: new_position = new_image_array.index( image_path ) new_positions.append(new_position) except ValueError: # the path was not found in the new array so that means it was deleted new_positions.append(end_index) end_index -= 1 self._window.imagehandler._image_files = new_image_array self._window.imagehandler._raw_pixbufs = {} self._window.imagehandler.do_cacheing() self._window.thumbnailsidebar.clear() self._window.thumbnailsidebar.load_thumbnails() while self._window.imagehandler.is_cacheing and \ not self._window.thumbnailsidebar._is_loading: while gtk.events_pending(): gtk.main_iteration(False) self._window.set_page(1) self._window.thumbnailsidebar._selection_is_forced = False else: _close_dialog() self.kill = True
def _response(self, dialog, response): if response == constants.RESPONSE_SAVE_AS: dialog = file_chooser_simple_dialog.SimpleFileChooserDialog( self, Gtk.FileChooserAction.SAVE) src_path = self.file_handler.get_path_to_base() archive_name = os.path.basename(src_path) if os.path.isfile(src_path): archive_name = os.path.splitext(archive_name)[0] dialog.set_current_directory(os.path.dirname(src_path)) dialog.set_save_name(archive_name + '.zip') dialog.filechooser.set_extra_widget( Gtk.Label(label=_('Archives are stored as ZIP files.'))) ffilter = Gtk.FileFilter() ffilter.set_name(_('ZIP archives')) dialog.filechooser.add_filter(ffilter) for ext, mime in constants.ZIP_FORMATS: ffilter.add_mime_type(mime) ffilter.add_pattern('*' + ext) dialog.run() paths = dialog.get_paths() dialog.destroy() if paths: self._pack_archive(paths[0]) elif response == constants.RESPONSE_IMPORT: dialog = file_chooser_simple_dialog.SimpleFileChooserDialog(self) dialog.add_image_filters() dialog.run() paths = dialog.get_paths() dialog.destroy() exts = '|'.join(prefs['comment extensions']) comment_re = re.compile(r'\.(%s)\s*$' % exts, re.I) for path in paths: if image_tools.is_image_file(path): self._imported_files.append(path) self._image_area.add_extra_image(path) elif os.path.isfile(path): if comment_re.search(path): self._imported_files.append(path) self._comment_area.add_extra_file(path) elif response == Gtk.ResponseType.APPLY: old_image_array = self._window.imagehandler.get_image_files() treeiter = self._image_area._liststore.get_iter_first() new_image_array = [] while treeiter is not None: path = self._image_area._liststore.get_value(treeiter, 2) new_image_array.append(path) treeiter = self._image_area._liststore.iter_next(treeiter) new_positions = [] end_index = len(old_image_array) - 1 for image_path in old_image_array: try: new_position = new_image_array.index(image_path) new_positions.append(new_position) except ValueError: # the path was not found in the new array so that means it was deleted new_positions.append(end_index) end_index -= 1 self._window.imagehandler.set_image_files(new_image_array) self._window.imagehandler.clear_raw_pixbufs() self._window.imagehandler.do_cacheing() self._window.thumbnailsidebar.clear() self._window.set_page(1) self._window.thumbnailsidebar.load_thumbnails() else: _close_dialog() self.kill = True