Example #1
0
    def slotEditUser(self, item=None):
        if not item:
            item = self.ui.userList.currentItem()
        self.ui.userList.setCurrentItem(item)
        user = item.getUser()
        if user.uid > -1:
            self.ui.userIDCheck.setChecked(True)
            self.ui.userID.setValue(user.uid)
        self.ui.username.setText(QString(user.username))
        self.ui.realname.setText(QString(user.realname))
        self.ui.pass1.setText(QString(user.passwd))
        self.ui.pass2.setText(QString(user.passwd))

        if "wheel" in user.groups:
            self.ui.admin.setChecked(True)
        else:
            self.ui.admin.setChecked(False)

        self.ui.noPass.setChecked(user.no_password)

        self.edititemindex = self.ui.userList.currentRow()
        self.ui.createButton.setText(_("Update"))
        icon = QIcon()
        icon.addPixmap(QPixmap(":/gui/pics/tick.png"), QIcon.Normal, QIcon.Off)
        self.ui.createButton.setIcon(icon)
        self.ui.cancelButton.setVisible(self.ui.createButton.isVisible())
Example #2
0
    def setup_store_checks(self):
        first_run = self.config.get('first_run', True)

        # Add check boxes for each store so the user
        # can disable searching specific stores on a
        # per search basis.
        existing = {}
        for n in self.store_checks:
            existing[n] = self.store_checks[n].isChecked()

        self.store_checks = {}

        stores_check_widget = QWidget()
        store_list_layout = QGridLayout()
        stores_check_widget.setLayout(store_list_layout)

        icon = QIcon(I('donate.png'))
        for i, x in enumerate(sorted(self.gui.istores.keys(), key=lambda x: x.lower())):
            cbox = QCheckBox(x)
            cbox.setChecked(existing.get(x, first_run))
            store_list_layout.addWidget(cbox, i, 0, 1, 1)
            if self.gui.istores[x].base_plugin.affiliate:
                iw = QLabel(self)
                iw.setToolTip('<p>' + _('Buying from this store supports the calibre developer: %s</p>') % self.gui.istores[x].base_plugin.author + '</p>')
                iw.setPixmap(icon.pixmap(16, 16))
                store_list_layout.addWidget(iw, i, 1, 1, 1)
            self.store_checks[x] = cbox
        store_list_layout.setRowStretch(store_list_layout.rowCount(), 10)
        self.store_list.setWidget(stores_check_widget)

        self.config['first_run'] = False
Example #3
0
 def load_menu(self):
     self.store_list_menu.clear()
     icon = QIcon()
     icon.addFile(I('donate.png'), QSize(16, 16))
     for n, p in sorted(self.gui.istores.items(), key=lambda x: x[0].lower()):
         if p.base_plugin.affiliate:
             self.store_list_menu.addAction(icon, n, partial(self.open_store, p))
         else:
             self.store_list_menu.addAction(n, partial(self.open_store, p))
Example #4
0
 def setThemeFromGtk():
     f = QFile(QDir.homePath() + "/.gtkrc-2.0");
     if not f.open(QIODevice.ReadOnly | QIODevice.Text):
         return
     while not f.atEnd():
         l = f.readLine().trimmed();
         if l.startsWith("gtk-icon-theme-name="):
             s = QString(l.split('=')[-1]);
             syslog.syslog( syslog.LOG_DEBUG,
                            "DEBUG  setting gtk theme %s" % str(s));
             QIcon.setThemeName(s.remove('"'));
             break
 def init(self):
     self.initUserList()
     self.initSubredditList()
     if (self._rddtDataExtractor.downloadType is DownloadType.USER_SUBREDDIT_CONSTRAINED):
         self.userSubBtn.setChecked(True)
     elif (self._rddtDataExtractor.downloadType is DownloadType.USER_SUBREDDIT_ALL):
         self.allUserBtn.setChecked(True)
     elif (self._rddtDataExtractor.downloadType is DownloadType.SUBREDDIT_CONTENT):
         self.allSubBtn.setChecked(True)
     icon = QIcon()
     icon.addPixmap(QPixmap("RedditDataExtractor/images/logo.png"), QIcon.Normal, QIcon.Off)
     self.setWindowIcon(icon)
Example #6
0
    def slotAdvanced(self):
        icon_path = None
        if self.ui.scrollArea.isVisible():
            icon_path = ":/gui/pics/expand.png"
            self.time_line.start()
        else:
            self.ui.scrollArea.show()
            icon_path = ":/gui/pics/collapse.png"
            self.time_line.start()

        icon = QIcon()
        icon.addPixmap(QPixmap(icon_path), QIcon.Normal, QIcon.Off)
        self.ui.addMoreUsers.setIcon(icon)
        self.checkUsers()
def _env_imagename_to_QIcon(imagename, _cache = {}): ### to be replaced with env.imagename_to_QIcon for global env or an arg env
    try:
        return _cache[imagename]
    except KeyError:
        pass

    ## pixmap_fname = imagename # stub
    from utilities.icon_utilities import imagename_to_pixmap
    pixmap = imagename_to_pixmap(imagename)
    pixmap_fname = pixmap # will this arg work too?

    res = QIcon()
    res.setPixmap(pixmap_fname, QIcon.Automatic)
    _cache[imagename] = res # memoize, and also keep permanent python reference
    return res
Example #8
0
 def get_service_icon(self, id, name, url):
     icon, st = None, self.app.preferences.settings
     if not st.contains('icon/'+name):
         icon = get_favicon(url)
         if icon:
             icon = QIcon(QPixmap.fromImage(QImage.fromData(icon)))
             print name, "icon loaded?", not icon.isNull()
             if not icon.isNull():
                 st.setValue('icon/'+name, icon)
         else: print "error while loading", name, "icon"
     else:
         icon = st.value('icon/'+name, None)
         if icon: icon = QIcon(icon)
     if icon:
         self.app.preferences.ui.accountsTabWidget.setTabIcon(id, icon)
     return icon
Example #9
0
    def __init__(self, type_, title, msg,
                 det_msg='',
                 q_icon=None,
                 show_copy_button=True,
                 parent=None, default_yes=True):
        QDialog.__init__(self, parent)
        if q_icon is None:
            icon = {
                    self.ERROR : 'error',
                    self.WARNING: 'warning',
                    self.INFO:    'information',
                    self.QUESTION: 'question',
            }[type_]
            icon = 'dialog_%s.png'%icon
            self.icon = QIcon(I(icon))
        else:
            self.icon = q_icon
        self.setupUi(self)

        self.setWindowTitle(title)
        self.setWindowIcon(self.icon)
        self.icon_label.setPixmap(self.icon.pixmap(128, 128))
        self.msg.setText(msg)
        self.det_msg.setPlainText(det_msg)
        self.det_msg.setVisible(False)
        self.toggle_checkbox.setVisible(False)

        if show_copy_button:
            self.ctc_button = self.bb.addButton(_('&Copy to clipboard'),
                    self.bb.ActionRole)
            self.ctc_button.clicked.connect(self.copy_to_clipboard)

        self.show_det_msg = _('Show &details')
        self.hide_det_msg = _('Hide &details')
        self.det_msg_toggle = self.bb.addButton(self.show_det_msg, self.bb.ActionRole)
        self.det_msg_toggle.clicked.connect(self.toggle_det_msg)
        self.det_msg_toggle.setToolTip(
                _('Show detailed information about this error'))

        self.copy_action = QAction(self)
        self.addAction(self.copy_action)
        self.copy_action.setShortcuts(QKeySequence.Copy)
        self.copy_action.triggered.connect(self.copy_to_clipboard)

        self.is_question = type_ == self.QUESTION
        if self.is_question:
            self.bb.setStandardButtons(self.bb.Yes|self.bb.No)
            self.bb.button(self.bb.Yes if default_yes else self.bb.No
                    ).setDefault(True)
            self.default_yes = default_yes
        else:
            self.bb.button(self.bb.Ok).setDefault(True)

        if not det_msg:
            self.det_msg_toggle.setVisible(False)

        self.do_resize()
Example #10
0
    def slotDeleteUser(self):
        if self.ui.userList.currentRow() == self.edititemindex:
            self.resetWidgets()
            self.ui.autoLogin.setCurrentIndex(0)
        _cur = self.ui.userList.currentRow()
        item = self.ui.userList.item(_cur).getUser()
        if item.uid in self.used_ids:
            self.used_ids.remove(item.uid)
        self.ui.userList.takeItem(_cur)
        self.ui.autoLogin.removeItem(_cur + 1)
        self.ui.createButton.setText(_("Add"))

        icon = QIcon()
        icon.addPixmap(QPixmap(":/gui/pics/user-group-new.png"), QIcon.Normal, QIcon.Off)
        self.ui.createButton.setIcon(icon)

        self.ui.cancelButton.hide()
        self.checkUsers()
Example #11
0
 def resetWidgets(self):
     # clear all
     self.edititemindex = None
     self.ui.username.clear()
     self.ui.realname.clear()
     self.ui.pass1.clear()
     self.ui.pass2.clear()
     self.ui.admin.setChecked(False)
     self.ui.noPass.setChecked(False)
     self.ui.userIDCheck.setChecked(False)
     self.ui.createButton.setEnabled(False)
     if self.ui.cancelButton.isVisible():
         self.ui.cancelButton.setHidden(self.sender() == self.ui.cancelButton)
         self.checkUsers()
     self.ui.createButton.setText(_("Add"))
     icon = QIcon()
     icon.addPixmap(QPixmap(":/gui/pics/user-group-new.png"), QIcon.Normal, QIcon.Off)
     self.ui.createButton.setIcon(icon)
