home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2010 November / maximum-cd-2010-11.iso / DiscContents / calibre-0.7.13.msi / file_1289 (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2010-08-06  |  13.2 KB  |  302 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. __license__ = 'GPL v3'
  5. __copyright__ = '2010, Kovid Goyal <kovid@kovidgoyal.net>'
  6. __docformat__ = 'restructuredtext en'
  7. import functools
  8. import sys
  9. import os
  10. from PyQt4.Qt import QMenu, Qt, QStackedWidget, QSize, QSizePolicy, QStatusBar, QLabel, QFont
  11. from calibre.utils.config import prefs
  12. from calibre.constants import isosx, __appname__, preferred_encoding, __version__
  13. from calibre.gui2 import config, is_widescreen
  14. from calibre.gui2.library.views import BooksView, DeviceBooksView
  15. from calibre.gui2.widgets import Splitter
  16. from calibre.gui2.tag_view import TagBrowserWidget
  17. from calibre.gui2.book_details import BookDetails
  18. from calibre.gui2.notify import get_notifier
  19. _keep_refs = []
  20.  
  21. def partial(*args, **kwargs):
  22.     ans = functools.partial(*args, **kwargs)
  23.     _keep_refs.append(ans)
  24.     return ans
  25.  
  26.  
  27. class LibraryViewMixin(object):
  28.     
  29.     def __init__(self, db):
  30.         similar_menu = QMenu(_('Similar books...'))
  31.         similar_menu.addAction(self.action_books_by_same_author)
  32.         similar_menu.addAction(self.action_books_in_this_series)
  33.         similar_menu.addAction(self.action_books_with_the_same_tags)
  34.         similar_menu.addAction(self.action_books_by_this_publisher)
  35.         self.action_books_by_same_author.setShortcut(Qt.ALT + Qt.Key_A)
  36.         self.action_books_in_this_series.setShortcut(Qt.ALT + Qt.Key_S)
  37.         self.action_books_by_this_publisher.setShortcut(Qt.ALT + Qt.Key_P)
  38.         self.action_books_with_the_same_tags.setShortcut(Qt.ALT + Qt.Key_T)
  39.         self.addAction(self.action_books_by_same_author)
  40.         self.addAction(self.action_books_by_this_publisher)
  41.         self.addAction(self.action_books_in_this_series)
  42.         self.addAction(self.action_books_with_the_same_tags)
  43.         self.similar_menu = similar_menu
  44.         self.action_books_by_same_author.triggered.connect(partial(self.show_similar_books, 'authors'))
  45.         self.action_books_in_this_series.triggered.connect(partial(self.show_similar_books, 'series'))
  46.         self.action_books_with_the_same_tags.triggered.connect(partial(self.show_similar_books, 'tag'))
  47.         self.action_books_by_this_publisher.triggered.connect(partial(self.show_similar_books, 'publisher'))
  48.         self.library_view.set_context_menu(self.action_edit, self.action_sync, self.action_convert, self.action_view, self.action_save, self.action_open_containing_folder, self.action_show_book_details, self.action_del, self.action_conn_share, add_to_library = None, edit_device_collections = None, similar_menu = similar_menu)
  49.         add_to_library = (_('Add books to library'), self.add_books_from_device)
  50.         edit_device_collections = (_('Manage collections'), partial(self.edit_device_collections, oncard = None))
  51.         self.memory_view.set_context_menu(None, None, None, self.action_view, self.action_save, None, None, self.action_del, None, add_to_library = add_to_library, edit_device_collections = edit_device_collections)
  52.         edit_device_collections = (_('Manage collections'), partial(self.edit_device_collections, oncard = 'carda'))
  53.         self.card_a_view.set_context_menu(None, None, None, self.action_view, self.action_save, None, None, self.action_del, None, add_to_library = add_to_library, edit_device_collections = edit_device_collections)
  54.         edit_device_collections = (_('Manage collections'), partial(self.edit_device_collections, oncard = 'cardb'))
  55.         self.card_b_view.set_context_menu(None, None, None, self.action_view, self.action_save, None, None, self.action_del, None, add_to_library = add_to_library, edit_device_collections = edit_device_collections)
  56.         self.library_view.files_dropped.connect(self.files_dropped, type = Qt.QueuedConnection)
  57.         for func, args in [
  58.             ('connect_to_search_box', (self.search, self.search_done)),
  59.             ('connect_to_book_display', (self.book_details.show_data,))]:
  60.             for view in (self.library_view, self.memory_view, self.card_a_view, self.card_b_view):
  61.                 getattr(view, func)(*args)
  62.             
  63.         
  64.         self.memory_view.connect_dirtied_signal(self.upload_booklists)
  65.         self.memory_view.connect_upload_collections_signal(func = self.upload_collections, oncard = None)
  66.         self.card_a_view.connect_dirtied_signal(self.upload_booklists)
  67.         self.card_a_view.connect_upload_collections_signal(func = self.upload_collections, oncard = 'carda')
  68.         self.card_b_view.connect_dirtied_signal(self.upload_booklists)
  69.         self.card_b_view.connect_upload_collections_signal(func = self.upload_collections, oncard = 'cardb')
  70.         self.book_on_device(None, reset = True)
  71.         db.set_book_on_device_func(self.book_on_device)
  72.         self.library_view.set_database(db)
  73.         self.library_view.model().set_book_on_device_func(self.book_on_device)
  74.         prefs['library_path'] = self.library_path
  75.         for view in ('library', 'memory', 'card_a', 'card_b'):
  76.             view = getattr(self, view + '_view')
  77.             view.verticalHeader().sectionDoubleClicked.connect(self.view_specific_book)
  78.         
  79.  
  80.     
  81.     def show_similar_books(self, type, *args):
  82.         search = []
  83.         join = ' '
  84.         idx = self.library_view.currentIndex()
  85.         if not idx.isValid():
  86.             return None
  87.         row = idx.row()
  88.         if type == 'series':
  89.             series = idx.model().db.series(row)
  90.             if series:
  91.                 search = [
  92.                     'series:"' + series + '"']
  93.             
  94.         elif type == 'publisher':
  95.             publisher = idx.model().db.publisher(row)
  96.             if publisher:
  97.                 search = [
  98.                     'publisher:"' + publisher + '"']
  99.             
  100.         elif type == 'tag':
  101.             tags = idx.model().db.tags(row)
  102.             if tags:
  103.                 search = [ 'tag:"=' + t + '"' for t in tags.split(',') ]
  104.             
  105.         elif type in ('author', 'authors'):
  106.             authors = idx.model().db.authors(row)
  107.             if authors:
  108.                 search = [ 'author:"=' + a.strip().replace('|', ',') + '"' for a in authors.split(',') ]
  109.                 join = ' or '
  110.             
  111.         
  112.         if search:
  113.             self.search.set_search_string(join.join(search))
  114.         
  115.  
  116.     
  117.     def search_done(self, view, ok):
  118.         if view is self.current_view():
  119.             self.search.search_done(ok)
  120.             self.set_number_of_books_shown()
  121.         
  122.  
  123.  
  124.  
  125. class LibraryWidget(Splitter):
  126.     
  127.     def __init__(self, parent):
  128.         orientation = Qt.Vertical
  129.         if config['gui_layout'] == 'narrow':
  130.             orientation = None if is_widescreen() else Qt.Vertical
  131.         
  132.         idx = None if orientation == Qt.Vertical else 1
  133.         size = None if orientation == Qt.Vertical else 550
  134.         Splitter.__init__(self, 'cover_browser_splitter', _('Cover Browser'), I('cover_flow.svg'), orientation = orientation, parent = parent, connect_button = not config['separate_cover_flow'], side_index = idx, initial_side_size = size, initial_show = False)
  135.         parent.library_view = BooksView(parent)
  136.         parent.library_view.setObjectName('library_view')
  137.         self.addWidget(parent.library_view)
  138.  
  139.  
  140.  
  141. class Stack(QStackedWidget):
  142.     
  143.     def __init__(self, parent):
  144.         QStackedWidget.__init__(self, parent)
  145.         parent.cb_splitter = LibraryWidget(parent)
  146.         self.tb_widget = TagBrowserWidget(parent)
  147.         parent.tb_splitter = Splitter('tag_browser_splitter', _('Tag Browser'), I('tags.svg'), parent = parent, side_index = 0, initial_side_size = 200)
  148.         parent.tb_splitter.addWidget(self.tb_widget)
  149.         parent.tb_splitter.addWidget(parent.cb_splitter)
  150.         parent.tb_splitter.setCollapsible(parent.tb_splitter.other_index, False)
  151.         self.addWidget(parent.tb_splitter)
  152.         for x in ('memory', 'card_a', 'card_b'):
  153.             name = x + '_view'
  154.             w = DeviceBooksView(parent)
  155.             setattr(parent, name, w)
  156.             self.addWidget(w)
  157.             w.setObjectName(name)
  158.         
  159.  
  160.  
  161.  
  162. class StatusBar(QStatusBar):
  163.     
  164.     def __init__(self, parent = None):
  165.         QStatusBar.__init__(self, parent)
  166.         self.default_message = __appname__ + ' ' + _('version') + ' ' + self.get_version() + ' ' + _('created by Kovid Goyal')
  167.         self.device_string = ''
  168.         self.update_label = QLabel('')
  169.         self.update_label.setOpenExternalLinks(True)
  170.         self.addPermanentWidget(self.update_label)
  171.         self.update_label.setVisible(False)
  172.         self._font = QFont()
  173.         self._font.setBold(True)
  174.         self.setFont(self._font)
  175.  
  176.     
  177.     def initialize(self, systray = None):
  178.         self.systray = systray
  179.         self.notifier = get_notifier(systray)
  180.         self.messageChanged.connect(self.message_changed, type = Qt.QueuedConnection)
  181.         self.message_changed('')
  182.  
  183.     
  184.     def device_connected(self, devname):
  185.         self.device_string = _('Connected ') + devname
  186.         self.clearMessage()
  187.  
  188.     
  189.     def device_disconnected(self):
  190.         self.device_string = ''
  191.         self.clearMessage()
  192.  
  193.     
  194.     def new_version_available(self, ver, url):
  195.         msg = u'<span style="color:red; font-weight: bold">%s: <a href="%s">%s<a></span>' % (_('Update found'), url, ver)
  196.         self.update_label.setText(msg)
  197.         self.update_label.setCursor(Qt.PointingHandCursor)
  198.         self.update_label.setVisible(True)
  199.  
  200.     
  201.     def get_version(self):
  202.         dv = os.environ.get('CALIBRE_DEVELOP_FROM', None)
  203.         v = __version__
  204.         if getattr(sys, 'frozen', False) and dv and os.path.abspath(dv) in sys.path:
  205.             v += '*'
  206.         
  207.         return v
  208.  
  209.     
  210.     def show_message(self, msg, timeout = 0):
  211.         self.showMessage(msg, timeout)
  212.         if self.notifier is not None and not config['disable_tray_notification']:
  213.             if isosx and isinstance(msg, unicode):
  214.                 
  215.                 try:
  216.                     msg = msg.encode(preferred_encoding)
  217.                 except UnicodeEncodeError:
  218.                     msg = msg.encode('utf-8')
  219.                 except:
  220.                     None<EXCEPTION MATCH>UnicodeEncodeError
  221.                 
  222.  
  223.             None<EXCEPTION MATCH>UnicodeEncodeError
  224.             self.notifier(msg)
  225.         
  226.  
  227.     
  228.     def clear_message(self):
  229.         self.clearMessage()
  230.  
  231.     
  232.     def message_changed(self, msg):
  233.         if not msg and msg.isEmpty() and msg.isNull() or not unicode(msg).strip():
  234.             extra = ''
  235.             if self.device_string:
  236.                 extra = ' ..::.. ' + self.device_string
  237.             
  238.             self.showMessage(self.default_message + extra)
  239.         
  240.  
  241.  
  242.  
  243. class LayoutMixin(object):
  244.     
  245.     def __init__(self):
  246.         if config['gui_layout'] == 'narrow':
  247.             self.book_details = BookDetails(False, self)
  248.             self.stack = Stack(self)
  249.             self.bd_splitter = Splitter('book_details_splitter', _('Book Details'), I('book.svg'), orientation = Qt.Vertical, parent = self, side_index = 1)
  250.             self.bd_splitter.addWidget(self.stack)
  251.             self.bd_splitter.addWidget(self.book_details)
  252.             self.bd_splitter.setCollapsible(self.bd_splitter.other_index, False)
  253.             self.centralwidget.layout().addWidget(self.bd_splitter)
  254.         else:
  255.             self.bd_splitter = Splitter('book_details_splitter', _('Book Details'), I('book.svg'), initial_side_size = 200, orientation = Qt.Horizontal, parent = self, side_index = 1)
  256.             self.stack = Stack(self)
  257.             self.bd_splitter.addWidget(self.stack)
  258.             self.book_details = BookDetails(True, self)
  259.             self.bd_splitter.addWidget(self.book_details)
  260.             self.bd_splitter.setCollapsible(self.bd_splitter.other_index, False)
  261.             self.bd_splitter.setSizePolicy(QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding))
  262.             self.centralwidget.layout().addWidget(self.bd_splitter)
  263.         self.status_bar = StatusBar(self)
  264.         for x in ('cb', 'tb', 'bd'):
  265.             button = getattr(self, x + '_splitter').button
  266.             button.setIconSize(QSize(24, 24))
  267.             self.status_bar.addPermanentWidget(button)
  268.         
  269.         self.status_bar.addPermanentWidget(self.jobs_button)
  270.         self.setStatusBar(self.status_bar)
  271.  
  272.     
  273.     def finalize_layout(self):
  274.         self.status_bar.initialize(self.system_tray_icon)
  275.         self.book_details.show_book_info.connect(self.show_book_info)
  276.         self.book_details.files_dropped.connect(self.files_dropped_on_book)
  277.         self.book_details.open_containing_folder.connect(self.view_folder_for_id)
  278.         self.book_details.view_specific_format.connect(self.view_format_by_id)
  279.         m = self.library_view.model()
  280.         if m.rowCount(None) > 0:
  281.             self.library_view.set_current_row(0)
  282.             m.current_changed(self.library_view.currentIndex(), self.library_view.currentIndex())
  283.         
  284.         self.library_view.setFocus(Qt.OtherFocusReason)
  285.  
  286.     
  287.     def save_layout_state(self):
  288.         for x in ('library', 'memory', 'card_a', 'card_b'):
  289.             getattr(self, x + '_view').save_state()
  290.         
  291.         for x in ('cb', 'tb', 'bd'):
  292.             getattr(self, x + '_splitter').save_state()
  293.         
  294.  
  295.     
  296.     def read_layout_settings(self):
  297.         for x in ('cb', 'tb', 'bd'):
  298.             getattr(self, x + '_splitter').restore_state()
  299.         
  300.  
  301.  
  302.