home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2011 January / maximum-cd-2011-01.iso / DiscContents / calibre-0.7.26.msi / file_1400 (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2010-10-31  |  32.4 KB  |  855 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. from __future__ import with_statement
  5. __license__ = 'GPL v3'
  6. __copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>'
  7. __docformat__ = 'restructuredtext en'
  8. import os
  9. import traceback
  10. import re
  11. from Queue import Empty, Queue
  12. from contextlib import closing
  13. from PyQt4.Qt import QWizard, QWizardPage, QPixmap, Qt, QAbstractListModel, QVariant, QItemSelectionModel, SIGNAL, QObject, QTimer
  14. from calibre import __appname__, patheq
  15. from calibre.library.database2 import LibraryDatabase2
  16. from calibre.library.move import MoveLibrary
  17. from calibre.constants import filesystem_encoding
  18. from calibre.gui2.wizard.send_email import smtp_prefs
  19. from calibre.gui2.wizard.device_ui import Ui_WizardPage as DeviceUI
  20. from calibre.gui2.wizard.library_ui import Ui_WizardPage as LibraryUI
  21. from calibre.gui2.wizard.finish_ui import Ui_WizardPage as FinishUI
  22. from calibre.gui2.wizard.kindle_ui import Ui_WizardPage as KindleUI
  23. from calibre.gui2.wizard.stanza_ui import Ui_WizardPage as StanzaUI
  24. from calibre.gui2 import min_available_height, available_width
  25. from calibre.utils.config import dynamic, prefs
  26. from calibre.gui2 import NONE, choose_dir, error_dialog
  27. from calibre.gui2.dialogs.progress import ProgressDialog
  28.  
  29. class Device(object):
  30.     output_profile = 'default'
  31.     output_format = 'EPUB'
  32.     name = 'Default'
  33.     manufacturer = 'Default'
  34.     id = 'default'
  35.     
  36.     def set_output_profile(cls):
  37.         if cls.output_profile:
  38.             load_defaults = load_defaults
  39.             save_defaults = save_defaults
  40.             import calibre.ebooks.conversion.config
  41.             recs = load_defaults('page_setup')
  42.             recs['output_profile'] = cls.output_profile
  43.             save_defaults('page_setup', recs)
  44.         
  45.  
  46.     set_output_profile = classmethod(set_output_profile)
  47.     
  48.     def set_output_format(cls):
  49.         if cls.output_format:
  50.             prefs.set('output_format', cls.output_format)
  51.         
  52.  
  53.     set_output_format = classmethod(set_output_format)
  54.     
  55.     def commit(cls):
  56.         cls.set_output_profile()
  57.         cls.set_output_format()
  58.  
  59.     commit = classmethod(commit)
  60.  
  61.  
  62. class Kindle(Device):
  63.     output_profile = 'kindle'
  64.     output_format = 'MOBI'
  65.     name = 'Kindle 1, 2 or 3'
  66.     manufacturer = 'Amazon'
  67.     id = 'kindle'
  68.  
  69.  
  70. class JetBook(Device):
  71.     output_profile = 'jetbook5'
  72.     output_format = 'EPUB'
  73.     name = 'JetBook'
  74.     manufacturer = 'Ectaco'
  75.     id = 'jetbook'
  76.  
  77.  
  78. class JetBookMini(Device):
  79.     output_profile = 'jetbook5'
  80.     output_format = 'FB2'
  81.     name = 'JetBook Mini'
  82.     manufacturer = 'Ectaco'
  83.     id = 'jetbookmini'
  84.  
  85.  
  86. class KindleDX(Kindle):
  87.     output_profile = 'kindle_dx'
  88.     output_format = 'MOBI'
  89.     name = 'Kindle DX'
  90.     id = 'kindledx'
  91.  
  92.  
  93. class Sony505(Device):
  94.     output_profile = 'sony'
  95.     name = 'All other SONY devices'
  96.     output_format = 'EPUB'
  97.     manufacturer = 'SONY'
  98.     id = 'prs505'
  99.  
  100.  
  101. class Kobo(Device):
  102.     name = 'Kobo Reader'
  103.     manufacturer = 'Kobo'
  104.     output_profile = 'kobo'
  105.     output_format = 'EPUB'
  106.     id = 'kobo'
  107.  
  108.  
  109. class Booq(Device):
  110.     name = 'Booq Reader'
  111.     manufacturer = 'Booq'
  112.     output_profile = 'sony'
  113.     output_format = 'EPUB'
  114.     id = 'booq'
  115.  
  116.  
  117. class TheBook(Device):
  118.     name = 'The Book'
  119.     manufacturer = 'Augen'
  120.     output_profile = 'sony'
  121.     output_format = 'EPUB'
  122.     id = 'thebook'
  123.  
  124.  
  125. class Avant(Booq):
  126.     name = 'Booq Avant'
  127.  
  128.  
  129. class Sony300(Sony505):
  130.     name = 'SONY Reader Pocket Edition'
  131.     id = 'prs300'
  132.     output_profile = 'sony300'
  133.  
  134.  
  135. class Sony900(Sony505):
  136.     name = 'SONY Reader Daily Edition'
  137.     id = 'prs900'
  138.     output_profile = 'sony900'
  139.  
  140.  
  141. class Nook(Sony505):
  142.     id = 'nook'
  143.     name = 'Nook'
  144.     manufacturer = 'Barnes & Noble'
  145.     output_profile = 'nook'
  146.  
  147.  
  148. class CybookG3(Device):
  149.     name = 'Cybook Gen 3'
  150.     output_format = 'MOBI'
  151.     output_profile = 'cybookg3'
  152.     manufacturer = 'Bookeen'
  153.     id = 'cybookg3'
  154.  
  155.  
  156. class CybookOpus(CybookG3):
  157.     name = 'Cybook Opus'
  158.     output_format = 'EPUB'
  159.     output_profile = 'cybook_opus'
  160.     id = 'cybook_opus'
  161.  
  162.  
  163. class PocketBook360(CybookOpus):
  164.     manufacturer = 'PocketBook'
  165.     name = 'PocketBook 360'
  166.     id = 'pocketbook360'
  167.     output_profile = 'cybook_opus'
  168.  
  169.  
  170. class PocketBook(CybookG3):
  171.     manufacturer = 'PocketBook'
  172.     name = 'PocketBook 301/302'
  173.     id = 'pocketbook'
  174.     output_profile = 'cybookg3'
  175.  
  176.  
  177. class iPhone(Device):
  178.     name = 'iPad or iPhone/iTouch + Stanza'
  179.     output_format = 'EPUB'
  180.     manufacturer = 'Apple'
  181.     id = 'iphone'
  182.  
  183.  
  184. class Android(Device):
  185.     name = 'Adroid phone + WordPlayer/Aldiko'
  186.     output_format = 'EPUB'
  187.     manufacturer = 'Android'
  188.     id = 'android'
  189.  
  190.  
  191. class HanlinV3(Device):
  192.     name = 'Hanlin V3'
  193.     output_format = 'EPUB'
  194.     output_profile = 'hanlinv3'
  195.     manufacturer = 'Jinke'
  196.     id = 'hanlinv3'
  197.  
  198.  
  199. class HanlinV5(HanlinV3):
  200.     name = 'Hanlin V5'
  201.     output_profile = 'hanlinv5'
  202.     id = 'hanlinv5'
  203.  
  204.  
  205. class BeBook(HanlinV3):
  206.     name = 'BeBook'
  207.     manufacturer = 'Endless Ideas'
  208.     id = 'bebook'
  209.  
  210.  
  211. class BeBookMini(HanlinV5):
  212.     name = 'BeBook Mini'
  213.     manufacturer = 'Endless Ideas'
  214.     id = 'bebook_mini'
  215.  
  216.  
  217. class EZReader(HanlinV3):
  218.     name = 'EZReader'
  219.     manufacturer = 'Astak'
  220.     id = 'ezreader'
  221.  
  222.  
  223. class EZReaderPP(HanlinV5):
  224.     name = 'EZReader Pocket Pro'
  225.     manufacturer = 'Astak'
  226.     id = 'ezreader_pp'
  227.  
  228.  
  229. class Bambook(Device):
  230.     name = 'Sanda Bambook'
  231.     output_format = 'SNB'
  232.     manufacturer = 'Sanda'
  233.     id = 'bambook'
  234.     output_profile = 'bambook'
  235.  
  236.  
  237. def get_devices():
  238.     for x in globals().values():
  239.         if isinstance(x, type) and issubclass(x, Device):
  240.             yield x
  241.             continue
  242.     
  243.  
  244.  
  245. def get_manufacturers():
  246.     mans = set([])
  247.     for x in get_devices():
  248.         mans.add(x.manufacturer)
  249.     
  250.     if 'Default' in mans:
  251.         mans.remove('Default')
  252.     
  253.     return [
  254.         'Default'] + sorted(mans)
  255.  
  256.  
  257. def get_devices_of(manufacturer):
  258.     ans = _[1]
  259.     return sorted(ans, cmp = (lambda x, y: cmp(x.name, y.name)))
  260.  
  261.  
  262. class ManufacturerModel(QAbstractListModel):
  263.     
  264.     def __init__(self):
  265.         QAbstractListModel.__init__(self)
  266.         self.manufacturers = get_manufacturers()
  267.  
  268.     
  269.     def rowCount(self, p):
  270.         return len(self.manufacturers)
  271.  
  272.     
  273.     def columnCount(self, p):
  274.         return 1
  275.  
  276.     
  277.     def data(self, index, role):
  278.         if role == Qt.DisplayRole:
  279.             return QVariant(self.manufacturers[index.row()])
  280.         if role == Qt.UserRole:
  281.             return self.manufacturers[index.row()]
  282.         return NONE
  283.  
  284.     
  285.     def index_of(self, man):
  286.         for i, x in enumerate(self.manufacturers):
  287.             if x == man:
  288.                 return self.index(i)
  289.         
  290.  
  291.  
  292.  
  293. class DeviceModel(QAbstractListModel):
  294.     
  295.     def __init__(self, manufacturer):
  296.         QAbstractListModel.__init__(self)
  297.         self.devices = get_devices_of(manufacturer)
  298.  
  299.     
  300.     def rowCount(self, p):
  301.         return len(self.devices)
  302.  
  303.     
  304.     def columnCount(self, p):
  305.         return 1
  306.  
  307.     
  308.     def data(self, index, role):
  309.         if role == Qt.DisplayRole:
  310.             return QVariant(self.devices[index.row()].name)
  311.         if role == Qt.UserRole:
  312.             return self.devices[index.row()]
  313.         return NONE
  314.  
  315.     
  316.     def index_of(self, dev):
  317.         for i, device in enumerate(self.devices):
  318.             if device is dev:
  319.                 return self.index(i)
  320.         
  321.  
  322.  
  323.  
  324. class KindlePage(QWizardPage, KindleUI):
  325.     ID = 3
  326.     
  327.     def __init__(self):
  328.         QWizardPage.__init__(self)
  329.         self.setupUi(self)
  330.  
  331.     
  332.     def initializePage(self):
  333.         opts = smtp_prefs().parse()
  334.         for x in opts.accounts.keys():
  335.             if x.strip().endswith('@kindle.com'):
  336.                 self.to_address.setText(x)
  337.                 continue
  338.         
  339.         
  340.         def x():
  341.             t = unicode(self.to_address.text())
  342.             if t.strip():
  343.                 return t.strip()
  344.  
  345.         self.send_email_widget.initialize(x)
  346.  
  347.     
  348.     def commit(self):
  349.         x = unicode(self.to_address.text()).strip()
  350.         parts = x.split('@')
  351.         if len(parts) < 2 or not parts[0]:
  352.             return None
  353.  
  354.     
  355.     def nextId(self):
  356.         return FinishPage.ID
  357.  
  358.  
  359.  
  360. class StanzaPage(QWizardPage, StanzaUI):
  361.     ID = 5
  362.     
  363.     def __init__(self):
  364.         QWizardPage.__init__(self)
  365.         self.setupUi(self)
  366.         self.connect(self.content_server, SIGNAL('stateChanged(int)'), self.set_port)
  367.  
  368.     
  369.     def initializePage(self):
  370.         config = config
  371.         import calibre.gui2
  372.         yes = config['autolaunch_server']
  373.         self.content_server.setChecked(yes)
  374.         self.set_port()
  375.  
  376.     
  377.     def nextId(self):
  378.         return FinishPage.ID
  379.  
  380.     
  381.     def commit(self):
  382.         load_defaults = load_defaults
  383.         save_defaults = save_defaults
  384.         import calibre.ebooks.conversion.config
  385.         recs = load_defaults('comic_input')
  386.         recs['dont_grayscale'] = True
  387.         save_defaults('comic_input', recs)
  388.         p = self.set_port()
  389.         if p is not None:
  390.             server_config = server_config
  391.             import calibre.library.server
  392.             c = server_config()
  393.             c.set('port', p)
  394.         
  395.  
  396.     
  397.     def set_port(self, *args):
  398.         if not self.content_server.isChecked():
  399.             return None
  400.         import socket
  401.         s = socket.socket()
  402.         closing(s).__enter__()
  403.         
  404.         try:
  405.             for p in range(8080, 8100):
  406.                 
  407.                 try:
  408.                     s.bind(('0.0.0.0', p))
  409.                     t = unicode(self.instructions.text())
  410.                     t = re.sub(':\\d+', ':' + str(p), t)
  411.                     self.instructions.setText(t)
  412.                     return p
  413.                 continue
  414.                 closing(s)
  415.                 self.content_server.isChecked()
  416.                 continue
  417.                 continue
  418.  
  419.         finally:
  420.             pass
  421.  
  422.  
  423.  
  424.  
  425. class WordPlayerPage(StanzaPage):
  426.     ID = 6
  427.     
  428.     def __init__(self):
  429.         StanzaPage.__init__(self)
  430.         self.label.setText('<p>' + _('If you use the WordPlayer e-book app on your Android phone, you can access your calibre book collection directly on the device. To do this you have to turn on the content server.'))
  431.         self.instructions.setText('<p>' + _('Remember to leave calibre running as the server only runs as long as calibre is running.') + '<br><br>' + _('You have to add the URL http://myhostname:8080 as your calibre library in WordPlayer. Here myhostname should be the fully qualified hostname or the IP address of the computer calibre is running on.'))
  432.  
  433.  
  434.  
  435. class DevicePage(QWizardPage, DeviceUI):
  436.     ID = 2
  437.     
  438.     def __init__(self):
  439.         QWizardPage.__init__(self)
  440.         self.setupUi(self)
  441.         self.registerField('manufacturer', self.manufacturer_view)
  442.         self.registerField('device', self.device_view)
  443.  
  444.     
  445.     def initializePage(self):
  446.         self.man_model = ManufacturerModel()
  447.         self.manufacturer_view.setModel(self.man_model)
  448.         previous = dynamic.get('welcome_wizard_device', False)
  449.         if previous:
  450.             previous = _[1]
  451.             previous = previous[0]
  452.         else:
  453.             previous = Device
  454.         idx = self.man_model.index_of(previous.manufacturer)
  455.         if idx is None:
  456.             idx = self.man_model.index_of(Device.manufacturer)
  457.             previous = Device
  458.         
  459.         self.manufacturer_view.selectionModel().select(idx, QItemSelectionModel.Select)
  460.         self.dev_model = DeviceModel(self.man_model.data(idx, Qt.UserRole))
  461.         idx = self.dev_model.index_of(previous)
  462.         self.device_view.setModel(self.dev_model)
  463.         self.device_view.selectionModel().select(idx, QItemSelectionModel.Select)
  464.         self.connect(self.manufacturer_view.selectionModel(), SIGNAL('selectionChanged(QItemSelection,QItemSelection)'), self.manufacturer_changed)
  465.  
  466.     
  467.     def manufacturer_changed(self, current, previous):
  468.         new = list(current.indexes())[0]
  469.         man = self.man_model.data(new, Qt.UserRole)
  470.         self.dev_model = DeviceModel(man)
  471.         self.device_view.setModel(self.dev_model)
  472.         self.device_view.selectionModel().select(self.dev_model.index(0), QItemSelectionModel.Select)
  473.  
  474.     
  475.     def commit(self):
  476.         idx = list(self.device_view.selectionModel().selectedIndexes())[0]
  477.         dev = self.dev_model.data(idx, Qt.UserRole)
  478.         dev.commit()
  479.         dynamic.set('welcome_wizard_device', dev.id)
  480.  
  481.     
  482.     def nextId(self):
  483.         idx = list(self.device_view.selectionModel().selectedIndexes())[0]
  484.         dev = self.dev_model.data(idx, Qt.UserRole)
  485.         if dev in (Kindle, KindleDX):
  486.             return KindlePage.ID
  487.         if dev is iPhone:
  488.             return StanzaPage.ID
  489.         if dev is Android:
  490.             return WordPlayerPage.ID
  491.         return FinishPage.ID
  492.  
  493.  
  494.  
  495. class MoveMonitor(QObject):
  496.     
  497.     def __init__(self, worker, rq, callback, parent):
  498.         QObject.__init__(self, parent)
  499.         self.worker = worker
  500.         self.rq = rq
  501.         self.callback = callback
  502.         self.parent = parent
  503.         self.worker.start()
  504.         self.dialog = ProgressDialog(_('Moving library...'), '', max = self.worker.total, parent = parent)
  505.         self.dialog.button_box.setDisabled(True)
  506.         self.dialog.setModal(True)
  507.         self.dialog.show()
  508.         self.timer = QTimer(self)
  509.         self.connect(self.timer, SIGNAL('timeout()'), self.check)
  510.         self.timer.start(200)
  511.  
  512.     
  513.     def check(self):
  514.         if self.worker.is_alive():
  515.             self.update()
  516.         else:
  517.             self.timer.stop()
  518.             self.dialog.hide()
  519.             if self.worker.failed:
  520.                 error_dialog(self.parent, _('Failed to move library'), _('Failed to move library'), self.worker.details, show = True)
  521.                 return self.callback(None)
  522.             return self.callback(self.worker.to)
  523.         return self.worker.is_alive()
  524.  
  525.     
  526.     def update(self):
  527.         
  528.         try:
  529.             title = self.rq.get_nowait()[-1]
  530.             self.dialog.value += 1
  531.             self.dialog.set_msg(_('Copied') + ' ' + title)
  532.         except Empty:
  533.             pass
  534.  
  535.  
  536.  
  537.  
  538. class Callback(object):
  539.     
  540.     def __init__(self, callback):
  541.         self.callback = callback
  542.  
  543.     
  544.     def __call__(self, newloc):
  545.         if newloc is not None:
  546.             prefs['library_path'] = newloc
  547.         
  548.         self.callback(newloc)
  549.  
  550.  
  551. _mm = None
  552.  
  553. def move_library(oldloc, newloc, parent, callback_on_complete):
  554.     global _mm
  555.     callback = Callback(callback_on_complete)
  556.     
  557.     try:
  558.         if not os.path.exists(os.path.join(newloc, 'metadata.db')):
  559.             if oldloc and os.access(os.path.join(oldloc, 'metadata.db'), os.R_OK):
  560.                 
  561.                 try:
  562.                     db = LibraryDatabase2(oldloc)
  563.                 except:
  564.                     return move_library(None, newloc, parent, callback)
  565.  
  566.                 rq = Queue()
  567.                 m = MoveLibrary(oldloc, newloc, len(db.get_top_level_move_items()[0]), rq)
  568.                 _mm = MoveMonitor(m, rq, callback, parent)
  569.                 return None
  570.             os.access(os.path.join(oldloc, 'metadata.db'), os.R_OK)
  571.             db = LibraryDatabase2(newloc)
  572.             callback(newloc)
  573.             return None
  574.         os.path.exists(os.path.join(newloc, 'metadata.db'))
  575.         
  576.         try:
  577.             LibraryDatabase2(newloc)
  578.         except Exception:
  579.             err = None
  580.             det = traceback.format_exc()
  581.             error_dialog(parent, _('Invalid database'), _('<p>An invalid library already exists at %s, delete it before trying to move the existing library.<br>Error: %s') % (newloc, str(err)), det, show = True)
  582.             callback(None)
  583.             return None
  584.  
  585.         callback(newloc)
  586.         return None
  587.     except Exception:
  588.         err = None
  589.         det = traceback.format_exc()
  590.         error_dialog(parent, _('Could not move library'), unicode(err), det, show = True)
  591.  
  592.     callback(None)
  593.  
  594.  
  595. class LibraryPage(QWizardPage, LibraryUI):
  596.     ID = 1
  597.     
  598.     def __init__(self):
  599.         QWizardPage.__init__(self)
  600.         self.setupUi(self)
  601.         self.registerField('library_location', self.location)
  602.         self.connect(self.button_change, SIGNAL('clicked()'), self.change)
  603.         self.init_languages()
  604.         self.connect(self.language, SIGNAL('currentIndexChanged(int)'), self.change_language)
  605.         self.connect(self.location, SIGNAL('textChanged(QString)'), self.location_text_changed)
  606.  
  607.     
  608.     def location_text_changed(self, newtext):
  609.         self.emit(SIGNAL('completeChanged()'))
  610.  
  611.     
  612.     def init_languages(self):
  613.         self.language.blockSignals(True)
  614.         self.language.clear()
  615.         available_translations = available_translations
  616.         get_language = get_language
  617.         get_lang = get_lang
  618.         import calibre.utils.localization
  619.         lang = get_lang()
  620.         if lang is None or lang not in available_translations():
  621.             lang = 'en'
  622.         
  623.         self.language.addItem(get_language(lang), QVariant(lang))
  624.         items = _[1]
  625.         items.sort(cmp = (lambda x, y: cmp(x[1], y[1])))
  626.         for item in items:
  627.             self.language.addItem(item[1], QVariant(item[0]))
  628.         
  629.         self.language.blockSignals(False)
  630.         prefs['language'] = str(self.language.itemData(self.language.currentIndex()).toString())
  631.  
  632.     
  633.     def change_language(self, idx):
  634.         prefs['language'] = str(self.language.itemData(self.language.currentIndex()).toString())
  635.         import __builtin__
  636.         
  637.         __builtin__.__dict__['_'] = lambda x: x
  638.         set_translators = set_translators
  639.         import calibre.utils.localization
  640.         qt_app = qt_app
  641.         import calibre.gui2
  642.         set_translators()
  643.         qt_app.load_translations()
  644.         self.emit(SIGNAL('retranslate()'))
  645.         self.init_languages()
  646.         
  647.         try:
  648.             if prefs['language'].lower().startswith('zh'):
  649.                 enable_plugin = enable_plugin
  650.                 import calibre.customize.ui
  651.                 for name in ('Douban Books', 'Douban.com covers'):
  652.                     enable_plugin(name)
  653.                 
  654.         except:
  655.             pass
  656.  
  657.  
  658.     
  659.     def is_library_dir_suitable(self, x):
  660.         if not LibraryDatabase2.exists_at(x):
  661.             pass
  662.         return not os.listdir(x)
  663.  
  664.     
  665.     def validatePage(self):
  666.         newloc = unicode(self.location.text())
  667.         if not self.is_library_dir_suitable(newloc):
  668.             self.show_library_dir_error(newloc)
  669.             return False
  670.         return True
  671.  
  672.     
  673.     def change(self):
  674.         x = choose_dir(self, 'database location dialog', _('Select location for books'))
  675.         if x:
  676.             if self.is_library_dir_suitable(x):
  677.                 self.location.setText(x)
  678.             else:
  679.                 self.show_library_dir_error(x)
  680.         
  681.  
  682.     
  683.     def show_library_dir_error(self, x):
  684.         if not isinstance(x, unicode):
  685.             
  686.             try:
  687.                 x = x.decode(filesystem_encoding)
  688.             x = unicode(repr(x))
  689.  
  690.         
  691.         error_dialog(self, _('Bad location'), _('You must choose an empty folder for the calibre library. %s is not empty.') % x, show = True)
  692.  
  693.     
  694.     def initializePage(self):
  695.         lp = prefs['library_path']
  696.         self.default_library_name = None
  697.         if not lp:
  698.             fname = _('Calibre Library')
  699.             if isinstance(fname, unicode):
  700.                 
  701.                 try:
  702.                     fname = fname.encode(filesystem_encoding)
  703.                 fname = 'Calibre Library'
  704.  
  705.             
  706.             lp = os.path.expanduser('~' + os.sep + fname)
  707.             self.default_library_name = lp
  708.             if not os.path.exists(lp):
  709.                 
  710.                 try:
  711.                     os.makedirs(lp)
  712.                 traceback.print_exc()
  713.                 lp = os.path.expanduser('~')
  714.  
  715.             
  716.         
  717.         self.location.setText(lp)
  718.  
  719.     
  720.     def isComplete(self):
  721.         
  722.         try:
  723.             lp = unicode(self.location.text())
  724.             if bool(lp) and os.path.exists(lp) and os.path.isdir(lp):
  725.                 pass
  726.             ans = os.access(lp, os.W_OK)
  727.         except:
  728.             ans = False
  729.  
  730.         return ans
  731.  
  732.     
  733.     def commit(self, completed):
  734.         oldloc = prefs['library_path']
  735.         newloc = unicode(self.location.text())
  736.         
  737.         try:
  738.             newloce = newloc.encode(filesystem_encoding)
  739.             if self.default_library_name is not None and os.path.exists(self.default_library_name) and not os.listdir(self.default_library_name) and newloce != self.default_library_name:
  740.                 os.rmdir(self.default_library_name)
  741.         except:
  742.             pass
  743.  
  744.         if not os.path.exists(newloc):
  745.             os.mkdir(newloc)
  746.         
  747.         if not patheq(oldloc, newloc):
  748.             move_library(oldloc, newloc, self.wizard(), completed)
  749.             return True
  750.         return False
  751.  
  752.     
  753.     def nextId(self):
  754.         return DevicePage.ID
  755.  
  756.  
  757.  
  758. class FinishPage(QWizardPage, FinishUI):
  759.     ID = 4
  760.     
  761.     def __init__(self):
  762.         QWizardPage.__init__(self)
  763.         self.setupUi(self)
  764.  
  765.     
  766.     def nextId(self):
  767.         return -1
  768.  
  769.     
  770.     def commit(self):
  771.         pass
  772.  
  773.  
  774.  
  775. class Wizard(QWizard):
  776.     
  777.     def __init__(self, parent):
  778.         QWizard.__init__(self, parent)
  779.         self.setWindowTitle(__appname__ + ' ' + _('welcome wizard'))
  780.         p = QPixmap()
  781.         p.loadFromData(open(P('content_server/calibre.png'), 'rb').read())
  782.         self.setPixmap(self.LogoPixmap, p.scaledToHeight(80, Qt.SmoothTransformation))
  783.         self.setPixmap(self.WatermarkPixmap, QPixmap(I('welcome_wizard.png')))
  784.         self.setPixmap(self.BackgroundPixmap, QPixmap(I('wizard.png')))
  785.         self.device_page = DevicePage()
  786.         self.library_page = LibraryPage()
  787.         self.connect(self.library_page, SIGNAL('retranslate()'), self.retranslate)
  788.         self.finish_page = FinishPage()
  789.         self.set_finish_text()
  790.         self.kindle_page = KindlePage()
  791.         self.stanza_page = StanzaPage()
  792.         self.word_player_page = WordPlayerPage()
  793.         self.setPage(self.library_page.ID, self.library_page)
  794.         self.setPage(self.device_page.ID, self.device_page)
  795.         self.setPage(self.finish_page.ID, self.finish_page)
  796.         self.setPage(self.kindle_page.ID, self.kindle_page)
  797.         self.setPage(self.stanza_page.ID, self.stanza_page)
  798.         self.setPage(self.word_player_page.ID, self.word_player_page)
  799.         self.device_extra_page = None
  800.         nh = min_available_height() - 75
  801.         nw = available_width() - 30
  802.         if nh < 0:
  803.             nh = 580
  804.         
  805.         if nw < 0:
  806.             nw = 400
  807.         
  808.         nh = min(400, nh)
  809.         nw = min(580, nw)
  810.         self.resize(nw, nh)
  811.  
  812.     
  813.     def retranslate(self):
  814.         for pid in self.pageIds():
  815.             page = self.page(pid)
  816.             page.retranslateUi(page)
  817.         
  818.         self.set_finish_text()
  819.  
  820.     
  821.     def accept(self):
  822.         pages = map(self.page, self.visitedPages())
  823.         for page in pages:
  824.             if page is not self.library_page:
  825.                 page.commit()
  826.                 continue
  827.         
  828.         if not self.library_page.commit(self.completed):
  829.             self.completed(None)
  830.         
  831.  
  832.     
  833.     def completed(self, newloc):
  834.         return QWizard.accept(self)
  835.  
  836.     
  837.     def set_finish_text(self, *args):
  838.         bt = unicode(self.buttonText(self.FinishButton)).replace('&', '')
  839.         t = unicode(self.finish_page.finish_text.text())
  840.         if '%s' in t:
  841.             self.finish_page.finish_text.setText(t % bt)
  842.         
  843.  
  844.  
  845.  
  846. def wizard(parent = None):
  847.     w = Wizard(parent)
  848.     return w
  849.  
  850. if __name__ == '__main__':
  851.     from calibre.gui2 import Application
  852.     app = Application([])
  853.     wizard().exec_()
  854.  
  855.