Example #12
0
File: icons.py Project: dodo/blain
 def get_service_icon(self, name, url):
     key = "service/" + name
     if key in self.icons:
         return self.icons[key]
     icon, st = None, self.app.accounts.settings
     if not st.contains('icon/'+name):
         icon = get_favicon(url)
         if icon:
             icon = QIcon(QPixmap.fromImage(QImage.fromData(icon)))
             #print name, "icon loaded?", not icon.isNull()
             if not icon.isNull():
                 st.setValue('icon/'+name, icon)
         else: print "[ERROR] while loading", name, "icon"
     else:
         icon = st.value('icon/'+name, None)
         if icon: icon = QIcon(icon)
     if icon:
         self.icons[key] = icon
     return icon
Example #13
0
    def __init__(self, plugins):
        QAbstractItemModel.__init__(self)

        self.NO_DRM_ICON = QIcon(I('ok.png'))
        self.DONATE_ICON = QIcon()
        self.DONATE_ICON.addFile(I('donate.png'), QSize(16, 16))

        self.all_matches = plugins
        self.matches = plugins
        self.filter = ''
        self.search_filter = SearchFilter(self.all_matches)

        self.sort_col = 1
        self.sort_order = Qt.AscendingOrder
Example #14
0
 def __init__(self, gui):
     QDialog.__init__(self, gui)
     self.l = l = QVBoxLayout(self)
     self.msg = QLabel('')
     self.msg.setWordWrap(True)
     l.addWidget(self.msg)
     self.bb = bb = QDialogButtonBox(QDialogButtonBox.Close)
     bb.accepted.connect(self.accept)
     bb.rejected.connect(self.reject)
     b = bb.addButton(_('Queue &all books for backup'), bb.ActionRole)
     b.clicked.connect(self.mark_all_dirty)
     b.setIcon(QIcon(I('lt.png')))
     l.addWidget(bb)
     self.db = weakref.ref(gui.current_db)
     self.setResult(9)
     self.setWindowTitle(_('Backup status'))
     self.update()
     self.resize(self.sizeHint() + QSize(50, 15))
Example #15
0
    def __init__(self, parent):
        QDialog.__init__(self, parent)
        self.setAttribute(Qt.WA_DeleteOnClose, False)
        self.queue = []
        self.do_pop.connect(self.pop, type=Qt.QueuedConnection)

        self._layout = l = QGridLayout()
        self.setLayout(l)
        self.icon = QIcon(I('dialog_error.png'))
        self.setWindowIcon(self.icon)
        self.icon_label = QLabel()
        self.icon_label.setPixmap(self.icon.pixmap(68, 68))
        self.icon_label.setMaximumSize(QSize(68, 68))
        self.msg_label = QLabel('<p>&nbsp;')
        self.msg_label.setStyleSheet('QLabel { margin-top: 1ex; }')
        self.msg_label.setWordWrap(True)
        self.msg_label.setTextFormat(Qt.RichText)
        self.det_msg = QPlainTextEdit(self)
        self.det_msg.setVisible(False)

        self.bb = QDialogButtonBox(QDialogButtonBox.Close, parent=self)
        self.bb.accepted.connect(self.accept)
        self.bb.rejected.connect(self.reject)
        self.ctc_button = self.bb.addButton(_('&Copy to clipboard'),
                self.bb.ActionRole)
        self.ctc_button.clicked.connect(self.copy_to_clipboard)
        self.show_det_msg = _('Show &details')
        self.hide_det_msg = _('Hide &details')
        self.det_msg_toggle = self.bb.addButton(self.show_det_msg, self.bb.ActionRole)
        self.det_msg_toggle.clicked.connect(self.toggle_det_msg)
        self.det_msg_toggle.setToolTip(
                _('Show detailed information about this error'))
        self.suppress = QCheckBox(self)

        l.addWidget(self.icon_label, 0, 0, 1, 1)
        l.addWidget(self.msg_label,  0, 1, 1, 1)
        l.addWidget(self.det_msg,    1, 0, 1, 2)
        l.addWidget(self.suppress,   2, 0, 1, 2, Qt.AlignLeft|Qt.AlignBottom)
        l.addWidget(self.bb,         3, 0, 1, 2, Qt.AlignRight|Qt.AlignBottom)
        l.setColumnStretch(1, 100)

        self.setModal(False)
        self.suppress.setVisible(False)
        self.do_resize()
Example #16
0
    def __init__(self, parent=None):
        QWidget.__init__(self)
        self.parent = parent
        self.setWindowTitle("My Part Window")
        self.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding)
        layout = QtGui.QHBoxLayout(self)
        layout.setMargin(0)
        layout.setSpacing(0)

        #########################

        holder = QWidget()
        holder.setMaximumWidth(200)
        sublayout = QVBoxLayout(holder)
        sublayout.setMargin(0)
        sublayout.setSpacing(0)
        layout.addWidget(holder)

        ###

        self.featureManager = QtGui.QTabWidget()
        self.featureManager.setCurrentIndex(0)
        self.featureManager.setMaximumWidth(200)

        self.modelTreeTab = QtGui.QWidget()
        self.featureManager.addTab(self.modelTreeTab, "Model Tree")
        modelTreeTabLayout = QtGui.QVBoxLayout(self.modelTreeTab)
        modelTreeTabLayout.setMargin(0)
        modelTreeTabLayout.setSpacing(0)

        self.propertyManagerTab = QtGui.QWidget()
        self.featureManager.addTab(self.propertyManagerTab, "Property Manager")

        sublayout.addWidget(self.featureManager)

        ###

        self.modelTree = modelTreeGui.TestWrapper()
        self.modelTree.addIconButton(QIcon(icons + '/GrapheneGeneratorDialog_image3.png'),
                                     self.dismiss)
        modelTreeTabLayout.addWidget(self.modelTree)

        self.glpane = GLPane()
        layout.addWidget(self.glpane)
Example #17
0
    def __init__(self,
            default_status_msg=_('Welcome to') + ' ' + __appname__+' console',
            parent=None):
        QDialog.__init__(self, parent)

        self.restart_requested = False
        self.l = QVBoxLayout()
        self.setLayout(self.l)

        self.resize(800, 600)
        geom = dynamic.get('console_window_geometry', None)
        if geom is not None:
            self.restoreGeometry(geom)

        # Setup tool bar {{{
        self.tool_bar = QToolBar(self)
        self.tool_bar.setToolButtonStyle(Qt.ToolButtonTextOnly)
        self.l.addWidget(self.tool_bar)
        # }}}

        # Setup status bar {{{
        self.status_bar = QStatusBar(self)
        self.status_bar.defmsg = QLabel(__appname__ + _(' console ') +
                __version__)
        self.status_bar._font = QFont()
        self.status_bar._font.setBold(True)
        self.status_bar.defmsg.setFont(self.status_bar._font)
        self.status_bar.addWidget(self.status_bar.defmsg)
        # }}}

        self.console = Console(parent=self)
        self.console.running.connect(partial(self.status_bar.showMessage,
            _('Code is running')))
        self.console.running_done.connect(self.status_bar.clearMessage)
        self.l.addWidget(self.console)
        self.l.addWidget(self.status_bar)
        self.setWindowTitle(__appname__ + ' console')
        self.setWindowIcon(QIcon(I('console.png')))

        self.restart_action = QAction(_('Restart console'), self)
        self.restart_action.setShortcut(_('Ctrl+R'))
        self.addAction(self.restart_action)
        self.restart_action.triggered.connect(self.restart)
        self.console.context_menu.addAction(self.restart_action)
Example #18
0
    def show_context_menu(self, point):
        item = self.itemAt(point)
        if item is None or item in set(self.categories.itervalues()):
            return
        m = QMenu(self)
        sel = self.selectedItems()
        num = len(sel)
        if num > 0:
            m.addAction(QIcon(I('trash.png')), _('&Delete selected files'),
                        self.request_delete)
        ci = self.currentItem()
        if ci is not None:
            cn = unicode(ci.data(0, NAME_ROLE).toString())
            mt = unicode(ci.data(0, MIME_ROLE).toString())
            cat = unicode(ci.data(0, CATEGORY_ROLE).toString())
            m.addAction(QIcon(I('modified.png')),
                        _('&Rename %s') % (elided_text(self.font(), cn)),
                        self.edit_current_item)
            if is_raster_image(mt):
                m.addAction(
                    QIcon(I('default_cover.png')),
                    _('Mark %s as cover image') % elided_text(self.font(), cn),
                    partial(self.mark_as_cover, cn))
            elif current_container(
            ).SUPPORTS_TITLEPAGES and mt in OEB_DOCS and cat == 'text':
                m.addAction(
                    QIcon(I('default_cover.png')),
                    _('Mark %s as title/cover page') %
                    elided_text(self.font(), cn),
                    partial(self.mark_as_titlepage, cn))

        selected_map = defaultdict(list)
        for item in sel:
            selected_map[unicode(item.data(
                0, CATEGORY_ROLE).toString())].append(
                    unicode(item.data(0, NAME_ROLE).toString()))

        for items in selected_map.itervalues():
            items.sort(key=self.index_of_name)

        if len(selected_map['text']) > 1:
            m.addAction(
                QIcon(I('merge.png')), _('&Merge selected text files'),
                partial(self.start_merge, 'text', selected_map['text']))
        if len(selected_map['styles']) > 1:
            m.addAction(
                QIcon(I('merge.png')), _('&Merge selected style files'),
                partial(self.start_merge, 'styles', selected_map['styles']))

        if len(list(m.actions())) > 0:
            m.popup(self.mapToGlobal(point))
Example #19
0
 def data(self, role):
     if role == Qt.DisplayRole:
         return QVariant(self.title)
     if role == Qt.DecorationRole:
         if self.icon is None:
             icon = '%s.png' % self.urn[8:]
             p = QPixmap()
             if icon in self.favicons:
                 try:
                     with zipfile.ZipFile(self.zf, 'r') as zf:
                         p.loadFromData(zf.read(self.favicons[icon]))
                 except:
                     pass
             if not p.isNull():
                 self.icon = QVariant(QIcon(p))
             else:
                 self.icon = self.default_icon
         return self.icon
     return NONE
