def _add_comment(self, path, num): name = os.path.basename(path) page = gtk.VBox(False) page.set_border_width(8) scrolled = gtk.ScrolledWindow() scrolled.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) page.pack_start(scrolled) outbox = gtk.EventBox() scrolled.add_with_viewport(outbox) inbox = gtk.EventBox() inbox.set_border_width(6) outbox.add(inbox) text = self._window.filehandler.get_comment_text(num) if text is None: text = _('Could not read %s') % name text_buffer = gtk.TextBuffer(self._tag_table) text_buffer.set_text(i18n.to_unicode(text)) text_buffer.apply_tag(self._tag, *text_buffer.get_bounds()) text_view = gtk.TextView(text_buffer) inbox.add(text_view) bg_color = text_view.get_default_attributes().bg_color outbox.modify_bg(gtk.STATE_NORMAL, bg_color) tab_label = gtk.Label(i18n.to_unicode(name)) self._notebook.insert_page(page, tab_label)
def update_title(self): """Set the title acording to current state.""" if self.displayed_double(): title = i18n.to_unicode( "[%d,%d / %d] %s" % ( self.imagehandler.get_current_page(), self.imagehandler.get_current_page() + 1, self.imagehandler.get_number_of_pages(), self.imagehandler.get_pretty_current_filename(), ) ) else: title = i18n.to_unicode( "[%d / %d] %s" % ( self.imagehandler.get_current_page(), self.imagehandler.get_number_of_pages(), self.imagehandler.get_pretty_current_filename(), ) ) if self.slideshow.is_running(): title = "[%s] %s" % (_("SLIDESHOW"), title) self.set_title(title)
def __init__(self, window): gtk.Dialog.__init__(self, _('Comments'), window, 0, (gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE)) self.set_has_separator(False) self.set_resizable(True) self.set_default_response(gtk.RESPONSE_CLOSE) self.set_default_size(600, 550) notebook = gtk.Notebook() notebook.set_scrollable(True) self.set_border_width(4) notebook.set_border_width(6) self.vbox.pack_start(notebook) tag = gtk.TextTag() tag.set_property('editable', False) tag.set_property('editable-set', True) tag.set_property('family', 'Monospace') tag.set_property('family-set', True) tag.set_property('scale', 0.9) tag.set_property('scale-set', True) tag_table = gtk.TextTagTable() tag_table.add(tag) for num in xrange(1, window.filehandler.get_number_of_comments() + 1): page = gtk.VBox(False) page.set_border_width(8) scrolled = gtk.ScrolledWindow() scrolled.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) page.pack_start(scrolled) outbox = gtk.EventBox() scrolled.add_with_viewport(outbox) inbox = gtk.EventBox() inbox.set_border_width(6) outbox.add(inbox) name = os.path.basename(window.filehandler.get_comment_name(num)) text = window.filehandler.get_comment_text(num) if text is None: text = _('Could not read %s') % name text_buffer = gtk.TextBuffer(tag_table) text_buffer.set_text(i18n.to_unicode(text)) text_buffer.apply_tag(tag, *text_buffer.get_bounds()) text_view = gtk.TextView(text_buffer) inbox.add(text_view) bg_color = text_view.get_default_attributes().bg_color outbox.modify_bg(gtk.STATE_NORMAL, bg_color) tab_label = gtk.Label(i18n.to_unicode(name)) notebook.insert_page(page, tab_label) self.show_all()
def update_info(self, selected): '''Update the info box using the currently <selected> books from the _BookArea. ''' if selected: book_id = self._library.book_area.get_book_at_path(selected[0]) book = self._library.backend.get_book_by_id(book_id) else: book = None if book: name = book.name dir_path = os.path.dirname(book.path) pages = book.pages size = book.size last_page = book.get_last_read_page() last_date = book.get_last_read_date() else: name = dir_path = pages = size = last_page = last_date = None if len(selected) > 0: self._open_button.set_sensitive(True) else: self._open_button.set_sensitive(False) if name is not None: self._namelabel.set_text(i18n.to_unicode(name)) self._namelabel.set_tooltip_text(i18n.to_unicode(name)) else: self._namelabel.set_text('') self._namelabel.set_has_tooltip(False) infotext = [] if last_page is not None and pages is not None and last_page != pages: infotext.append('%s %d/%d' % (_('Page'), last_page, pages)) elif pages is not None: infotext.append(_('%d pages') % pages) if size is not None: infotext.append('%.1f MiB' % (size / 1048576.0)) if (pages is not None and last_page is not None and last_date is not None and last_page == pages): infotext.append( _('Finished reading on %(date)s, %(time)s') % { 'date': last_date.strftime('%x'), 'time': last_date.strftime('%X'), }) self._filelabel.set_text(', '.join(infotext)) if dir_path is not None: self._dirlabel.set_text(i18n.to_unicode(dir_path)) else: self._dirlabel.set_text('')
def update_info(self, selected): """Update the info box using the currently <selected> books from the _BookArea. """ if selected: book_id = self._library.book_area.get_book_at_path(selected[0]) book = self._library.backend.get_book_by_id(book_id) else: book = None if book: name = book.name dir_path = os.path.dirname(book.path) pages = book.pages size = book.size last_page = book.get_last_read_page() last_date = book.get_last_read_date() else: name = dir_path = pages = size = last_page = last_date = None if len(selected) > 0: self._open_button.set_sensitive(True) else: self._open_button.set_sensitive(False) if name is not None: self._namelabel.set_text(i18n.to_unicode(name)) self._namelabel.set_tooltip_text(i18n.to_unicode(name)) else: self._namelabel.set_text('') self._namelabel.set_has_tooltip(False) infotext = [] if last_page is not None and pages is not None and last_page != pages: infotext.append('%s %d/%d' % (_('Page'), last_page, pages)) elif pages is not None: infotext.append(_('%d pages') % pages) if size is not None: infotext.append('%.1f MiB' % (size / 1048576.0)) if (pages is not None and last_page is not None and last_date is not None and last_page == pages): infotext.append(_('Finished reading on %(date)s, %(time)s') % { 'date': last_date.strftime('%x'), 'time': last_date.strftime('%X') }) self._filelabel.set_text(', '.join(infotext)) if dir_path is not None: self._dirlabel.set_text(i18n.to_unicode(dir_path)) else: self._dirlabel.set_text('')
def get_pretty_current_filename(self): '''Return a string with the name of the currently viewed file that is suitable for printing. ''' if self._window.filehandler.archive_type is not None: return i18n.to_unicode(os.path.basename(self._base_path)) img_file = os.path.abspath(self.get_current_path()) if not img_file: return '' name = os.path.join(*tools.splitpath(img_file)[-2:]) return i18n.to_unicode(name)
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 = functools.partial(image_tools.is_image_file, check_mimetype=True) elif mode == FileProvider.ARCHIVES: should_accept = archive_tools.is_archive_file else: should_accept = lambda file: True files = [] fname_map = {} try: # listdir() return list of bytes only if path is bytes for fn in self.listdir(self.base_dir): filename = i18n.to_unicode(fn) fpath = os.path.join(self.base_dir, filename) if should_accept(fpath): files.append(fpath) fname_map[fpath] = os.path.join(self.base_dir, fn) except OSError: log.warning('! ' + _('Could not open %s: Permission denied.'), self.base_dir) return [] FileProvider.sort_files(files) return [fname_map[fpath] for fpath in files]
def _update_page_secondary_info(self, page, location): secondary_info = [ (_('Location'), i18n.to_unicode(os.path.dirname(location))), ] try: stats = os.stat(location) except OSError as e: page.set_secondary_info(secondary_info) return if _has_pwd: uid = pwd.getpwuid(stats.st_uid)[0] else: uid = str(stats.st_uid) if stats.st_size > 1048576.0: size = '%.1f MiB' % (stats.st_size / 1048576.0) else: size = '%.1f KiB' % (stats.st_size / 1024.0) secondary_info.extend( ((_('Size'), size), (_('Accessed'), time.strftime('%Y-%m-%d, %H:%M:%S', time.localtime(stats.st_atime))), (_('Modified'), time.strftime('%Y-%m-%d, %H:%M:%S', time.localtime(stats.st_mtime))), (_('Permissions'), oct(stat.S_IMODE(stats.st_mode))), (_('Owner'), uid))) page.set_secondary_info(secondary_info)
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 = image_tools.is_image_file elif mode == FileProvider.ARCHIVES: should_accept = archive_tools.is_archive_file 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 set_status_message(self, message): """Set a specific message on the statusbar, replacing whatever was there earlier. """ self._statusbar.pop(0) self._statusbar.push(0, ' ' * status.Statusbar.SPACING + '%s' % i18n.to_unicode(message))
def _update_page_secondary_info(self, page, location): secondary_info = [ (_('Location'), i18n.to_unicode(os.path.dirname(location))), ] try: stats = os.stat(location) except OSError as e: page.set_secondary_info(secondary_info) return if _has_pwd: uid = pwd.getpwuid(stats.st_uid)[0] else: uid = str(stats.st_uid) if stats.st_size > 1048576.0: size = '%.1f MiB' % (stats.st_size / 1048576.0) else: size = '%.1f KiB' % (stats.st_size / 1024.0) secondary_info.extend(( (_('Size'), size), (_('Accessed'), time.strftime('%Y-%m-%d, %H:%M:%S', time.localtime(stats.st_atime))), (_('Modified'), time.strftime('%Y-%m-%d, %H:%M:%S', time.localtime(stats.st_mtime))), (_('Permissions'), oct(stat.S_IMODE(stats.st_mode))), (_('Owner'), uid) )) page.set_secondary_info(secondary_info)
def fetch_images(self): """Load all the images in the archive or directory.""" for page in xrange(1, self._window.imagehandler.get_number_of_pages() + 1): path = self._window.imagehandler.get_path_to_page(page) encoded_path = i18n.to_unicode(os.path.basename(path)) encoded_path = encoded_path.replace("&", "&") self._liststore.append([self._filler, encoded_path, path, False])
def set_filename(self, filename): """Set the filename to be displayed to <filename>. Call this before set_main_info(). """ label = labels.BoldLabel(i18n.to_unicode(filename)) label.set_alignment(0, 0.5) self._mainbox.pack_start(label, False, False) self._mainbox.pack_start(gtk.VBox()) # Just to add space (better way?)
def fetch_images(self): """Load all the images in the archive or directory.""" for page in range(1, self._window.imagehandler.get_number_of_pages() + 1): path = self._window.imagehandler.get_path_to_page(page) encoded_path = i18n.to_unicode(os.path.basename(path)) encoded_path = encoded_path.replace('&', '&') self._liststore.append([self._filler, encoded_path, path, False])
def update_info(self, selected): """Update the info box using the currently <selected> books from the _BookArea. """ if selected: book = self._library.book_area.get_book_at_path(selected[0]) name = self._library.backend.get_book_name(book) dir_path = os.path.dirname( self._library.backend.get_book_path(book)) format = self._library.backend.get_book_format(book) pages = self._library.backend.get_book_pages(book) size = self._library.backend.get_book_size(book) else: name = dir_path = format = pages = size = None if len(selected) > 0: self._open_button.set_sensitive(True) else: self._open_button.set_sensitive(False) if name is not None: self._namelabel.set_text(i18n.to_unicode(name)) self._namelabel.set_tooltip_text(i18n.to_unicode(name)) else: self._namelabel.set_text('') self._namelabel.set_has_tooltip(False) if pages is not None: self._pageslabel.set_text(_('%d pages') % pages) else: self._pageslabel.set_text('') if format is not None and size is not None: self._filelabel.set_text( '%s, %s' % (strings.ARCHIVE_DESCRIPTIONS[format], '%.1f MiB' % (size / 1048576.0))) else: self._filelabel.set_text('') if dir_path is not None: self._dirlabel.set_text(i18n.to_unicode(dir_path)) else: self._dirlabel.set_text('')
def Win32Popen(cmd): """ Spawns a new process on Win32. cmd is a list of parameters. This method's sole purpose is calling CreateProcessW, not CreateProcessA as it is done by subprocess.Popen. """ import ctypes # Declare common data types DWORD = ctypes.c_uint WORD = ctypes.c_ushort LPTSTR = ctypes.c_wchar_p LPBYTE = ctypes.POINTER(ctypes.c_ubyte) HANDLE = ctypes.c_void_p class StartupInfo(ctypes.Structure): _fields_ = [("cb", DWORD), ("lpReserved", LPTSTR), ("lpDesktop", LPTSTR), ("lpTitle", LPTSTR), ("dwX", DWORD), ("dwY", DWORD), ("dwXSize", DWORD), ("dwYSize", DWORD), ("dwXCountChars", DWORD), ("dwYCountChars", DWORD), ("dwFillAttribute", DWORD), ("dwFlags", DWORD), ("wShowWindow", WORD), ("cbReserved2", WORD), ("lpReserved2", LPBYTE), ("hStdInput", HANDLE), ("hStdOutput", HANDLE), ("hStdError", HANDLE)] class ProcessInformation(ctypes.Structure): _fields_ = [("hProcess", HANDLE), ("hThread", HANDLE), ("dwProcessId", DWORD), ("dwThreadId", DWORD)] LPSTRARTUPINFO = ctypes.POINTER(StartupInfo) LPROCESS_INFORMATION = ctypes.POINTER(ProcessInformation) ctypes.windll.kernel32.CreateProcessW.argtypes = [ LPTSTR, LPTSTR, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_bool, DWORD, ctypes.c_void_p, LPTSTR, LPSTRARTUPINFO, LPROCESS_INFORMATION ] ctypes.windll.kernel32.CreateProcessW.restype = ctypes.c_bool # Convert list of arguments into a single string cmdline = subprocess.list2cmdline(cmd) buffer = ctypes.create_unicode_buffer(cmdline) # Some required structures for the method call... startupinfo = StartupInfo() ctypes.memset(ctypes.addressof(startupinfo), 0, ctypes.sizeof(startupinfo)) startupinfo.cb = ctypes.sizeof(startupinfo) processinfo = ProcessInformation() # Spawn new process success = ctypes.windll.kernel32.CreateProcessW(cmd[0], buffer, None, None, False, 0, None, None, ctypes.byref(startupinfo), ctypes.byref(processinfo)) if success: ctypes.windll.kernel32.CloseHandle(processinfo.hProcess) ctypes.windll.kernel32.CloseHandle(processinfo.hThread) return processinfo.dwProcessId else: raise ctypes.WinError(ctypes.GetLastError(), i18n.to_unicode(ctypes.FormatError()))
def set_filename(self, filename): '''Set the filename to be displayed to <filename>. Call this before set_main_info(). ''' label = labels.BoldLabel(i18n.to_unicode(filename)) label.set_alignment(0, 0.5) label.set_selectable(True) self._mainbox.pack_start(label, False, False, 0) self._mainbox.pack_start(Gtk.VBox(homogeneous=True, spacing=0), True, True, 0) # Just to add space (better way?)
def update_info(self, selected): """Update the info box using the currently <selected> books from the _BookArea. """ if selected: book = self._library.book_area.get_book_at_path(selected[0]) name = self._library.backend.get_book_name(book) dir_path = os.path.dirname(self._library.backend.get_book_path(book)) format = self._library.backend.get_book_format(book) pages = self._library.backend.get_book_pages(book) size = self._library.backend.get_book_size(book) else: name = dir_path = format = pages = size = None if len(selected) > 0: self._open_button.set_sensitive(True) else: self._open_button.set_sensitive(False) if name is not None: self._namelabel.set_text(i18n.to_unicode(name)) self._namelabel.set_tooltip_text(i18n.to_unicode(name)) else: self._namelabel.set_text("") self._namelabel.set_has_tooltip(False) if pages is not None: self._pageslabel.set_text(_("%d pages") % pages) else: self._pageslabel.set_text("") if format is not None and size is not None: self._filelabel.set_text("%s, %s" % (strings.ARCHIVE_DESCRIPTIONS[format], "%.1f MiB" % (size / 1048576.0))) else: self._filelabel.set_text("") if dir_path is not None: self._dirlabel.set_text(i18n.to_unicode(dir_path)) else: self._dirlabel.set_text("")
def remove(self, path): if not preferences.prefs['store recent file info']: return uri = (portability.uri_prefix() + urllib.request.pathname2url(i18n.to_unicode(path))) try: self._manager.remove_item(uri) except glib.GError: # Could not remove item pass
def fetch_images(self): """Load all the images in the archive or directory.""" for page in xrange(1, self._window.imagehandler.get_number_of_pages() + 1): thumb = self._window.thumbnailsidebar.get_thumbnail(page) path = self._window.imagehandler.get_path_to_page(page) encoded_path = i18n.to_unicode(os.path.basename(path)) encoded_path = encoded_path.replace('&', '&') self._liststore.append([thumb, encoded_path, path])
def update_title(self): """Set the title acording to current state.""" if self.displayed_double(): title = i18n.to_unicode( '[%d,%d / %d] %s' % (self.imagehandler.get_current_page(), self.imagehandler.get_current_page() + 1, self.imagehandler.get_number_of_pages(), self.imagehandler.get_pretty_current_filename())) else: title = i18n.to_unicode( '[%d / %d] %s' % (self.imagehandler.get_current_page(), self.imagehandler.get_number_of_pages(), self.imagehandler.get_pretty_current_filename())) if self.slideshow.is_running(): title = '[%s] %s' % (_('SLIDESHOW'), title) self.set_title(title)
def print_(*args, **options): """ This function is supposed to replace the standard print statement. Its prototype follows that of the print() function introduced in Python 2.6: Prints <args>, with each argument separeted by sep=' ' and ending with end='\n'. It converts any text to the encoding used by STDOUT, and replaces problematic characters with underscore. Prevents UnicodeEncodeErrors and similar when using print on non-ASCII strings, on systems not using UTF-8 as default encoding. """ args = [i18n.to_unicode(val) for val in args] if 'sep' in options: sep = options['sep'] else: sep = u' ' if 'end' in options: end = options['end'] else: end = u'\n' def print_generic(text): if text: if (sys.stdout and hasattr(sys.stdout, 'encoding') and sys.stdout.encoding is not None): encoding = sys.stdout.encoding else: encoding = locale.getpreferredencoding( ) or sys.getfilesystemencoding() sys.stdout.write(text) def print_win32(text): if not text: return import ctypes INVALID_HANDLE_VALUE, STD_OUTPUT_HANDLE = -1, -11 outhandle = ctypes.windll.kernel32.GetStdHandle(STD_OUTPUT_HANDLE) if outhandle != INVALID_HANDLE_VALUE and outhandle: chars_written = ctypes.c_int(0) ctypes.windll.kernel32.WriteConsoleW(outhandle, text, len(text), ctypes.byref(chars_written), None) else: print_generic(text) print_function = sys.platform == 'win32' and print_win32 or print_generic if len(args) > 0: print_function(args[0]) for text in args[1:]: print_function(sep) print_function(text) print_function(end)
def print_(*args, **options): """ This function is supposed to replace the standard print statement. Its prototype follows that of the print() function introduced in Python 2.6: Prints <args>, with each argument separeted by sep=' ' and ending with end='\n'. It converts any text to the encoding used by STDOUT, and replaces problematic characters with underscore. Prevents UnicodeEncodeErrors and similar when using print on non-ASCII strings, on systems not using UTF-8 as default encoding. """ args = [ i18n.to_unicode(val) for val in args ] if 'sep' in options: sep = options['sep'] else: sep = u' ' if 'end' in options: end = options['end'] else: end = u'\n' def print_generic(text): if text: if (sys.stdout and hasattr(sys.stdout, 'encoding') and sys.stdout.encoding is not None): encoding = sys.stdout.encoding else: encoding = locale.getpreferredencoding() or sys.getfilesystemencoding() stdout = getattr(sys.stdout, 'buffer', sys.stdout) # py23 stdout.write(text.encode(encoding, 'replace')) def print_win32(text): if not text: return import ctypes INVALID_HANDLE_VALUE, STD_OUTPUT_HANDLE = -1, -11 outhandle = ctypes.windll.kernel32.GetStdHandle(STD_OUTPUT_HANDLE) if outhandle != INVALID_HANDLE_VALUE and outhandle: chars_written = ctypes.c_int(0) ctypes.windll.kernel32.WriteConsoleW(outhandle, text, len(text), ctypes.byref(chars_written), None) else: print_generic(text) print_function = sys.platform == 'win32' and print_win32 or print_generic if len(args) > 0: print_function(args[0]) for text in args[1:]: print_function(sep) print_function(text) print_function(end)
def get_pretty_current_filename(self): """Return a string with the name of the currently viewed file that is suitable for printing. """ if self._window.filehandler.archive_type is not None: name = os.path.basename(self._base_path) elif self._image_files: img_file = os.path.abspath(self._image_files[self._current_image_index]) name = os.path.join(os.path.basename(os.path.dirname(img_file)), os.path.basename(img_file)) else: name = u"" return i18n.to_unicode(name)
def get_pretty_current_filename(self): """Return a string with the name of the currently viewed file that is suitable for printing. """ if self._window.filehandler.archive_type is not None: name = os.path.basename(self._base_path) elif self._image_files: img_file = os.path.abspath( self._image_files[self._current_image_index]) name = os.path.join(os.path.basename(os.path.dirname(img_file)), os.path.basename(img_file)) else: name = u'' return i18n.to_unicode(name)
def fetch_images(self): """Load all the images in the archive or directory.""" pixbuf = gtk.gdk.Pixbuf(colorspace=gtk.gdk.COLORSPACE_RGB, has_alpha=True, bits_per_sample=8, width=prefs['thumbnail size'], height=prefs['thumbnail size']) # Make the pixbuf transparent. pixbuf.fill(0) for page in xrange(1, self._window.imagehandler.get_number_of_pages() + 1): path = self._window.imagehandler.get_path_to_page(page) encoded_path = i18n.to_unicode(os.path.basename(path)) encoded_path = encoded_path.replace('&', '&') self._liststore.append([pixbuf, encoded_path, path, page, False])
def update_title(self): """Set the title acording to current state.""" this_screen = 2 if self.displayed_double() else 1 # XXX limited to at most 2 pages # TODO introduce formatter to merge these string ops with the ops for status bar updates title = '[' for i in range(this_screen): title += '%d' % (self.imagehandler.get_current_page() + i) if i < this_screen - 1: title += ',' title += ' / %d] %s' % (self.imagehandler.get_number_of_pages(), self.imagehandler.get_pretty_current_filename()) title = i18n.to_unicode(title) if self.slideshow.is_running(): title = '[%s] %s' % (_('SLIDESHOW'), title) self.set_title(title)
def _get_text_data(self, filepath): ''' Creates a tEXt dictionary for <filepath>. ''' mime = mimetypes.guess_type(filepath)[0] or 'unknown/mime' uri = portability.uri_prefix() + pathname2url( i18n.to_unicode(os.path.normpath(filepath))) stat = os.stat(filepath) # MTime could be floating point number, so convert to long first to have a fixed point number mtime = str(stat.st_mtime) size = str(stat.st_size) format, width, height = image_tools.get_image_info(filepath) return { 'tEXt::Thumb::URI': uri, 'tEXt::Thumb::MTime': mtime, 'tEXt::Thumb::Size': size, 'tEXt::Thumb::Mimetype': mime, 'tEXt::Thumb::Image::Width': str(width), 'tEXt::Thumb::Image::Height': str(height), 'tEXt::Software': 'MComix %s' % constants.VERSION }
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 set_filename(self, filename): '''Update the filename.''' self._filename = i18n.to_unicode(filename)
def __init__(self, window): gtk.Dialog.__init__(self, _('Properties'), window, 0, (gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE)) self.set_resizable(True) self.set_has_separator(False) self.set_default_response(gtk.RESPONSE_CLOSE) notebook = gtk.Notebook() self.set_border_width(4) notebook.set_border_width(6) self.vbox.pack_start(notebook, False, False, 0) if window.filehandler.archive_type is not None: # ------------------------------------------------------------ # Archive tab # ------------------------------------------------------------ page = properties_page._Page() thumb = window.imagehandler.get_thumbnail(1, width=200, height=128) page.set_thumbnail(thumb) filename = window.filehandler.get_pretty_current_filename() page.set_filename(filename) try: stats = os.stat(window.filehandler.get_path_to_base()) main_info = ( _('%d pages') % window.imagehandler.get_number_of_pages(), _('%d comments') % window.filehandler.get_number_of_comments(), strings.ARCHIVE_DESCRIPTIONS[window.filehandler.archive_type], '%.1f MiB' % (stats.st_size / 1048576.0)) page.set_main_info(main_info) try: uid = pwd.getpwuid(stats.st_uid)[0] except Exception: uid = str(stats.st_uid) secondary_info = ( (_('Location'), i18n.to_unicode(os.path.dirname( window.filehandler.get_path_to_base()))), (_('Accessed'), time.strftime('%Y-%m-%d, %H:%M:%S', time.localtime(stats.st_atime))), (_('Modified'), time.strftime('%Y-%m-%d, %H:%M:%S', time.localtime(stats.st_mtime))), (_('Permissions'), oct(stat.S_IMODE(stats.st_mode))), (_('Owner'), uid)) page.set_secondary_info(secondary_info) except Exception: pass notebook.append_page(page, gtk.Label(_('Archive'))) # ---------------------------------------------------------------- # Image tab # ---------------------------------------------------------------- path = window.imagehandler.get_path_to_page() page = properties_page._Page() thumb = window.imagehandler.get_thumbnail(width=200, height=128) page.set_thumbnail(thumb) filename = os.path.basename(path) page.set_filename(filename) try: stats = os.stat(path) width, height = window.imagehandler.get_size() main_info = ( '%dx%d px' % (width, height), window.imagehandler.get_mime_name(), '%.1f KiB' % (stats.st_size / 1024.0)) page.set_main_info(main_info) try: uid = pwd.getpwuid(stats.st_uid)[0] except Exception: uid = str(stats.st_uid) secondary_info = ( (_('Location'), i18n.to_unicode(os.path.dirname(path))), (_('Accessed'), time.strftime('%Y-%m-%d, %H:%M:%S', time.localtime(stats.st_atime))), (_('Modified'), time.strftime('%Y-%m-%d, %H:%M:%S', time.localtime(stats.st_mtime))), (_('Permissions'), oct(stat.S_IMODE(stats.st_mode))), (_('Owner'), uid)) page.set_secondary_info(secondary_info) except Exception: pass notebook.append_page(page, gtk.Label(_('Image'))) self.show_all()
def add(self, path): if not preferences.prefs['store recent file info']: return uri = (portability.uri_prefix() + urllib.request.pathname2url(i18n.to_unicode(path))) self._manager.add_item(uri)
def __init__(self, window): gtk.Dialog.__init__(self, _('Properties'), window, 0, (gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE)) self.set_resizable(True) self.set_has_separator(False) self.set_default_response(gtk.RESPONSE_CLOSE) notebook = gtk.Notebook() self.set_border_width(4) notebook.set_border_width(6) self.vbox.pack_start(notebook, False, False, 0) if window.filehandler.archive_type is not None: # ------------------------------------------------------------ # Archive tab # ------------------------------------------------------------ page = properties_page._Page() thumb = window.imagehandler.get_thumbnail(1, width=200, height=128) page.set_thumbnail(thumb) filename = window.filehandler.get_pretty_current_filename() page.set_filename(filename) try: stats = os.stat(window.filehandler.get_path_to_base()) main_info = (_('%d pages') % window.imagehandler.get_number_of_pages(), _('%d comments') % window.filehandler.get_number_of_comments(), strings.ARCHIVE_DESCRIPTIONS[ window.filehandler.archive_type], '%.1f MiB' % (stats.st_size / 1048576.0)) page.set_main_info(main_info) try: uid = pwd.getpwuid(stats.st_uid)[0] except Exception: uid = str(stats.st_uid) secondary_info = ( (_('Location'), i18n.to_unicode( os.path.dirname( window.filehandler.get_path_to_base()))), (_('Accessed'), time.strftime('%Y-%m-%d, %H:%M:%S', time.localtime(stats.st_atime))), (_('Modified'), time.strftime('%Y-%m-%d, %H:%M:%S', time.localtime(stats.st_mtime))), (_('Permissions'), oct(stat.S_IMODE(stats.st_mode))), (_('Owner'), uid)) page.set_secondary_info(secondary_info) except Exception: pass notebook.append_page(page, gtk.Label(_('Archive'))) # ---------------------------------------------------------------- # Image tab # ---------------------------------------------------------------- path = window.imagehandler.get_path_to_page() page = properties_page._Page() thumb = window.imagehandler.get_thumbnail(width=200, height=128) page.set_thumbnail(thumb) filename = os.path.basename(path) page.set_filename(filename) try: stats = os.stat(path) width, height = window.imagehandler.get_size() main_info = ('%dx%d px' % (width, height), window.imagehandler.get_mime_name(), '%.1f KiB' % (stats.st_size / 1024.0)) page.set_main_info(main_info) try: uid = pwd.getpwuid(stats.st_uid)[0] except Exception: uid = str(stats.st_uid) secondary_info = ((_('Location'), i18n.to_unicode(os.path.dirname(path))), (_('Accessed'), time.strftime('%Y-%m-%d, %H:%M:%S', time.localtime(stats.st_atime))), (_('Modified'), time.strftime('%Y-%m-%d, %H:%M:%S', time.localtime(stats.st_mtime))), (_('Permissions'), oct(stat.S_IMODE(stats.st_mode))), (_('Owner'), uid)) page.set_secondary_info(secondary_info) except Exception: pass notebook.append_page(page, gtk.Label(_('Image'))) self.show_all()
def set_root(self, root): """Set the name of the root (directory or archive).""" self._root = i18n.to_unicode(root)
def set_filename(self, filename): """Update the filename.""" self._filename = i18n.to_unicode(filename)
def _path_to_thumbpath(self, filepath): ''' Converts <path> to an URI for the thumbnail in <dst_dir>. ''' uri = portability.uri_prefix() + pathname2url( i18n.to_unicode(os.path.normpath(filepath))) return self._uri_to_thumbpath(uri)
def Win32Popen(cmd): """ Spawns a new process on Win32. cmd is a list of parameters. This method's sole purpose is calling CreateProcessW, not CreateProcessA as it is done by subprocess.Popen. """ import ctypes # Declare common data types DWORD = ctypes.c_uint WORD = ctypes.c_ushort LPTSTR = ctypes.c_wchar_p LPBYTE = ctypes.POINTER(ctypes.c_ubyte) HANDLE = ctypes.c_void_p class StartupInfo(ctypes.Structure): _fields_ = [("cb", DWORD), ("lpReserved", LPTSTR), ("lpDesktop", LPTSTR), ("lpTitle", LPTSTR), ("dwX", DWORD), ("dwY", DWORD), ("dwXSize", DWORD), ("dwYSize", DWORD), ("dwXCountChars", DWORD), ("dwYCountChars", DWORD), ("dwFillAttribute", DWORD), ("dwFlags", DWORD), ("wShowWindow", WORD), ("cbReserved2", WORD), ("lpReserved2", LPBYTE), ("hStdInput", HANDLE), ("hStdOutput", HANDLE), ("hStdError", HANDLE)] class ProcessInformation(ctypes.Structure): _fields_ = [("hProcess", HANDLE), ("hThread", HANDLE), ("dwProcessId", DWORD), ("dwThreadId", DWORD)] LPSTRARTUPINFO = ctypes.POINTER(StartupInfo) LPROCESS_INFORMATION = ctypes.POINTER(ProcessInformation) ctypes.windll.kernel32.CreateProcessW.argtypes = [LPTSTR, LPTSTR, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_bool, DWORD, ctypes.c_void_p, LPTSTR, LPSTRARTUPINFO, LPROCESS_INFORMATION] ctypes.windll.kernel32.CreateProcessW.restype = ctypes.c_bool # Convert list of arguments into a single string cmdline = subprocess.list2cmdline(cmd) buffer = ctypes.create_unicode_buffer(cmdline) # Some required structures for the method call... startupinfo = StartupInfo() ctypes.memset(ctypes.addressof(startupinfo), 0, ctypes.sizeof(startupinfo)) startupinfo.cb = ctypes.sizeof(startupinfo) processinfo = ProcessInformation() # Spawn new process success = ctypes.windll.kernel32.CreateProcessW(cmd[0], buffer, None, None, False, 0, None, None, ctypes.byref(startupinfo), ctypes.byref(processinfo)) if success: ctypes.windll.kernel32.CloseHandle(processinfo.hProcess) ctypes.windll.kernel32.CloseHandle(processinfo.hThread) return processinfo.dwProcessId else: raise ctypes.WinError(ctypes.GetLastError(), i18n.to_unicode(ctypes.FormatError()))