Example #20
0
    def __init__(self, db, duplicates, parent=None):
        QDialog.__init__(self, parent)
        self.l = l = QGridLayout()
        self.setLayout(l)
        t = ngettext('Duplicate found', 'Duplicates found', len(duplicates))
        if len(duplicates) > 1:
            t = '%d %s' % (len(duplicates), t)
        self.setWindowTitle(t)
        self.i = i = QIcon(I('dialog_question.png'))
        self.setWindowIcon(i)

        self.l1 = l1 = QLabel()
        self.l2 = l2 = QLabel(
            _('Books with the same titles as the following already '
              'exist in calibre. Select which books you want added anyway.'))
        l2.setWordWrap(True)
        l1.setPixmap(i.pixmap(128, 128))
        l.addWidget(l1, 0, 0)
        l.addWidget(l2, 0, 1)

        self.dup_list = dl = QTreeWidget(self)
        l.addWidget(dl, 1, 0, 1, 2)
        dl.setHeaderHidden(True)
        dl.addTopLevelItems(list(self.process_duplicates(db, duplicates)))
        dl.expandAll()
        dl.setIndentation(30)

        self.bb = bb = QDialogButtonBox(QDialogButtonBox.Ok
                                        | QDialogButtonBox.Cancel)
        bb.accepted.connect(self.accept)
        bb.rejected.connect(self.reject)
        l.addWidget(bb, 2, 0, 1, 2)
        l.setColumnStretch(1, 10)
        self.ab = ab = bb.addButton(_('Select &all'), bb.ActionRole)
        ab.clicked.connect(self.select_all)
        self.nb = ab = bb.addButton(_('Select &none'), bb.ActionRole)
        ab.clicked.connect(self.select_none)

        self.resize(self.sizeHint())
        geom = gprefs.get('duplicates-question-dialog-geometry', None)
        if geom is not None:
            self.restoreGeometry(geom)
        self.exec_()
Example #21
0
 def reg(icon, text, target, sid, keys, description):
     if not isinstance(icon, QIcon):
         icon = QIcon(I(icon))
     ac = actions[sid] = QAction(icon, text, self) if icon else QAction(
         text, self)
     ac.setObjectName('action-' + sid)
     if target is not None:
         ac.triggered.connect(target)
     if isinstance(keys, type('')):
         keys = (keys, )
     self.keyboard.register_shortcut(sid,
                                     unicode(ac.text()).replace(
                                         '&', ''),
                                     default_keys=keys,
                                     description=description,
                                     action=ac,
                                     group=group)
     self.addAction(ac)
     return ac
Example #22
0
def show_report(changed, title, report, parent, show_current_diff):
    report = format_report(title, report)
    d = QDialog(parent)
    d.l = QVBoxLayout()
    d.setLayout(d.l)
    d.e = QTextBrowser(d)
    d.l.addWidget(d.e)
    d.e.setHtml(report)
    d.bb = QDialogButtonBox(QDialogButtonBox.Close)
    if changed:
        b = d.b = d.bb.addButton(_('See what &changed'), d.bb.AcceptRole)
        b.setIcon(QIcon(I('diff.png'))), b.setAutoDefault(False)
        b.clicked.connect(partial(show_current_diff, allow_revert=True))
    d.bb.button(d.bb.Close).setDefault(True)
    d.l.addWidget(d.bb)
    d.bb.rejected.connect(d.reject)
    d.bb.accepted.connect(d.accept)
    d.resize(600, 400)
    d.exec_()
Example #23
0
 def genesis(self, gui):
     self.gui = gui
     self.delegate = Delegate(self.tweaks_view)
     self.tweaks_view.setItemDelegate(self.delegate)
     self.tweaks_view.currentChanged = self.current_changed
     self.view = self.tweaks_view
     self.highlighter = PythonHighlighter(self.edit_tweak.document())
     self.restore_default_button.clicked.connect(self.restore_to_default)
     self.apply_button.clicked.connect(self.apply_tweak)
     self.plugin_tweaks_button.clicked.connect(self.plugin_tweaks)
     self.splitter.setStretchFactor(0, 1)
     self.splitter.setStretchFactor(1, 100)
     self.next_button.clicked.connect(self.find_next)
     self.previous_button.clicked.connect(self.find_previous)
     self.search.initialize('tweaks_search_history', help_text=_('Search for tweak'))
     self.search.search.connect(self.find)
     self.view.setContextMenuPolicy(Qt.CustomContextMenu)
     self.view.customContextMenuRequested.connect(self.show_context_menu)
     self.copy_icon = QIcon(I('edit-copy.png'))
Example #24
0
 def data(self, index, role):
     try:
         field, visible = self.fields[index.row()]
     except:
         return NONE
     if role == Qt.DisplayRole:
         name = field
         try:
             name = self.db.field_metadata[field]['name']
         except:
             pass
         if not name:
             name = field
         return name
     if role == Qt.CheckStateRole:
         return Qt.Checked if visible else Qt.Unchecked
     if role == Qt.DecorationRole and field.startswith('#'):
         return QIcon(I('column.png'))
     return NONE
Example #25
0
    def __init__(self, opts, notify=None):
        MainWindow.__init__(self, opts, disable_automatic_gc=True)
        self.boss = Boss(self, notify=notify)
        self.setWindowTitle(self.APP_NAME)
        self.setWindowIcon(QIcon(I('tweak.png')))
        self.opts = opts
        self.path_to_ebook = None
        self.container = None
        self.current_metadata = None
        self.blocking_job = BlockingJob(self)
        self.keyboard = KeyboardManager(self, config_name='shortcuts/tweak_book')

        self.central = Central(self)
        self.setCentralWidget(self.central)
        self.check_book = Check(self)
        self.spell_check = SpellCheck(parent=self)
        self.toc_view = TOCViewer(self)
        self.saved_searches = SavedSearches(self)
        self.image_browser = InsertImage(self, for_browsing=True)
        self.insert_char = CharSelect(self)

        self.create_actions()
        self.create_toolbars()
        self.create_docks()
        self.create_menubar()

        self.status_bar = self.statusBar()
        self.status_bar.addPermanentWidget(self.boss.save_manager.status_widget)
        self.cursor_position_widget = CursorPositionWidget(self)
        self.status_bar.addPermanentWidget(self.cursor_position_widget)
        self.status_bar_default_msg = la = QLabel(_('{0} {1} created by {2}').format(__appname__, get_version(), 'Kovid Goyal'))
        la.base_template = unicode(la.text())
        self.status_bar.addWidget(la)
        f = self.status_bar.font()
        f.setBold(True)
        self.status_bar.setFont(f)

        self.boss(self)
        g = QApplication.instance().desktop().availableGeometry(self)
        self.resize(g.width()-50, g.height()-50)

        self.restore_state()
        self.apply_settings()
Example #26
0
def iconset_from_color(color):
    """
    Return a QIcon suitable for showing the given color in a menu item or (###k untested, unreviewed) some other widget.
    The color can be a QColor or any python type we use for colors (out of the few our helper funcs understand).
    """
    # figure out desired size of a small icon
    from PyQt4.Qt import QIcon
    #size = QIcon.iconSize(QIcon.Small) # a QSize object
    #w, h = size.width(), size.height()
    w, h = 16, 16  # hardwire it and be done
    # get pixmap of that color
    pixmap = pixmap_from_color_and_size(color, (w, h))
    # for now, let Qt figure out the Active appearance, etc. Later we can draw our own black outline, or so. ##e
    iconset = QIcon(pixmap)
    checkmark = ("checkmark" == debug_pref("color checkmark",
                                           Choice(["checkmark", "box"])))

    modify_iconset_On_states(iconset, color=color, checkmark=checkmark)
    return iconset
Example #27
0
    def __init__(self, db, parent=None):
        QWizard.__init__(self, parent)
        self.setModal(True)
        self.setWindowTitle(_('Add books to calibre'))
        self.setWindowIcon(QIcon(I('add_book.png')))
        self.setPixmap(
            self.LogoPixmap,
            QPixmap(P('content_server/calibre.png')).scaledToHeight(
                80, Qt.SmoothTransformation))
        self.setPixmap(self.WatermarkPixmap, QPixmap(I('welcome_wizard.png')))

        self.register = {}

        for attr, cls in [
            ('welcome_page', WelcomePage),
            ('scan_page', ScanPage),
        ]:
            setattr(self, attr, cls(db, self))
            self.setPage(getattr(cls, 'ID'), getattr(self, attr))
Example #28
0
 def __init__(self, parent=None):
     QWidget.__init__(self, parent)
     self.l = l = QHBoxLayout()
     self.setLayout(l)
     l.setContentsMargins(0, 0, 0, 0)
     self.t = t = QToolBar(self)
     l.addWidget(t)
     t.setOrientation(Qt.Vertical)
     t.setIconSize(QSize(12, 12))
     t.setMovable(False)
     t.setFloatable(False)
     t.cl = ac = t.addAction(QIcon(I('window-close.png')),
                             _('Close search panel'))
     ac.triggered.connect(self.hide_panel)
     self.widget = SearchWidget(self)
     l.addWidget(self.widget)
     self.restore_state, self.save_state = self.widget.restore_state, self.widget.save_state
     self.widget.search_triggered.connect(self.search_triggered)
     self.pre_fill = self.widget.pre_fill
Example #29
0
File: ui.py Project: kmshi/calibre
    def __init__(self, opts, notify=None):
        MainWindow.__init__(self, opts, disable_automatic_gc=True)
        self.boss = Boss(self, notify=notify)
        self.setWindowTitle(self.APP_NAME)
        self.setWindowIcon(QIcon(I('tweak.png')))
        self.opts = opts
        self.path_to_ebook = None
        self.container = None
        self.current_metadata = None
        self.blocking_job = BlockingJob(self)
        self.keyboard = KeyboardManager(self,
                                        config_name='shortcuts/tweak_book')

        self.central = Central(self)
        self.setCentralWidget(self.central)
        self.check_book = Check(self)
        self.toc_view = TOCViewer(self)

        self.create_actions()
        self.create_toolbars()
        self.create_docks()
        self.create_menubar()

        self.status_bar = self.statusBar()
        self.status_bar.addPermanentWidget(
            self.boss.save_manager.status_widget)
        self.cursor_position_widget = CursorPositionWidget(self)
        self.status_bar.addPermanentWidget(self.cursor_position_widget)
        self.status_bar.addWidget(
            QLabel(
                _('{0} {1} created by {2}').format(__appname__, get_version(),
                                                   'Kovid Goyal')))
        f = self.status_bar.font()
        f.setBold(True)
        self.status_bar.setFont(f)

        self.boss(self)
        g = QApplication.instance().desktop().availableGeometry(self)
        self.resize(g.width() - 50, g.height() - 50)
        self.restore_state()

        self.keyboard.finalize()
Example #30
0
 def create_toolbars(self):
     self.action_bar = b = self.addToolBar(_('File actions tool bar'))
     b.setObjectName('action_bar')  # Needed for saveState
     for x in ('undo', 'redo'):
         b.addAction(actions['editor-%s' % x])
     self.edit_bar = b = self.addToolBar(_('Edit actions tool bar'))
     for x in ('cut', 'copy', 'paste'):
         b.addAction(actions['editor-%s' % x])
     self.tools_bar = b = self.addToolBar(_('Editor tools'))
     b.setObjectName('tools_bar')
     if self.syntax == 'html':
         b.addAction(actions['fix-html-current'])
     if self.syntax in {'xml', 'html', 'css'}:
         b.addAction(actions['pretty-current'])
     if self.syntax in {'html', 'css'}:
         b.addAction(actions['insert-image'])
     if self.syntax == 'html':
         b.addAction(actions['insert-hyperlink'])
     if self.syntax in {'xml', 'html'}:
         b.addAction(actions['insert-tag'])
         w = self.insert_tag_button = b.widgetForAction(
             actions['insert-tag'])
         w.setPopupMode(QToolButton.MenuButtonPopup)
         w.m = m = QMenu()
         w.setMenu(m)
         w.setContextMenuPolicy(Qt.CustomContextMenu)
         w.customContextMenuRequested.connect(
             self.insert_tag_button.showMenu)
         self._build_insert_tag_button_menu()
     if self.syntax == 'html':
         self.format_bar = b = self.addToolBar(_('Format text'))
         b.setObjectName('html_format_bar')
         for x in ('bold', 'italic', 'underline', 'strikethrough',
                   'subscript', 'superscript', 'color', 'background-color'):
             b.addAction(actions['format-text-%s' % x])
         ac = b.addAction(QIcon(I('format-text-heading.png')),
                          _('Change paragraph to heading'))
         m = QMenu()
         ac.setMenu(m)
         b.widgetForAction(ac).setPopupMode(QToolButton.InstantPopup)
         for name in tuple('h%d' % d for d in range(1, 7)) + ('p', ):
             m.addAction(actions['rename-block-tag-%s' % name])
Example #31
0
def create_icon(text, palette=None, sz=32, divider=2):
    if palette is None:
        palette = QApplication.palette()
    img = QImage(sz, sz, QImage.Format_ARGB32)
    img.fill(Qt.transparent)
    p = QPainter(img)
    p.setRenderHints(p.TextAntialiasing | p.Antialiasing)
    qDrawShadeRect(p,
                   img.rect(),
                   palette,
                   fill=QColor('#ffffff'),
                   lineWidth=1,
                   midLineWidth=1)
    f = p.font()
    f.setFamily('Liberation Sans'), f.setPixelSize(sz //
                                                   divider), f.setBold(True)
    p.setFont(f), p.setPen(Qt.black)
    p.drawText(img.rect().adjusted(2, 2, -2, -2), Qt.AlignCenter, text)
    p.end()
    return QIcon(QPixmap.fromImage(img))
Example #32
0
 def __init__(self, val, device):
     QWidget.__init__(self)
     self.t = t = QLineEdit(self)
     t.setText(', '.join(val or []))
     t.setCursorPosition(0)
     self.l = l = QGridLayout(self)
     self.setLayout(l)
     self.m = m = QLabel('<p>' +
                         _('''A <b>list of &folders</b> on the device to
     which to send ebooks. The first one that exists will be used:'''))
     m.setWordWrap(True)
     m.setBuddy(t)
     l.addWidget(m, 0, 0, 1, 2)
     l.addWidget(t, 1, 0)
     self.b = b = QToolButton()
     l.addWidget(b, 1, 1)
     b.setIcon(QIcon(I('document_open.png')))
     b.clicked.connect(self.browse)
     b.setToolTip(_('Browse for a folder on the device'))
     self._device = weakref.ref(device)
Example #33
0
def init_qt(args):
    parser = option_parser()
    opts, args = parser.parse_args(args)
    if getattr(opts, 'detach', False):
        detach_gui()
    find_portable_library()
    if opts.with_library is not None:
        libpath = os.path.expanduser(opts.with_library)
        if not os.path.exists(libpath):
            os.makedirs(libpath)
        if os.path.isdir(libpath):
            prefs.set('library_path', os.path.abspath(libpath))
            prints('Using library at', prefs['library_path'])
    QCoreApplication.setOrganizationName(ORG_NAME)
    QCoreApplication.setApplicationName(APP_UID)
    override = 'calibre-gui' if islinux else None
    app = Application(args, override_program_name=override)
    app.file_event_hook = EventAccumulator()
    app.setWindowIcon(QIcon(I('lt.png')))
    return app, opts, args
Example #34
0
    def __init__(self, gui):
        QDialog.__init__(self, gui)
        self.setAttribute(Qt.WA_DeleteOnClose, False)
        self.gui = gui
        self.queue = []

        self._layout = l = QGridLayout()
        self.setLayout(l)
        self.icon = QIcon(I('dialog_error.png'))
        self.setWindowIcon(self.icon)
        self.icon_label = QLabel()
        self.icon_label.setPixmap(self.icon.pixmap(128, 128))
        self.icon_label.setMaximumSize(QSize(128, 128))
        self.msg_label = QLabel('<p>&nbsp;')
        self.msg_label.setWordWrap(True)
        self.msg_label.setTextFormat(Qt.RichText)
        self.det_msg = QPlainTextEdit(self)
        self.det_msg.setVisible(False)

        self.bb = QDialogButtonBox(QDialogButtonBox.Close, parent=self)
        self.bb.accepted.connect(self.accept)
        self.bb.rejected.connect(self.reject)
        self.ctc_button = self.bb.addButton(_('&Copy to clipboard'),
                self.bb.ActionRole)
        self.ctc_button.clicked.connect(self.copy_to_clipboard)
        self.show_det_msg = _('Show &details')
        self.hide_det_msg = _('Hide &details')
        self.det_msg_toggle = self.bb.addButton(self.show_det_msg, self.bb.ActionRole)
        self.det_msg_toggle.clicked.connect(self.toggle_det_msg)
        self.det_msg_toggle.setToolTip(
                _('Show detailed information about this error'))

        l.addWidget(self.icon_label, 0, 0, 1, 1)
        l.addWidget(self.msg_label,  0, 1, 1, 1, Qt.AlignLeft|Qt.AlignTop)
        l.addWidget(self.det_msg, 1, 0, 1, 2)

        l.addWidget(self.bb, 2, 0, 1, 2, Qt.AlignRight|Qt.AlignBottom)

        self.setModal(False)
        self.base_height = max(200, self.sizeHint().height() + 20)
        self.do_resize()
Example #35
0
 def filename_button_clicked(self):
     try:
         path = choose_files(self,
                             'choose_category_icon',
                             _('Select Icon'),
                             filters=[('Images',
                                       ['png', 'gif', 'jpg', 'jpeg'])],
                             all_files=False,
                             select_only_single_file=True)
         if path:
             icon_path = path[0]
             icon_name = lower(
                 sanitize_file_name_unicode(
                     os.path.splitext(os.path.basename(icon_path))[0] +
                     '.png'))
             if icon_name not in self.icon_file_names:
                 self.icon_file_names.append(icon_name)
                 self.update_filename_box()
                 try:
                     p = QIcon(icon_path).pixmap(QSize(128, 128))
                     d = os.path.join(config_dir, 'cc_icons')
                     if not os.path.exists(os.path.join(d, icon_name)):
                         if not os.path.exists(d):
                             os.makedirs(d)
                         with open(os.path.join(d, icon_name), 'wb') as f:
                             f.write(pixmap_to_data(p, format='PNG'))
                 except:
                     import traceback
                     traceback.print_exc()
             if self.multiple_icon_cb.isChecked():
                 if icon_name not in self.rule_icon_files:
                     self.rule_icon_files.append(icon_name)
                 self.update_icon_filenames_in_box()
             else:
                 self.filename_box.setCurrentIndex(
                     self.filename_box.findText(icon_name))
             self.filename_box.adjustSize()
     except:
         import traceback
         traceback.print_exc()
     return
Example #36
0
    def __init__(self, parent, page):
        QDialog.__init__(self, parent)
        self.setWindowTitle(_('Inspect book code'))
        self.setWindowIcon(QIcon(I('debug.png')))
        l = QVBoxLayout()
        self.setLayout(l)

        self.inspector = QWebInspector(self)
        self.inspector.setPage(page)
        l.addWidget(self.inspector)

        self.bb = bb = QDialogButtonBox(QDialogButtonBox.Close)
        l.addWidget(bb)
        bb.accepted.connect(self.accept)
        bb.rejected.connect(self.reject)

        self.resize(self.sizeHint())

        geom = gprefs.get('viewer_inspector_geom', None)
        if geom is not None:
            self.restoreGeometry(geom)
Example #37
0
 def data(self, index, role):
     row = index.row()
     action = self._data[row].action_spec
     if role == Qt.DisplayRole:
         text = action[0]
         text = text.replace('&', '')
         if text == _('%d books'):
             text = _('Choose library')
         return QVariant(text)
     if role == Qt.DecorationRole:
         if hasattr(self._data[row], 'qaction'):
             icon = self._data[row].qaction.icon()
             if not icon.isNull():
                 return QVariant(icon)
         ic = action[1]
         if ic is None:
             ic = 'blank.png'
         return QVariant(QIcon(I(ic)))
     if role == Qt.ToolTipRole and action[2] is not None:
         return QVariant(action[2])
     return NONE
Example #38
0
 def __init__(self, vertical, parent=None):
     QWebView.__init__(self, parent)
     self.vertical = vertical
     self.page().setLinkDelegationPolicy(self.page().DelegateAllLinks)
     self.linkClicked.connect(self.link_activated)
     self._link_clicked = False
     self.setAttribute(Qt.WA_OpaquePaintEvent, False)
     palette = self.palette()
     self.setAcceptDrops(False)
     palette.setBrush(QPalette.Base, Qt.transparent)
     self.page().setPalette(palette)
     self.css = P('templates/book_details.css', data=True).decode('utf-8')
     for x, icon in [('remove_format', 'trash.png'),
                     ('save_format', 'save.png'),
                     ('restore_format', 'edit-undo.png'),
                     ('copy_link', 'edit-copy.png')]:
         ac = QAction(QIcon(I(icon)), '', self)
         ac.current_fmt = None
         ac.current_url = None
         ac.triggered.connect(getattr(self, '%s_triggerred' % x))
         setattr(self, '%s_action' % x, ac)
Example #39
0
 def count_message(action, count, show_diff=False):
     msg = _('%(action)s %(num)s occurrences of %(query)s' %
             dict(num=count, query=errfind, action=action))
     if show_diff and count > 0:
         d = MessageBox(MessageBox.INFO,
                        _('Searching done'),
                        prepare_string_for_xml(msg),
                        parent=gui_parent,
                        show_copy_button=False)
         d.diffb = b = d.bb.addButton(_('See what &changed'),
                                      d.bb.ActionRole)
         b.setIcon(QIcon(
             I('diff.png'))), d.set_details(None), b.clicked.connect(
                 d.accept)
         b.clicked.connect(partial(show_current_diff, allow_revert=True))
         d.exec_()
     else:
         info_dialog(gui_parent,
                     _('Searching done'),
                     prepare_string_for_xml(msg),
                     show=True)
Example #40
0
    def __init__(self, dev, ignored_folders=None, parent=None):
        QDialog.__init__(self, parent)
        self.l = l = QVBoxLayout()
        self.setLayout(l)
        self.la = la = QLabel(
            '<p>' + _('<b>Scanned folders:</b>') + ' ' +
            _('You can select which top level folders calibre will '
              'scan when searching this device for books.'))
        la.setWordWrap(True)
        l.addWidget(la)
        self.tabs = QTabWidget(self)
        l.addWidget(self.tabs)
        self.widgets = []

        for storage in dev.filesystem_cache.entries:
            w = QListWidget(self)
            w.storage = storage
            self.tabs.addTab(w, storage.name)
            self.widgets.append(w)
            for child in sorted(storage.folders, key=attrgetter('name')):
                i = QListWidgetItem(child.name)
                i.setFlags(Qt.ItemIsUserCheckable | Qt.ItemIsEnabled)
                i.setCheckState(Qt.Unchecked if dev.is_folder_ignored(
                    storage, child.name, ignored_folders=ignored_folders
                ) else Qt.Checked)
                w.addItem(i)

        self.bb = QDialogButtonBox(QDialogButtonBox.Ok
                                   | QDialogButtonBox.Cancel)
        self.bb.accepted.connect(self.accept)
        self.bb.rejected.connect(self.reject)
        self.sab = self.bb.addButton(_('Select &All'), self.bb.ActionRole)
        self.sab.clicked.connect(self.select_all)
        self.snb = self.bb.addButton(_('Select &None'), self.bb.ActionRole)
        self.snb.clicked.connect(self.select_none)
        l.addWidget(self.bb)
        self.setWindowTitle(_('Choose folders to scan'))
        self.setWindowIcon(QIcon(I('devices/tablet.png')))

        self.resize(500, 500)
Example #41
0
    def __init__(self, dev, ignored_folders=None, parent=None):
        QDialog.__init__(self, parent)
        self.l = l = QVBoxLayout()
        self.setLayout(l)
        self.la = la = QLabel('<p>' + _('<b>Scanned folders:</b>') + ' ' +
                              _('You can select which folders calibre will '
                                'scan when searching this device for books.'))
        la.setWordWrap(True)
        l.addWidget(la)
        self.tabs = QTabWidget(self)
        l.addWidget(self.tabs)
        self.widgets = []

        for storage in dev.filesystem_cache.entries:
            self.dev = dev
            w = Storage(storage, item_func=self.create_item)
            del self.dev
            self.tabs.addTab(w, storage.name)
            self.widgets.append(w)
            w.itemChanged.connect(self.item_changed)

        self.la2 = la = QLabel(
            _('If you a select a previously unselected folder, any sub-folders'
              ' will not be visible until you restart calibre.'))
        l.addWidget(la)
        la.setWordWrap(True)

        self.bb = QDialogButtonBox(QDialogButtonBox.Ok
                                   | QDialogButtonBox.Cancel)
        self.bb.accepted.connect(self.accept)
        self.bb.rejected.connect(self.reject)
        self.sab = self.bb.addButton(_('Select &All'), self.bb.ActionRole)
        self.sab.clicked.connect(self.select_all)
        self.snb = self.bb.addButton(_('Select &None'), self.bb.ActionRole)
        self.snb.clicked.connect(self.select_none)
        l.addWidget(self.bb)
        self.setWindowTitle(_('Choose folders to scan'))
        self.setWindowIcon(QIcon(I('devices/tablet.png')))

        self.resize(600, 500)
Example #42
0
 def slotCheckCD(self):
     if self.check_media_stop:
         self.check_media_stop = False
         self.ui.progressBar.show()
         icon = QIcon()
         icon.addPixmap(QPixmap(":/gui/pics/dialog-error.png"), QIcon.Normal, QIcon.Off)
         self.ui.checkButton.setIcon(icon)
         self.ui.checkButton.setText("")
         self.checkMedia()
     else:
         self.check_media_stop = True
         self.ui.progressBar.show()
         icon = QIcon()
         icon.addPixmap(QPixmap(":/gui/pics/task-accepted.png"), QIcon.Normal, QIcon.Off)
         self.ui.checkButton.setIcon(icon)
         self.ui.checkButton.setText(_("Validate"))
Example #43
0
def confirm(msg,
            name,
            parent=None,
            pixmap='dialog_warning.png',
            title=None,
            show_cancel_button=True,
            confirm_msg=None,
            config_set=None):
    config_set = config_set or dynamic
    if not config_set.get(confirm_config_name(name), True):
        return True
    d = Dialog(msg, name, parent, config_set=config_set)
    d.label.setPixmap(QPixmap(I(pixmap)))
    d.setWindowIcon(QIcon(I(pixmap)))
    if title is not None:
        d.setWindowTitle(title)
    if not show_cancel_button:
        d.buttonBox.button(d.buttonBox.Cancel).setVisible(False)
    if confirm_msg is not None:
        d.again.setText(confirm_msg)
    d.resize(d.sizeHint())
    return d.exec_() == d.Accepted
Example #44
0
    def update_filename_box(self):
        doing_multiple = self.multiple_icon_cb.isChecked()

        model = QStandardItemModel()
        self.filename_box.setModel(model)
        self.icon_file_names.sort(key=sort_key)
        if doing_multiple:
            item = QStandardItem(_('Open to see checkboxes'))
        else:
            item = QStandardItem('')
        model.appendRow(item)

        for i, filename in enumerate(self.icon_file_names):
            item = QStandardItem(filename)
            if doing_multiple:
                item.setFlags(Qt.ItemIsUserCheckable | Qt.ItemIsEnabled)
                item.setData(Qt.Unchecked, Qt.CheckStateRole)
            else:
                item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsSelectable)
            icon = QIcon(os.path.join(config_dir, 'cc_icons', filename))
            item.setIcon(icon)
            model.appendRow(item)
Example #45
0
 def ask_link(self):
     d = QDialog(self)
     d.setWindowTitle(_('Create link'))
     l = QFormLayout()
     d.setLayout(l)
     d.url = QLineEdit(d)
     d.name = QLineEdit(d)
     d.setMinimumWidth(600)
     d.bb = QDialogButtonBox(QDialogButtonBox.Ok|QDialogButtonBox.Cancel)
     d.br = b = QPushButton(_('&Browse'))
     b.setIcon(QIcon(I('document_open.png')))
     def cf():
         files = choose_files(d, 'select link file', _('Choose file'), select_only_single_file=True)
         if files:
             d.url.setText(files[0])
     b.clicked.connect(cf)
     d.la = la = QLabel(_(
         'Enter a URL. You can also choose to create a link to a file on '
         'your computer. If the selected file is an image, it will be '
         'inserted as an image. Note that if you create a link to a file on '
         'your computer, it will stop working if the file is moved.'))
     la.setWordWrap(True)
     la.setStyleSheet('QLabel { margin-bottom: 1.5ex }')
     l.setWidget(0, l.SpanningRole, la)
     l.addRow(_('Enter &URL:'), d.url)
     l.addRow(_('Enter &name (optional):'), d.name)
     l.addRow(_('Choose a file on your computer:'), d.br)
     l.addRow(d.bb)
     d.bb.accepted.connect(d.accept)
     d.bb.rejected.connect(d.reject)
     d.resize(d.sizeHint())
     link, name, is_image = None, None, False
     if d.exec_() == d.Accepted:
         link, name = unicode(d.url.text()).strip(), unicode(d.name.text()).strip()
         if link and os.path.exists(link):
             with lopen(link, 'rb') as f:
                 q = what(f)
             is_image = q in {'jpeg', 'png', 'gif'}
     return link, name, is_image
Example #46
0
 def __init__(self, parent=None):
     QDialog.__init__(self, parent)
     self._layout = QVBoxLayout(self)
     self.setLayout(self._layout)
     self.log = QPlainTextEdit(self)
     self._layout.addWidget(self.log)
     self.log.setPlainText(_('Getting device information')+'...')
     self.copy = QPushButton(_('Copy to &clipboard'))
     self.copy.setDefault(True)
     self.setWindowTitle(_('User-defined device information'))
     self.setWindowIcon(QIcon(I('debug.png')))
     self.copy.clicked.connect(self.copy_to_clipboard)
     self.ok = QPushButton('&OK')
     self.ok.setAutoDefault(False)
     self.ok.clicked.connect(self.accept)
     self.bbox = QDialogButtonBox(self)
     self.bbox.addButton(self.copy, QDialogButtonBox.ActionRole)
     self.bbox.addButton(self.ok, QDialogButtonBox.AcceptRole)
     self._layout.addWidget(self.bbox)
     self.resize(750, 500)
     self.bbox.setEnabled(False)
     QTimer.singleShot(1000, self.device_info)
Example #47
0
class MessageBox(QDialog, Ui_Dialog): # {{{

    ERROR = 0
    WARNING = 1
    INFO = 2
    QUESTION = 3

    def __init__(self, type_, title, msg,
                 det_msg='',
                 q_icon=None,
                 show_copy_button=True,
                 parent=None, default_yes=True):
        QDialog.__init__(self, parent)
        if q_icon is None:
            icon = {
                    self.ERROR : 'error',
                    self.WARNING: 'warning',
                    self.INFO:    'information',
                    self.QUESTION: 'question',
            }[type_]
            icon = 'dialog_%s.png'%icon
            self.icon = QIcon(I(icon))
        else:
            self.icon = q_icon
        self.setupUi(self)

        self.setWindowTitle(title)
        self.setWindowIcon(self.icon)
        self.icon_label.setPixmap(self.icon.pixmap(128, 128))
        self.msg.setText(msg)
        self.det_msg.setPlainText(det_msg)
        self.det_msg.setVisible(False)
        self.toggle_checkbox.setVisible(False)

        if show_copy_button:
            self.ctc_button = self.bb.addButton(_('&Copy to clipboard'),
                    self.bb.ActionRole)
            self.ctc_button.clicked.connect(self.copy_to_clipboard)

        self.show_det_msg = _('Show &details')
        self.hide_det_msg = _('Hide &details')
        self.det_msg_toggle = self.bb.addButton(self.show_det_msg, self.bb.ActionRole)
        self.det_msg_toggle.clicked.connect(self.toggle_det_msg)
        self.det_msg_toggle.setToolTip(
                _('Show detailed information about this error'))

        self.copy_action = QAction(self)
        self.addAction(self.copy_action)
        self.copy_action.setShortcuts(QKeySequence.Copy)
        self.copy_action.triggered.connect(self.copy_to_clipboard)

        self.is_question = type_ == self.QUESTION
        if self.is_question:
            self.bb.setStandardButtons(self.bb.Yes|self.bb.No)
            self.bb.button(self.bb.Yes if default_yes else self.bb.No
                    ).setDefault(True)
            self.default_yes = default_yes
        else:
            self.bb.button(self.bb.Ok).setDefault(True)

        if not det_msg:
            self.det_msg_toggle.setVisible(False)

        self.do_resize()


    def toggle_det_msg(self, *args):
        vis = unicode(self.det_msg_toggle.text()) == self.hide_det_msg
        self.det_msg_toggle.setText(self.show_det_msg if vis else
                self.hide_det_msg)
        self.det_msg.setVisible(not vis)
        self.do_resize()

    def do_resize(self):
        sz = self.sizeHint() + QSize(100, 0)
        sz.setWidth(min(500, sz.width()))
        sz.setHeight(min(500, sz.height()))
        self.resize(sz)

    def copy_to_clipboard(self, *args):
        QApplication.clipboard().setText(
                'calibre, version %s\n%s: %s\n\n%s' %
                (__version__, unicode(self.windowTitle()),
                    unicode(self.msg.text()),
                    unicode(self.det_msg.toPlainText())))
        if hasattr(self, 'ctc_button'):
            self.ctc_button.setText(_('Copied'))

    def showEvent(self, ev):
        ret = QDialog.showEvent(self, ev)
        if self.is_question:
            try:
                self.bb.button(self.bb.Yes if self.default_yes else self.bb.No
                        ).setFocus(Qt.OtherFocusReason)
            except:
                pass# Buttons were changed
        else:
            self.bb.button(self.bb.Ok).setFocus(Qt.OtherFocusReason)
        return ret

    def set_details(self, msg):
        if not msg:
            msg = ''
        self.det_msg.setPlainText(msg)
        self.det_msg_toggle.setText(self.show_det_msg)
        self.det_msg_toggle.setVisible(bool(msg))
        self.det_msg.setVisible(False)
        self.do_resize()
Example #48
0
class Matches(QAbstractItemModel):

    HEADERS = [_('Enabled'), _('Name'), _('No DRM'), _('Headquarters'), _('Affiliate'), _('Formats')]
    HTML_COLS = [1]

    def __init__(self, plugins):
        QAbstractItemModel.__init__(self)

        self.NO_DRM_ICON = QIcon(I('ok.png'))
        self.DONATE_ICON = QIcon()
        self.DONATE_ICON.addFile(I('donate.png'), QSize(16, 16))

        self.all_matches = plugins
        self.matches = plugins
        self.filter = ''
        self.search_filter = SearchFilter(self.all_matches)

        self.sort_col = 1
        self.sort_order = Qt.AscendingOrder

    def get_plugin(self, index):
        row = index.row()
        if row < len(self.matches):
            return self.matches[row]
        else:
            return None

    def search(self, filter):
        self.filter = filter.strip()
        if not self.filter:
            self.matches = self.all_matches
        else:
            try:
                self.matches = list(self.search_filter.parse(self.filter))
            except:
                self.matches = self.all_matches
        self.layoutChanged.emit()
        self.sort(self.sort_col, self.sort_order)

    def enable_all(self):
        for i in xrange(len(self.matches)):
            index = self.createIndex(i, 0)
            data = QVariant(True)
            self.setData(index, data, Qt.CheckStateRole)
    
    def enable_none(self):
        for i in xrange(len(self.matches)):
            index = self.createIndex(i, 0)
            data = QVariant(False)
            self.setData(index, data, Qt.CheckStateRole)
    
    def enable_invert(self):
        for i in xrange(len(self.matches)):
            self.toggle_plugin(self.createIndex(i, 0))

    def toggle_plugin(self, index):
        new_index = self.createIndex(index.row(), 0)
        data = QVariant(is_disabled(self.get_plugin(index)))
        self.setData(new_index, data, Qt.CheckStateRole)

    def index(self, row, column, parent=QModelIndex()):
        return self.createIndex(row, column)

    def parent(self, index):
        if not index.isValid() or index.internalId() == 0:
            return QModelIndex()
        return self.createIndex(0, 0)

    def rowCount(self, *args):
        return len(self.matches)

    def columnCount(self, *args):
        return len(self.HEADERS)

    def headerData(self, section, orientation, role):
        if role != Qt.DisplayRole:
            return NONE
        text = ''
        if orientation == Qt.Horizontal:
            if section < len(self.HEADERS):
                text = self.HEADERS[section]
            return QVariant(text)
        else:
            return QVariant(section+1)

    def data(self, index, role):
        row, col = index.row(), index.column()
        result = self.matches[row]
        if role in (Qt.DisplayRole, Qt.EditRole):
            if col == 1:
                return QVariant('<b>%s</b><br><i>%s</i>' % (result.name, result.description))
            elif col == 3:
                return QVariant(result.headquarters)
            elif col == 5:
                return QVariant(', '.join(result.formats).upper())
        elif role == Qt.DecorationRole:
            if col == 2:
                if result.drm_free_only:
                    return QVariant(self.NO_DRM_ICON)
            if col == 4:
                if result.affiliate:
                    return QVariant(self.DONATE_ICON)
        elif role == Qt.CheckStateRole:
            if col == 0:
                if is_disabled(result):
                    return Qt.Unchecked
                return Qt.Checked
        elif role == Qt.ToolTipRole:
            if col == 0:
                if is_disabled(result):
                    return QVariant('<p>' + _('This store is currently disabled and cannot be used in other parts of calibre.') + '</p>')
                else:
                    return QVariant('<p>' + _('This store is currently enabled and can be used in other parts of calibre.') + '</p>')
            elif col == 1:
                return QVariant('<p>%s</p>' % result.description)
            elif col == 2:
                if result.drm_free_only:
                    return QVariant('<p>' + _('This store only distributes ebooks without DRM.') + '</p>')
                else:
                    return QVariant('<p>' + _('This store distributes ebooks with DRM. It may have some titles without DRM, but you will need to check on a per title basis.') + '</p>')
            elif col == 3:
                return QVariant('<p>' + _('This store is headquartered in %s. This is a good indication of what market the store caters to. However, this does not necessarily mean that the store is limited to that market only.') % result.headquarters + '</p>')
            elif col == 4:
                if result.affiliate:
                    return QVariant('<p>' + _('Buying from this store supports the calibre developer: %s.') % result.author + '</p>')
            elif col == 5:
                return QVariant('<p>' + _('This store distributes ebooks in the following formats: %s') % ', '.join(result.formats) + '</p>')
        return NONE

    def setData(self, index, data, role):
        if not index.isValid():
            return False
        row, col = index.row(), index.column()
        if col == 0:
            if data.toBool():
                enable_plugin(self.get_plugin(index))
            else:
                disable_plugin(self.get_plugin(index))
        self.dataChanged.emit(self.index(index.row(), 0), self.index(index.row(), self.columnCount() - 1))
        return True

    def flags(self, index):
        if index.column() == 0:
            return QAbstractItemModel.flags(self, index) | Qt.ItemIsUserCheckable
        return QAbstractItemModel.flags(self, index)

    def data_as_text(self, match, col):
        text = ''
        if col == 0:
            text = 'b' if is_disabled(match) else 'a'
        elif col == 1:
            text = match.name
        elif col == 2:
            text = 'a' if getattr(match, 'drm_free_only', True) else 'b'
        elif col == 3:
            text = getattr(match, 'headquarters', '')
        elif col == 4:
            text = 'a' if getattr(match, 'affiliate', False) else 'b'
        return text

    def sort(self, col, order, reset=True):
        self.sort_col = col
        self.sort_order = order
        if not self.matches:
            return
        descending = order == Qt.DescendingOrder
        self.matches.sort(None,
            lambda x: sort_key(unicode(self.data_as_text(x, col))),
            descending)
        if reset:
            self.reset()
Example #49
0
class JobError(QDialog): # {{{

    WIDTH = 600

    def __init__(self, gui):
        QDialog.__init__(self, gui)
        self.setAttribute(Qt.WA_DeleteOnClose, False)
        self.gui = gui
        self.queue = []

        self._layout = l = QGridLayout()
        self.setLayout(l)
        self.icon = QIcon(I('dialog_error.png'))
        self.setWindowIcon(self.icon)
        self.icon_label = QLabel()
        self.icon_label.setPixmap(self.icon.pixmap(128, 128))
        self.icon_label.setMaximumSize(QSize(128, 128))
        self.msg_label = QLabel('<p>&nbsp;')
        self.msg_label.setWordWrap(True)
        self.msg_label.setTextFormat(Qt.RichText)
        self.det_msg = QPlainTextEdit(self)
        self.det_msg.setVisible(False)

        self.bb = QDialogButtonBox(QDialogButtonBox.Close, parent=self)
        self.bb.accepted.connect(self.accept)
        self.bb.rejected.connect(self.reject)
        self.ctc_button = self.bb.addButton(_('&Copy to clipboard'),
                self.bb.ActionRole)
        self.ctc_button.clicked.connect(self.copy_to_clipboard)
        self.show_det_msg = _('Show &details')
        self.hide_det_msg = _('Hide &details')
        self.det_msg_toggle = self.bb.addButton(self.show_det_msg, self.bb.ActionRole)
        self.det_msg_toggle.clicked.connect(self.toggle_det_msg)
        self.det_msg_toggle.setToolTip(
                _('Show detailed information about this error'))

        l.addWidget(self.icon_label, 0, 0, 1, 1)
        l.addWidget(self.msg_label,  0, 1, 1, 1, Qt.AlignLeft|Qt.AlignTop)
        l.addWidget(self.det_msg, 1, 0, 1, 2)

        l.addWidget(self.bb, 2, 0, 1, 2, Qt.AlignRight|Qt.AlignBottom)

        self.setModal(False)
        self.base_height = max(200, self.sizeHint().height() + 20)
        self.do_resize()

    def copy_to_clipboard(self, *args):
        d = QTextDocument()
        d.setHtml(self.msg_label.text())
        QApplication.clipboard().setText(
                u'calibre, version %s (%s, isfrozen: %s)\n%s: %s\n\n%s' %
                (__version__, sys.platform, isfrozen,
                    unicode(self.windowTitle()), unicode(d.toPlainText()),
                    unicode(self.det_msg.toPlainText())))
        if hasattr(self, 'ctc_button'):
            self.ctc_button.setText(_('Copied'))

    def toggle_det_msg(self, *args):
        vis = unicode(self.det_msg_toggle.text()) == self.hide_det_msg
        self.det_msg_toggle.setText(self.show_det_msg if vis else
                self.hide_det_msg)
        self.det_msg.setVisible(not vis)
        self.do_resize()

    def do_resize(self):
        h = self.base_height
        if self.det_msg.isVisible():
            h += 250
        self.resize(QSize(self.WIDTH, h))

    def showEvent(self, ev):
        ret = QDialog.showEvent(self, ev)
        self.bb.button(self.bb.Close).setFocus(Qt.OtherFocusReason)
        return ret
Example #50
0
File: moldy.py Project: shrx/moldy
    def __init__(self):
        QWidget.__init__(self)

        # define periodic table widget for element selection
        self.periodicTableWidget = widgets.PeriodicTableDialog()

        # initial molecule Zmatrix (can be empty)
        # self.inp = []
        self.inp = [['H'],
        ['O', 1, 0.9],
        ['O', 2, 1.4, 1, 105.],
        ['H', 3, 0.9, 2, 105., 1, 120.]]

        self.atomList = []
        self.highList = []
        self.labelList = []
        self.fast = False

        # define & initialize ZMatModel that will contain Zmatrix data
        self.ZMatModel = QStandardItemModel(len(self.inp), 7, self)
        self.ZMatTable = QTableView(self)
        self.ZMatTable.setModel(self.ZMatModel)
        self.ZMatTable.setFixedWidth(325)
        #self.ZMatTable.installEventFilter(self)
        #self.ZMatModel.installEventFilter(self)
        self.ZMatModel.setHorizontalHeaderLabels(['atom','','bond','','angle','','dihedral'])
        for j, width in enumerate([40, 22, 65, 22, 65, 22, 65]):
            self.ZMatTable.setColumnWidth(j, width)
        # populate the ZMatModel
        self.populateZMatModel()

        #define Menu bar menus and their actions
        self.menuBar = QMenuBar(self)
        fileMenu = self.menuBar.addMenu('&File')
        editMenu = self.menuBar.addMenu('&Edit')
        viewMenu = self.menuBar.addMenu('&View')
        measureMenu = self.menuBar.addMenu('&Measure')
        helpMenu = self.menuBar.addMenu('&Help')

        readZmatAction = QAction('&Read &ZMat', self)
        readZmatAction.setShortcut('Ctrl+O')
        readZmatAction.setStatusTip('Read Zmat from file')
        readZmatAction.triggered.connect(self.readZmat)
        fileMenu.addAction(readZmatAction)

        readXYZAction = QAction('&Read &XYZ', self)
        readXYZAction.setShortcut('Ctrl+Shift+O')
        readXYZAction.setStatusTip('Read XYZ from file')
        readXYZAction.triggered.connect(self.readXYZ)
        fileMenu.addAction(readXYZAction)

        readGaussianAction = QAction('&Read &Gaussian log', self)
        readGaussianAction.setShortcut('Ctrl+G')
        readGaussianAction.setStatusTip('Read Gaussian log file')
        readGaussianAction.triggered.connect(self.readGaussian)
        fileMenu.addAction(readGaussianAction)

        writeZmatAction = QAction('&Write &ZMat', self)
        writeZmatAction.setShortcut('Ctrl+S')
        writeZmatAction.setStatusTip('Write Zmat to file')
        writeZmatAction.triggered.connect(self.writeZmat)
        fileMenu.addAction(writeZmatAction)

        writeXYZAction = QAction('&Write &XYZ', self)
        writeXYZAction.setShortcut('Ctrl+Shift+S')
        writeXYZAction.setStatusTip('Write XYZ from file')
        writeXYZAction.triggered.connect(self.writeXYZ)
        fileMenu.addAction(writeXYZAction)

        exitAction = QAction('&Exit', self)
        exitAction.setShortcut('Ctrl+Q')
        exitAction.setStatusTip('Exit application')
        exitAction.triggered.connect(qApp.quit)
        fileMenu.addAction(exitAction)

        addRowAction = QAction('&Add &row', self)
        addRowAction.setShortcut('Ctrl+R')
        addRowAction.setStatusTip('Add row to ZMatrix')
        addRowAction.triggered.connect(self.addRow)
        editMenu.addAction(addRowAction)

        deleteRowAction = QAction('&Delete &row', self)
        deleteRowAction.setShortcut('Ctrl+Shift+R')
        deleteRowAction.setStatusTip('Delete row from ZMatrix')
        deleteRowAction.triggered.connect(self.deleteRow)
        editMenu.addAction(deleteRowAction)

        addAtomAction = QAction('&Add &atom', self)
        addAtomAction.setShortcut('Ctrl+A')
        addAtomAction.setStatusTip('Add atom to ZMatrix')
        addAtomAction.triggered.connect(self.buildB)
        editMenu.addAction(addAtomAction)

        drawModeMenu = QMenu('Draw mode', self)
        viewMenu.addMenu(drawModeMenu)
        fastDrawAction = QAction('&Fast draw', self)
        fastDrawAction.triggered.connect(self.fastDraw)
        normalDrawAction = QAction('&Normal draw', self)
        normalDrawAction.triggered.connect(self.normalDraw)
        drawModeMenu.addAction(normalDrawAction)
        drawModeMenu.addAction(fastDrawAction)

        clearHighlightsAction = QAction('&Clear selection', self)
        clearHighlightsAction.setShortcut('Ctrl+C')
        clearHighlightsAction.setStatusTip('Clear highlighted atoms')
        clearHighlightsAction.triggered.connect(self.clearHighlights)
        viewMenu.addAction(clearHighlightsAction)

        clearLabelsAction = QAction('&Clear labels', self)
        clearLabelsAction.setShortcut('Ctrl+Alt+C')
        clearLabelsAction.setStatusTip('Clear labels')
        clearLabelsAction.triggered.connect(self.clearLabels)
        viewMenu.addAction(clearLabelsAction)

        clearUpdateViewAction = QAction('&Clear selection and labels', self)
        clearUpdateViewAction.setShortcut('Ctrl+Shift+C')
        clearUpdateViewAction.setStatusTip('Clear highlighted atoms and labels')
        clearUpdateViewAction.triggered.connect(self.clearUpdateView)
        viewMenu.addAction(clearUpdateViewAction)

        self.showGaussAction = QAction('Show &Gaussian geometry optimization', self)
        self.showGaussAction.setShortcut('Ctrl+G')
        self.showGaussAction.setStatusTip('Show Gaussian geometry optimization plots for energy, force and displacement.')
        self.showGaussAction.setEnabled(False)
        self.showGaussAction.triggered.connect(self.showGauss)
        viewMenu.addAction(self.showGaussAction)
        self.showFreqAction = QAction('Show &IR frequency plot', self)
        self.showFreqAction.setShortcut('Ctrl+I')
        self.showFreqAction.setStatusTip('Show Gaussian calculated IR frequency plot.')
        self.showFreqAction.setEnabled(False)
        self.showFreqAction.triggered.connect(self.showFreq)
        viewMenu.addAction(self.showFreqAction)

        measureDistanceAction = QAction('&Measure &distance', self)
        measureDistanceAction.setShortcut('Ctrl+D')
        measureDistanceAction.setStatusTip('Measure distance between two atoms')
        measureDistanceAction.triggered.connect(self.measureDistanceB)
        measureMenu.addAction(measureDistanceAction)

        measureAngleAction = QAction('&Measure &angle', self)
        measureAngleAction.setShortcut('Ctrl+Shift+D')
        measureAngleAction.setStatusTip('Measure angle between three atoms')
        measureAngleAction.triggered.connect(self.measureAngleB)
        measureMenu.addAction(measureAngleAction)

        aboutAction = QAction('&About', self)
        aboutAction.setStatusTip('About this program...')
        aboutAction.triggered.connect(self.about)
        helpMenu.addAction(aboutAction)

        aboutQtAction = QAction('&About Qt', self)
        aboutQtAction.setStatusTip('About Qt...')
        aboutQtAction.triggered.connect(self.aboutQt)
        helpMenu.addAction(aboutQtAction)

        # define GL widget that displays the 3D molecule model
        self.window = widgets.MyGLView()
        self.window.installEventFilter(self)
        self.window.setMinimumSize(500, 500)
        #self.window.setBackgroundColor((50, 0, 10))
        self.updateView()

        self.gaussianPlot = GraphicsLayoutWidget()
        self.gaussianPlot.resize(750, 250)
        self.gaussianPlot.setWindowTitle('Gaussian geometry optimization')
        #self.gaussianPlot.setAspectLocked(True)
        #self.gaussianPlot.addLayout(rowspan=3, colspan=1)

        self.FreqModel = QStandardItemModel(1, 3, self)
        self.freqTable = QTableView(self)
        self.freqTable.setModel(self.FreqModel)
        self.freqTable.setMinimumWidth(240)
        self.freqTable.installEventFilter(self)
        self.FreqModel.installEventFilter(self)
        self.FreqModel.setHorizontalHeaderLabels(['Frequency','IR Intensity','Raman Intensity'])
        for j, width in enumerate([80, 80, 80]):
            self.freqTable.setColumnWidth(j, width)

        self.freqWidget = QWidget()
        self.freqWidget.setWindowTitle('IR frequency plot & table')
        self.freqWidget.resize(800, 400)
        self.freqWidget.layout = QHBoxLayout(self.freqWidget)
        self.freqWidget.layout.setSpacing(1)
        self.freqWidget.layout.setContentsMargins(1, 1, 1, 1)
        self.freqPlot = GraphicsLayoutWidget()
        self.freqWidget.layout.addWidget(self.freqPlot)
        self.freqWidget.layout.addWidget(self.freqTable)
        self.freqTable.clicked.connect(self.freqCellClicked)

        # define other application parts
        self.statusBar = QStatusBar(self)
        self.fileDialog = QFileDialog(self)

        # define application layout
        self.layout = QVBoxLayout(self)
        self.layout.setSpacing(1)
        self.layout.setContentsMargins(1, 1, 1, 1)
        self.layout1 = QHBoxLayout()
        self.layout1.setSpacing(1)
        self.layout1.addWidget(self.ZMatTable)
        self.layout1.addWidget(self.window)
        self.layout.addWidget(self.menuBar)
        self.layout.addLayout(self.layout1)
        self.layout.addWidget(self.statusBar)

        self.adjustSize()
        self.setWindowTitle('Moldy')
        iconPath = 'icon.png'
        icon = QIcon(iconPath)
        icon.addFile(iconPath, QSize(16, 16))
        icon.addFile(iconPath, QSize(24, 24))
        icon.addFile(iconPath, QSize(32, 32))
        icon.addFile(iconPath, QSize(48, 48))
        icon.addFile(iconPath, QSize(256, 256))
        self.setWindowIcon(icon)

        # start monitoring changes in the ZMatModel
        self.ZMatModel.dataChanged.connect(self.clearUpdateView)
Example #51
0
 def initContextMenu(self):
     m = QMenu()
     m.addAction( QIcon.fromTheme("application-exit"), "&Quit", qApp.quit)
     self.s.setContextMenu(m)
Example #52
0
class JobError(QDialog):  # {{{

    WIDTH = 600
    do_pop = pyqtSignal()

    def __init__(self, parent):
        QDialog.__init__(self, parent)
        self.setAttribute(Qt.WA_DeleteOnClose, False)
        self.queue = []
        self.do_pop.connect(self.pop, type=Qt.QueuedConnection)

        self._layout = l = QGridLayout()
        self.setLayout(l)
        self.icon = QIcon(I('dialog_error.png'))
        self.setWindowIcon(self.icon)
        self.icon_label = QLabel()
        self.icon_label.setPixmap(self.icon.pixmap(68, 68))
        self.icon_label.setMaximumSize(QSize(68, 68))
        self.msg_label = QLabel('<p>&nbsp;')
        self.msg_label.setStyleSheet('QLabel { margin-top: 1ex; }')
        self.msg_label.setWordWrap(True)
        self.msg_label.setTextFormat(Qt.RichText)
        self.det_msg = QPlainTextEdit(self)
        self.det_msg.setVisible(False)

        self.bb = QDialogButtonBox(QDialogButtonBox.Close, parent=self)
        self.bb.accepted.connect(self.accept)
        self.bb.rejected.connect(self.reject)
        self.ctc_button = self.bb.addButton(_('&Copy to clipboard'),
                self.bb.ActionRole)
        self.ctc_button.clicked.connect(self.copy_to_clipboard)
        self.show_det_msg = _('Show &details')
        self.hide_det_msg = _('Hide &details')
        self.det_msg_toggle = self.bb.addButton(self.show_det_msg, self.bb.ActionRole)
        self.det_msg_toggle.clicked.connect(self.toggle_det_msg)
        self.det_msg_toggle.setToolTip(
                _('Show detailed information about this error'))
        self.suppress = QCheckBox(self)

        l.addWidget(self.icon_label, 0, 0, 1, 1)
        l.addWidget(self.msg_label,  0, 1, 1, 1)
        l.addWidget(self.det_msg,    1, 0, 1, 2)
        l.addWidget(self.suppress,   2, 0, 1, 2, Qt.AlignLeft|Qt.AlignBottom)
        l.addWidget(self.bb,         3, 0, 1, 2, Qt.AlignRight|Qt.AlignBottom)
        l.setColumnStretch(1, 100)

        self.setModal(False)
        self.suppress.setVisible(False)
        self.do_resize()

    def update_suppress_state(self):
        self.suppress.setText(_(
            'Hide the remaining %d error messages'%len(self.queue)))
        self.suppress.setVisible(len(self.queue) > 3)
        self.do_resize()

    def copy_to_clipboard(self, *args):
        d = QTextDocument()
        d.setHtml(self.msg_label.text())
        QApplication.clipboard().setText(
                u'calibre, version %s (%s, isfrozen: %s)\n%s: %s\n\n%s' %
                (__version__, sys.platform, isfrozen,
                    unicode(self.windowTitle()), unicode(d.toPlainText()),
                    unicode(self.det_msg.toPlainText())))
        if hasattr(self, 'ctc_button'):
            self.ctc_button.setText(_('Copied'))

    def toggle_det_msg(self, *args):
        vis = unicode(self.det_msg_toggle.text()) == self.hide_det_msg
        self.det_msg_toggle.setText(self.show_det_msg if vis else
                self.hide_det_msg)
        self.det_msg.setVisible(not vis)
        self.do_resize()

    def do_resize(self):
        h = self.sizeHint().height()
        self.setMinimumHeight(0)  # Needed as this gets set if det_msg is shown
        # Needed otherwise re-showing the box after showing det_msg causes the box
        # to not reduce in height
        self.setMaximumHeight(h)
        self.resize(QSize(self.WIDTH, h))

    def showEvent(self, ev):
        ret = QDialog.showEvent(self, ev)
        self.bb.button(self.bb.Close).setFocus(Qt.OtherFocusReason)
        return ret

    def show_error(self, title, msg, det_msg=u''):
        self.queue.append((title, msg, det_msg))
        self.update_suppress_state()
        self.pop()

    def pop(self):
        if not self.queue or self.isVisible():
            return
        title, msg, det_msg = self.queue.pop(0)
        self.setWindowTitle(title)
        self.msg_label.setText(msg)
        self.det_msg.setPlainText(det_msg)
        self.det_msg.setVisible(False)
        self.det_msg_toggle.setText(self.show_det_msg)
        self.det_msg_toggle.setVisible(True)
        self.suppress.setChecked(False)
        self.update_suppress_state()
        if not det_msg:
            self.det_msg_toggle.setVisible(False)
        self.do_resize()
        self.show()

    def done(self, r):
        if self.suppress.isChecked():
            self.queue = []
        QDialog.done(self, r)
        self.do_pop.emit()