Ejemplo n.º 1
0
    def __init__(self, parent=None, add_clear_action=True):
        QComboBox.__init__(self, parent)
        self.normal_background = 'rgb(255, 255, 255, 0%)'
        self.line_edit = SearchLineEdit(self)
        self.setLineEdit(self.line_edit)
        if add_clear_action:
            self.clear_action = self.add_action('clear_left.png')
            self.clear_action.triggered.connect(self.clear_clicked)

        c = self.line_edit.completer()
        c.setCompletionMode(c.PopupCompletion)
        c.highlighted[str].connect(self.completer_used)

        self.line_edit.key_pressed.connect(self.key_pressed, type=Qt.DirectConnection)
        # QueuedConnection as workaround for https://bugreports.qt-project.org/browse/QTBUG-40807
        self.activated[str].connect(self.history_selected, type=Qt.QueuedConnection)
        self.setEditable(True)
        self.as_you_type = True
        self.timer = QTimer()
        self.timer.setSingleShot(True)
        self.timer.timeout.connect(self.timer_event, type=Qt.QueuedConnection)
        self.setInsertPolicy(self.NoInsert)
        self.setMaxCount(self.MAX_COUNT)
        self.setSizeAdjustPolicy(self.AdjustToMinimumContentsLengthWithIcon)
        self.setMinimumContentsLength(25)
        self._in_a_search = False
        self.tool_tip_text = self.toolTip()
Ejemplo n.º 2
0
    def initialise (self, univers):
        model = QStandardItemModel (3,1)
    
        i = 0
        for faction in univers.faction_list :
            item = QStandardItem(faction.name)
            item.setFlags(QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsEnabled);
            item.setData(QtCore.Qt.Unchecked, QtCore.Qt.CheckStateRole);

            model.setItem(i, 0, item)
            i = i + 1

        combo = QComboBox()
        combo.setModel(model)

        list_v = QListView()
        list_v.setModel(model)

        table = QTableView()
        table.setModel(model)

        container = QWidget()
        containerLayout = QVBoxLayout()
        container.setLayout(containerLayout)
        containerLayout.addWidget(combo)
        containerLayout.addWidget(list_v)
        containerLayout.addWidget(table)
Ejemplo n.º 3
0
    def __init__(self, parent=None):
        QComboBox.__init__(self, parent)
        self.setEditable(True)
        self.setLineEdit(EnLineEdit(self))

        for item in self.ENCODINGS:
            self.addItem(item)
Ejemplo n.º 4
0
 def __init__(self, name, layout):
     QComboBox.__init__(self)
     self.setEditable(False)
     opt = options[name]
     self.choices = opt.choices
     tuple(map(self.addItem, opt.choices))
     self.currentIndexChanged.connect(self.changed_signal.emit)
     init_opt(self, opt, layout)
Ejemplo n.º 5
0
    def __init__(self, parent_dialog, plugin_action):
        self.parent_dialog = parent_dialog
        self.plugin_action = plugin_action
        QWidget.__init__(self)
        
        self.l = QVBoxLayout()
        self.setLayout(self.l)

        label = QLabel(_("If you have custom columns defined, they will be listed below.  Choose how you would like these columns handled."))
        label.setWordWrap(True)
        self.l.addWidget(label)
        self.l.addSpacing(5)
        
        scrollable = QScrollArea()
        scrollcontent = QWidget()
        scrollable.setWidget(scrollcontent)
        scrollable.setWidgetResizable(True)
        self.l.addWidget(scrollable)

        self.sl = QVBoxLayout()
        scrollcontent.setLayout(self.sl)
        
        self.custcol_dropdowns = {}

        custom_columns = self.plugin_action.gui.library_view.model().custom_columns

        grid = QGridLayout()
        self.sl.addLayout(grid)
        row=0
        for key, column in custom_columns.iteritems():
            if column['datatype'] in permitted_values:
                # print("\n============== %s ===========\n"%key)
                # for (k,v) in column.iteritems():
                #     print("column['%s'] => %s"%(k,v))
                label = QLabel('%s(%s)'%(column['name'],key))
                label.setToolTip(_("Set this %s column on new merged books...")%column['datatype'])
                grid.addWidget(label,row,0)

                dropdown = QComboBox(self)
                dropdown.addItem('','none')
                for md in permitted_values[column['datatype']]:
                    # tags-like column also 'text'
                    if md == 'union' and not column['is_multiple']:
                        continue
                    if md == 'concat' and column['is_multiple']:
                        continue
                    dropdown.addItem(titleLabels[md],md)
                self.custcol_dropdowns[key] = dropdown
                if key in prefs['custom_cols']:
                    dropdown.setCurrentIndex(dropdown.findData(prefs['custom_cols'][key]))
                dropdown.setToolTip(_("How this column will be populated by default."))
                grid.addWidget(dropdown,row,1)
                row+=1
        
        self.sl.insertStretch(-1)
Ejemplo n.º 6
0
 def __init__(self, parent):
     QComboBox.__init__(self, parent)
     self.addItems([_('Normal'), _('Regex')])
     self.setToolTip('<style>dd {margin-bottom: 1.5ex}</style>' + _(
         '''Select how the search expression is interpreted
         <dl>
         <dt><b>Normal</b></dt>
         <dd>The search expression is treated as normal text, calibre will look for the exact text.</dd>
         <dt><b>Regex</b></dt>
         <dd>The search expression is interpreted as a regular expression. See the User Manual for more help on using regular expressions.</dd>
         </dl>'''))
Ejemplo n.º 7
0
 def keyPressEvent(self, event):
     k = event.key()
     if k in (Qt.Key_Enter, Qt.Key_Return):
         return self.do_search()
     if k not in (Qt.Key_Up, Qt.Key_Down):
         QComboBox.keyPressEvent(self, event)
     else:
         self.blockSignals(True)
         self.normalize_state()
         QComboBox.keyPressEvent(self, event)
         self.blockSignals(False)
Ejemplo n.º 8
0
 def test():
     w = QWidget()
     l = FlowLayout(w)
     la = QLabel('Some text in a label')
     l.addWidget(la)
     c = QCheckBox('A checkboxy widget')
     l.addWidget(c)
     cb = QComboBox()
     cb.addItems(['Item one'])
     l.addWidget(cb)
     return w
Ejemplo n.º 9
0
 def __init__(self, parent):
     QComboBox.__init__(self, parent)
     self.addItems([_('Down'), _('Up')])
     self.setToolTip('<style>dd {margin-bottom: 1.5ex}</style>' + _(
         '''
         Direction to search:
         <dl>
         <dt><b>Down</b></dt>
         <dd>Search for the next match from your current position</dd>
         <dt><b>Up</b></dt>
         <dd>Search for the previous match from your current position</dd>
         </dl>'''))
Ejemplo n.º 10
0
 def __init__(self, parent=None, is_half_star=False):
     QComboBox.__init__(self, parent)
     self.undo_stack = QUndoStack(self)
     self.undo, self.redo = self.undo_stack.undo, self.undo_stack.redo
     self.allow_undo = False
     self.is_half_star = is_half_star
     self._model = RatingModel(is_half_star=is_half_star, parent=self)
     self.setModel(self._model)
     self.delegate = QStyledItemDelegate(self)
     self.view().setItemDelegate(self.delegate)
     self.view().setStyleSheet("QListView { background: palette(window) }\nQListView::item { padding: 6px }")
     self.setMaxVisibleItems(self.count())
     self.currentIndexChanged.connect(self.update_font)
Ejemplo n.º 11
0
class ConfigWidget(QWidget):
    def __init__(self, plugin_action):
        QWidget.__init__(self)
        self.plugin_action = plugin_action
        layout = QVBoxLayout(self)
        self.setLayout(layout)

        # copy of preferences
        self.tmpserials = plugin_prefs['kobo_serials']

        combo_label = QLabel(_('When should Obok try to insert EPUBs into existing calibre entries?'), self)
        layout.addWidget(combo_label)
        self.find_homes = QComboBox()
        self.find_homes.setToolTip(_('<p>Default behavior when duplicates are detected. None of the choices will cause calibre ebooks to be overwritten'))
        layout.addWidget(self.find_homes)
        self.find_homes.addItems([_('Ask'), _('Always'), _('Never')])
        index = self.find_homes.findText(plugin_prefs['finding_homes_for_formats'])
        self.find_homes.setCurrentIndex(index)

        self.serials_button = QtGui.QPushButton(self)
        self.serials_button.setToolTip(_(u"Click to manage Kobo serial numbers for Kobo ebooks"))
        self.serials_button.setText(u"Kobo devices serials")
        self.serials_button.clicked.connect(self.edit_serials)
        layout.addWidget(self.serials_button)


    def edit_serials(self):
        d = ManageKeysDialog(self,u"Kobo device serial numbers",self.tmpserials, AddSerialDialog)
        d.exec_()

    
    def save_settings(self):
        plugin_prefs['finding_homes_for_formats'] = unicode(self.find_homes.currentText())
        plugin_prefs['kobo_serials'] = self.tmpserials
Ejemplo n.º 12
0
 def keyPressEvent(self, event):
     k = event.key()
     if k in (Qt.Key_Enter, Qt.Key_Return):
         return self.do_search()
     if k not in (Qt.Key_Up, Qt.Key_Down):
         return QComboBox.keyPressEvent(self, event)
     self.blockSignals(True)
     self.normalize_state()
     if k == Qt.Key_Down and self.currentIndex() == 0 and not self.lineEdit().text():
         self.setCurrentIndex(1), self.setCurrentIndex(0)
         event.accept()
     else:
         QComboBox.keyPressEvent(self, event)
     self.blockSignals(False)
Ejemplo n.º 13
0
    def __init__(self):
        QWidget.__init__(self)
        self.layout = QGridLayout()
        self.setLayout(self.layout)
        labelColumnWidths = []

        self.opdsUrlLabel = QLabel('OPDS URL: ')
        self.layout.addWidget(self.opdsUrlLabel, 0, 0)
        labelColumnWidths.append(self.layout.itemAtPosition(0, 0).sizeHint().width())

        print type(prefs.defaults['opds_url'])
        print type(prefs['opds_url'])
        convertSingleStringOpdsUrlPreferenceToListOfStringsPreference()
        self.opdsUrlEditor = QComboBox(self)
        self.opdsUrlEditor.addItems(prefs['opds_url'])
        self.opdsUrlEditor.setEditable(True)
        self.opdsUrlEditor.setInsertPolicy(QComboBox.InsertAtTop)
        self.layout.addWidget(self.opdsUrlEditor, 0, 1)
        self.opdsUrlLabel.setBuddy(self.opdsUrlEditor)

        self.hideNewsCheckbox = QCheckBox('Hide Newspapers', self)
        self.hideNewsCheckbox.setChecked(prefs['hideNewspapers'])
        self.layout.addWidget(self.hideNewsCheckbox, 1, 0)
        labelColumnWidths.append(self.layout.itemAtPosition(1, 0).sizeHint().width())

        self.hideBooksAlreadyInLibraryCheckbox = QCheckBox('Hide books already in library', self)
        self.hideBooksAlreadyInLibraryCheckbox.setChecked(prefs['hideBooksAlreadyInLibrary'])
        self.layout.addWidget(self.hideBooksAlreadyInLibraryCheckbox, 2, 0)
        labelColumnWidths.append(self.layout.itemAtPosition(2, 0).sizeHint().width())

        labelColumnWidth = max(labelColumnWidths)
        self.layout.setColumnMinimumWidth(1, labelColumnWidth * 2)
    def __init__(self):
        QWidget.__init__(self)
        self.l = QVBoxLayout()
        self.setLayout(self.l)

        self.cbox1 = QCheckBox("Reformatting")
        self.cbox1.setChecked(prefs["reformat"])
        self.l.addWidget(self.cbox1)

        self.cbox5 = QCheckBox("Paragraph by Ending mark")
        self.cbox5.setChecked(prefs["para_by_mark"])
        self.l.addWidget(self.cbox5)

        self.cbox2 = QCheckBox("Pretty Quote char")
        self.cbox2.setChecked(prefs["pretty_quote"])
        self.l.addWidget(self.cbox2)

        self.cbox3 = QCheckBox("Guess Chapter")
        self.cbox3.setChecked(prefs["guess_chapter"])
        self.l.addWidget(self.cbox3)

        self.cbox4 = QCheckBox("Allow Empty Paragraph")
        self.cbox4.setChecked(prefs["insert_empty_paragraph"])
        self.l.addWidget(self.cbox4)

        cl = QHBoxLayout()
        cl.addWidget(QLabel("Broken Word over lines"))
        self.combo1 = QComboBox()
        wbrk_list = ["None", "Pattern", "Naver"]
        self.combo1.addItems(wbrk_list)
        self.combo1.setCurrentIndex(wbrk_list.index(prefs["correct_word_break"]))
        cl.addWidget(self.combo1)
        self.l.addLayout(cl)
Ejemplo n.º 15
0
    def setupTextActions(self):
        tb = QToolBar(self)
        tb.setWindowTitle("Format Actions")
        self.addToolBar(tb)

        tb = QToolBar(self)
        tb.setAllowedAreas(Qt.TopToolBarArea | Qt.BottomToolBarArea)
        tb.setWindowTitle("Format Actions")
        self.addToolBarBreak(Qt.TopToolBarArea)
        self.addToolBar(tb)

        self.comboFont = QFontComboBox(tb)
        tb.addWidget(self.comboFont)
        self.comboFont.activated[str].connect(self.textFamily)

        self.comboSize = QComboBox(tb)
        self.comboSize.setObjectName("comboSize")
        tb.addWidget(self.comboSize)
        self.comboSize.setEditable(True)

        db = QFontDatabase()
        for size in db.standardSizes():
            self.comboSize.addItem('{}'.format(size))

        self.comboSize.activated[str].connect(self.textSize)
        self.comboSize.setCurrentIndex(self.comboSize.findText('{}'.format(QApplication.font().pointSize())))
Ejemplo n.º 16
0
    def __init__(self, fm, parent=None):
        QWidget.__init__(self, parent)
        self.fm = fm

        self.action_map = self.ACTION_MAP

        self.l = l = QGridLayout(self)
        self.setLayout(l)

        texts = _('If the ___ column ___ values')
        try:
            one, two, three = texts.split('___')
        except:
            one, two, three = 'If the ', ' column ', ' value '

        self.l1 = l1 = QLabel(one)
        l.addWidget(l1, 0, 0)

        self.column_box = QComboBox(self)
        l.addWidget(self.column_box, 0, 1)

        self.l2 = l2 = QLabel(two)
        l.addWidget(l2, 0, 2)

        self.action_box = QComboBox(self)
        l.addWidget(self.action_box, 0, 3)

        self.l3 = l3 = QLabel(three)
        l.addWidget(l3, 0, 4)

        self.value_box = QLineEdit(self)
        l.addWidget(self.value_box, 0, 5)

        self.column_box.addItem('', '')
        for key in sorted(
                conditionable_columns(fm),
                key=lambda(key): sort_key(fm[key]['name'])):
            self.column_box.addItem(fm[key]['name'], key)
        self.column_box.setCurrentIndex(0)

        self.column_box.currentIndexChanged.connect(self.init_action_box)
        self.action_box.currentIndexChanged.connect(self.init_value_box)

        for b in (self.column_box, self.action_box):
            b.setSizeAdjustPolicy(b.AdjustToMinimumContentsLengthWithIcon)
            b.setMinimumContentsLength(20)
Ejemplo n.º 17
0
    def choices_widget(self, name, choices, fallback_val, none_val, prefs=None):
        prefs = prefs or tprefs
        widget = QComboBox(self)
        widget.currentIndexChanged[int].connect(self.emit_changed)
        for key, human in sorted(choices.iteritems(), key=lambda key_human: key_human[1] or key_human[0]):
            widget.addItem(human or key, key)

        def getter(w):
            ans = unicode(w.itemData(w.currentIndex()) or '')
            return {none_val:None}.get(ans, ans)

        def setter(w, val):
            val = {None:none_val}.get(val, val)
            idx = w.findData(val, flags=Qt.MatchFixedString|Qt.MatchCaseSensitive)
            if idx == -1:
                idx = w.findData(fallback_val, flags=Qt.MatchFixedString|Qt.MatchCaseSensitive)
            w.setCurrentIndex(idx)

        return self(name, widget=widget, getter=getter, setter=setter, prefs=prefs)
Ejemplo n.º 18
0
    def __init__(self, parent=None):
        QComboBox.__init__(self, parent)
        self.normal_background = 'rgb(255, 255, 255, 0%)'

        self.line_edit = SearchLineEdit(self)
        self.setLineEdit(self.line_edit)
        self.line_edit.key_pressed.connect(self.key_pressed, type=Qt.DirectConnection)
        self.activated[str].connect(self.saved_search_selected)

        # Turn off auto-completion so that it doesn't interfere with typing
        # names of new searches.
        completer = QCompleter(self)
        self.setCompleter(completer)

        self.setEditable(True)
        self.setInsertPolicy(self.NoInsert)
        self.setSizeAdjustPolicy(self.AdjustToMinimumContentsLengthWithIcon)
        self.setMinimumContentsLength(10)
        self.tool_tip_text = self.toolTip()
Ejemplo n.º 19
0
    def __init__(self, plugin_action):
        QWidget.__init__(self)
        self.plugin_action = plugin_action
        layout = QVBoxLayout(self)
        self.setLayout(layout)

        # --- Directory Options ---
        directory_group_box = QGroupBox(_('Default Unpack Directory:'), self)
        layout.addWidget(directory_group_box)
        directory_group_box_layout = QVBoxLayout()
        directory_group_box.setLayout(directory_group_box_layout)

        # Directory path Textbox
        # Load the textbox with the current preference setting
        self.directory_txtBox = QLineEdit(plugin_prefs['Unpack_Folder'], self)
        self.directory_txtBox.setToolTip(_('<p>Default directory to extract files to'))
        directory_group_box_layout.addWidget(self.directory_txtBox)
        self.directory_txtBox.setReadOnly(True)

        # Folder select button
        directory_button = QPushButton(_('Select/Change Unpack Directory'), self)
        directory_button.setToolTip(_('<p>Select/Change directory to extract files to.'))
        # Connect button to the getDirectory function
        directory_button.clicked.connect(self.getDirectory)
        directory_group_box_layout.addWidget(directory_button)
        self.default_folder_check = QCheckBox(_('Always use the Default Unpack Directory'), self)
        self.default_folder_check.setToolTip(_('<p>When unchecked... you will be prompted to select a destination '+
                                                                                'directory for the extracted content each time you use Mobiunpack.'))
        directory_group_box_layout.addWidget(self.default_folder_check)
        # Load the checkbox with the current preference setting
        self.default_folder_check.setChecked(plugin_prefs['Always_Use_Unpack_Folder'])

        misc_group_box = QGroupBox(_('Default settings:'), self)
        layout.addWidget(misc_group_box)
        misc_group_box_layout = QVBoxLayout()
        misc_group_box.setLayout(misc_group_box_layout)

        self.use_hd_images = QCheckBox(_('Always use HD images if present'), self)
        self.use_hd_images.setToolTip(_('<p>When checked... any HD images present in the kindlebook '+
                                                                                'will be used for creating the ePub.'))
        misc_group_box_layout.addWidget(self.use_hd_images)
        # Load the checkbox with the current preference setting
        self.use_hd_images.setChecked(plugin_prefs['Use_HD_Images'])

        combo_label = QLabel('Select epub version output:', self)
        misc_group_box_layout.addWidget(combo_label)
        self.epub_version_combobox = QComboBox()
        self.epub_version_combobox.setToolTip(_('<p>Select the type of OPF file to create.'))
        misc_group_box_layout.addWidget(self.epub_version_combobox)
        self.epub_version_combobox.addItems(['Auto-detect', 'ePub2', 'ePub3'])
        if plugin_prefs['Epub_Version'] == 'A':
            self.epub_version_combobox.setCurrentIndex(0)
        else:
            self.epub_version_combobox.setCurrentIndex(int(plugin_prefs['Epub_Version'])-1)
Ejemplo n.º 20
0
 def __init__(self, parent, emphasize=False):
     QComboBox.__init__(self)
     self.addItems([_('Current file'), _('All text files'), _('Selected files')])
     self.setToolTip('<style>dd {margin-bottom: 1.5ex}</style>' + _(
         '''
         Where to search/replace:
         <dl>
         <dt><b>Current file</b></dt>
         <dd>Search only inside the currently opened file</dd>
         <dt><b>All text files</b></dt>
         <dd>Search in all text (HTML) files</dd>
         <dt><b>Selected files</b></dt>
         <dd>Search in the files currently selected in the Files Browser</dd>
         </dl>'''))
     self.emphasize = emphasize
     self.ofont = QFont(self.font())
     if emphasize:
         f = self.emph_font = QFont(self.ofont)
         f.setBold(True), f.setItalic(True)
         self.setFont(f)
Ejemplo n.º 21
0
 def __init__(self, prefs, configName, title):
     QWidget.__init__(self)
     self.l = QVBoxLayout()
     self.setLayout(self.l)
     
     self.configName = configName
 
     self.hotkeyLayout = QHBoxLayout()
     self.l.addLayout(self.hotkeyLayout)
     
     enabledLabel = QLabel(title)
     self.hotkeyLayout.addWidget(enabledLabel)
     
     self.enabledBox = QCheckBox()
     self.hotkeyLayout.addWidget(self.enabledBox)
     self.enabledBox.setChecked(prefs[configName + '_hotkey_enabled'])
     
     hotkeyLayout2 = QHBoxLayout()
     self.l.addLayout(hotkeyLayout2)
     
     ctrlLabel = QLabel("Ctrl")
     self.ctrlBox = QCheckBox()
     self.ctrlBox.setChecked(prefs[configName + '_hotkey_ctrl'])
     
     ctrlLabel.setBuddy(self.ctrlBox)
     hotkeyLayout2.addWidget(ctrlLabel)
     hotkeyLayout2.addWidget(self.ctrlBox)
     
     altLabel = QLabel("Alt")
     self.altBox = QCheckBox()
     self.altBox.setChecked(prefs[configName + '_hotkey_alt'])
     
     altLabel.setBuddy(self.altBox)
     hotkeyLayout2.addWidget(altLabel)
     hotkeyLayout2.addWidget(self.altBox)
     
     shiftLabel = QLabel("Shift")
     self.shiftBox = QCheckBox()
     self.shiftBox.setChecked(prefs[configName + '_hotkey_shift'])
     
     shiftLabel.setBuddy(self.shiftBox)
     hotkeyLayout2.addWidget(shiftLabel)
     hotkeyLayout2.addWidget(self.shiftBox)
     
     self.keycodeBox = QComboBox()
     for key, value in keycodes.iteritems():
         self.keycodeBox.addItem(key, value)
         
     index = self.keycodeBox.findData(prefs[configName + '_hotkey_keycode'])
     if index != -1:
         self.keycodeBox.setCurrentIndex(index)
         
     hotkeyLayout2.addWidget(self.keycodeBox)
Ejemplo n.º 22
0
    def setupRunActions(self):
        tb = QToolBar(self)
        tb.setWindowTitle("Run Actions")
        self.addToolBar(tb)

        menu = QMenu("Run", self)
        self.menuBar().addMenu(menu)

        self.actionRun = QAction(
                "&Run", self, shortcut=Qt.CTRL + Qt.Key_R)
        tb.addAction(self.actionRun)
        menu.addAction(self.actionRun)

        self.comboScannoFile = QComboBox(tb)
        self.comboScannoFile.setObjectName("comboScannoFile")
        tb.addWidget(self.comboScannoFile)
        self.comboScannoFile.setEditable(True)
        
        self.comboLogFile= QComboBox(tb)
        self.comboLogFile.setObjectName("comboLogFile")
        self.comboLogFile.setEditable(True)
        tb.addWidget(self.comboLogFile)
Ejemplo n.º 23
0
    def __init__(self, parent=None):
        QComboBox.__init__(self, parent)
        self.normal_background = 'rgb(255, 255, 255, 0%)'
        self.line_edit = SearchLineEdit(self)
        self.setLineEdit(self.line_edit)

        c = self.line_edit.completer()
        c.setCompletionMode(c.PopupCompletion)
        c.highlighted[str].connect(self.completer_used)
        c.activated[str].connect(self.history_selected)

        self.line_edit.key_pressed.connect(self.key_pressed, type=Qt.DirectConnection)
        self.activated.connect(self.history_selected)
        self.setEditable(True)
        self.as_you_type = True
        self.timer = QTimer()
        self.timer.setSingleShot(True)
        self.timer.timeout.connect(self.timer_event, type=Qt.QueuedConnection)
        self.setInsertPolicy(self.NoInsert)
        self.setMaxCount(self.MAX_COUNT)
        self.setSizeAdjustPolicy(self.AdjustToMinimumContentsLengthWithIcon)
        self.setMinimumContentsLength(25)
        self._in_a_search = False
        self.tool_tip_text = self.toolTip()
Ejemplo n.º 24
0
 def keyPressEvent(self, ev):
     if ev == QKeySequence.Undo:
         self.undo()
         return ev.accept()
     if ev == QKeySequence.Redo:
         self.redo()
         return ev.accept()
     k = ev.key()
     num = {getattr(Qt, "Key_%d" % i): i for i in range(6)}.get(k)
     if num is None:
         return QComboBox.keyPressEvent(self, ev)
     ev.accept()
     if self.is_half_star:
         num *= 2
     self.setCurrentIndex(num)
Ejemplo n.º 25
0
 def setData (self,list_items):
     size = min(self.frameSize().width()/2.0,self.frameSize().height())
     self.size_pie = QSize(size,size)
     self.data = list_items
     if self.initialize == False:
         self.c_box = QComboBox()
         self.c_box.addItem("warrior")
         self.c_box.addItem("rank")
         self.c_box.addItem("power")
         self.c_box.currentIndexChanged.connect(self.update)
         proxy = self.my_scene.addWidget(self.c_box)
         
         proxy.setPos(QPointF(0.0,self.margin['top']))    
         self.margin['top']+=self.c_box.height()
         self.initialize = True
     self.update()
Ejemplo n.º 26
0
    def setup_ui(self):
        self.l = l = QVBoxLayout(self)
        self.setLayout(l)

        self.tl = tl = QFormLayout()
        self.semantic_type = QComboBox(self)
        for key, val in self.all_types.iteritems():
            self.semantic_type.addItem(val, key)
        tl.addRow(_('Type of &semantics:'), self.semantic_type)
        self.target = t = QLineEdit(self)
        t.setPlaceholderText(_('The destination (href) for the link'))
        tl.addRow(_('&Target:'), t)
        l.addLayout(tl)

        self.hline = hl = QFrame(self)
        hl.setFrameStyle(hl.HLine)
        l.addWidget(hl)

        self.h = h = QHBoxLayout()
        l.addLayout(h)

        names = [n for n, linear in self.container.spine_names]
        fn, f = create_filterable_names_list(names, filter_text=_('Filter files'), parent=self)
        self.file_names, self.file_names_filter = fn, f
        fn.selectionModel().selectionChanged.connect(self.selected_file_changed)
        self.fnl = fnl = QVBoxLayout()
        self.la1 = la = QLabel(_('Choose a &file:'))
        la.setBuddy(fn)
        fnl.addWidget(la), fnl.addWidget(f), fnl.addWidget(fn)
        h.addLayout(fnl), h.setStretch(0, 2)

        fn, f = create_filterable_names_list([], filter_text=_('Filter locations'), parent=self)
        self.anchor_names, self.anchor_names_filter = fn, f
        fn.selectionModel().selectionChanged.connect(self.update_target)
        fn.doubleClicked.connect(self.accept, type=Qt.QueuedConnection)
        self.anl = fnl = QVBoxLayout()
        self.la2 = la = QLabel(_('Choose a &location (anchor) in the file:'))
        la.setBuddy(fn)
        fnl.addWidget(la), fnl.addWidget(f), fnl.addWidget(fn)
        h.addLayout(fnl), h.setStretch(1, 1)

        self.bb.addButton(self.bb.Help)
        self.bb.helpRequested.connect(self.help_requested)
        l.addWidget(self.bb)
        self.semantic_type_changed()
        self.semantic_type.currentIndexChanged.connect(self.semantic_type_changed)
        self.target.textChanged.connect(self.target_text_changed)
Ejemplo n.º 27
0
    def setData (self,list_items):
        size = min(self.frameSize().width()/2.0,self.frameSize().height())
        self.size_pie = QSize(size,size)
        #print ('size pie ',self.size_pie)
        if self.initialize == False:
            self.c_box = QComboBox()
            self.c_box.addItem("all")
            self.c_box.addItem("alive")
            self.c_box.addItem("dead")
            self.c_box.currentIndexChanged.connect(self.update)
            proxy = self.my_scene.addWidget(self.c_box)
            x = self.size_pie.width()+ self.space
            proxy.setPos(QPointF(x,self.margin['top']))    
            self.initialize = True

        self.data = list_items
        self.update()
Ejemplo n.º 28
0
    def __init__(self, plugin_action):
        QWidget.__init__(self)
        self.plugin_action = plugin_action
        layout = QVBoxLayout(self)
        self.setLayout(layout)

        combo_label = QLabel(_("When should Obok try to insert EPUBs into existing calibre entries?"), self)
        layout.addWidget(combo_label)
        self.find_homes = QComboBox()
        self.find_homes.setToolTip(
            _(
                "<p>Default behavior when duplicates are detected. None of the choices will cause calibre ebooks to be overwritten"
            )
        )
        layout.addWidget(self.find_homes)
        self.find_homes.addItems([_("Ask"), _("Always"), _("Never")])
        index = self.find_homes.findText(plugin_prefs["finding_homes_for_formats"])
        self.find_homes.setCurrentIndex(index)
Ejemplo n.º 29
0
    def setup_ui(self, parent):
        self.widgets = [QLabel('&'+self.col_metadata['name']+':', parent)]
        w = QWidget(parent)
        self.widgets.append(w)

        l = QHBoxLayout()
        l.setContentsMargins(0, 0, 0, 0)
        w.setLayout(l)
        self.combobox = QComboBox(parent)
        l.addWidget(self.combobox)

        t = _('Yes')
        c = QPushButton(t, parent)
        width = c.fontMetrics().boundingRect(t).width() + 7
        c.setMaximumWidth(width)
        l.addWidget(c)
        c.clicked.connect(self.set_to_yes)

        t = _('No')
        c = QPushButton(t, parent)
        width = c.fontMetrics().boundingRect(t).width() + 7
        c.setMaximumWidth(width)
        l.addWidget(c)
        c.clicked.connect(self.set_to_no)

        t = _('Clear')
        c = QPushButton(t, parent)
        width = c.fontMetrics().boundingRect(t).width() + 7
        c.setMaximumWidth(width)
        l.addWidget(c)
        c.clicked.connect(self.set_to_cleared)

        c = QLabel('', parent)
        c.setMaximumWidth(1)
        l.addWidget(c, 1)

        w = self.combobox
        items = [_('Yes'), _('No'), _('Undefined')]
        icons = [I('ok.png'), I('list_remove.png'), I('blank.png')]
        if not self.db.prefs.get('bools_are_tristate'):
            items = items[:-1]
            icons = icons[:-1]
        for icon, text in zip(icons, items):
            w.addItem(QIcon(icon), text)
Ejemplo n.º 30
0
    def __init__(self, parent=None):
        super().__init__(parent)

        self.lineEditPPScannos = QLineEdit()
        self.lineEditPPScannos.setReadOnly(True)
        self.comboScannoFiles = QComboBox()
        
        labelPPScannosLoc = QLabel('PPScannos File')
        labelPPScannosLoc.setBuddy(self.lineEditPPScannos)
        labelScannoLoc = QLabel('Default Scanno File')
        labelScannoLoc.setBuddy(self.comboScannoFiles)

        self.buttonPPScannos = QPushButton('Change')
        self.buttonPPScannos.pressed.connect(self.openFileDlg)
        
        hbox = QHBoxLayout()
        hbox.addWidget(labelPPScannosLoc)
        hbox.addWidget(self.lineEditPPScannos)
        hbox.addWidget(self.buttonPPScannos)
        
        self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)

        self.buttonBox.accepted.connect(self.accept)
        self.buttonBox.rejected.connect(self.reject)

        mainLayout = QGridLayout()
        mainLayout.addLayout(hbox, 0, 0, 2, 0)
        mainLayout.addWidget(labelScannoLoc, 1, 0)
        mainLayout.addWidget(self.comboScannoFiles, 1, 1)
        mainLayout.addWidget(self.buttonBox, 5, 0, 1, 2)
        self.setLayout(mainLayout)

        self.populate()
        
        self.lineEditPPScannos.textChanged.connect(self.ppscannosChanged)

        self.setWindowTitle("Configure Gui Scannos")
        self.resize(650, 400)
Ejemplo n.º 31
0
 def __init__(self, parent, values, selected_value=None):
     QComboBox.__init__(self, parent)
     self.values = values
     if selected_value is not None:
         self.populate_combo(selected_value)
Ejemplo n.º 32
0
    def setup_ui(self):
        self.vl = vl = QVBoxLayout(self)
        self.stack = l = QStackedLayout()
        self.pi = pi = ProgressIndicator(self, 256)
        vl.addLayout(l), vl.addWidget(self.bb)
        self.restore_defs_button = b = self.bb.addButton(
            _('Restore &default icons'), self.bb.ActionRole)
        b.clicked.connect(self.restore_defaults)
        b.setIcon(QIcon(I('view-refresh.png')))
        self.c = c = QWidget(self)
        self.c.v = v = QVBoxLayout(self.c)
        v.addStretch(), v.addWidget(pi, 0, Qt.AlignCenter)
        self.wait_msg = m = QLabel(self)
        v.addWidget(m, 0, Qt.AlignCenter), v.addStretch()
        m.setStyleSheet('QLabel { font-size: 40px; font-weight: bold }')
        self.start_spinner()

        l.addWidget(c)
        self.w = w = QWidget(self)
        l.addWidget(w)
        w.l = l = QGridLayout(w)

        def add_row(x, y=None):
            if isinstance(x, type('')):
                x = QLabel(x)
            row = l.rowCount()
            if y is None:
                if isinstance(x, QLabel):
                    x.setWordWrap(True)
                l.addWidget(x, row, 0, 1, 2)
            else:
                if isinstance(x, QLabel):
                    x.setBuddy(y)
                l.addWidget(x, row, 0), l.addWidget(y, row, 1)

        add_row(
            _('Choose an icon theme below. You will need to restart'
              ' calibre to see the new icons.'))
        add_row(
            _('Current icon theme:') + '\xa0<b>' +
            (self.current_theme or 'None'))
        self.sort_by = sb = QComboBox(self)
        add_row(_('&Sort by:'), sb)
        sb.addItems([
            _('Number of icons'),
            _('Popularity'),
            _('Name'),
        ])
        sb.setEditable(False), sb.setCurrentIndex(
            gprefs.get('choose_icon_theme_sort_by', 1))
        sb.currentIndexChanged[int].connect(self.re_sort)
        sb.currentIndexChanged[int].connect(
            lambda: gprefs.set('choose_icon_theme_sort_by', sb.currentIndex()))
        self.theme_list = tl = QListWidget(self)
        tl.setVerticalScrollMode(tl.ScrollPerPixel)
        self.delegate = Delegate(tl)
        tl.setItemDelegate(self.delegate)
        tl.itemDoubleClicked.connect(self.accept)
        add_row(tl)

        t = Thread(name='GetIconThemes', target=self.get_themes)
        t.daemon = True
        t.start()
Ejemplo n.º 33
0
 def __init__(self, parent, custom_columns={}, selected_column='', initial_items=['']):
     QComboBox.__init__(self, parent)
     self.populate_combo(custom_columns, selected_column, initial_items)
Ejemplo n.º 34
0
    def __init__(self, gui, existing_names, editing=None):
        QDialog.__init__(self, gui)

        self.gui = gui
        self.existing_names = existing_names

        if editing:
            self.setWindowTitle(_('Edit virtual library'))
        else:
            self.setWindowTitle(_('Create virtual library'))
        self.setWindowIcon(QIcon(I('lt.png')))

        gl = QGridLayout()
        self.setLayout(gl)
        self.la1 = la1 = QLabel(_('Virtual library &name:'))
        gl.addWidget(la1, 0, 0)
        self.vl_name = QComboBox()
        self.vl_name.setEditable(True)
        self.vl_name.lineEdit().setMaxLength(MAX_VIRTUAL_LIBRARY_NAME_LENGTH)
        la1.setBuddy(self.vl_name)
        gl.addWidget(self.vl_name, 0, 1)
        self.editing = editing

        self.saved_searches_label = sl = QTextBrowser(self)
        sl.viewport().setAutoFillBackground(False)
        gl.addWidget(sl, 2, 0, 1, 2)

        self.la2 = la2 = QLabel(_('&Search expression:'))
        gl.addWidget(la2, 1, 0)
        self.vl_text = QLineEdit()
        self.vl_text.textChanged.connect(self.search_text_changed)
        la2.setBuddy(self.vl_text)
        gl.addWidget(self.vl_text, 1, 1)
        self.vl_text.setText(_build_full_search_string(self.gui))

        self.sl = sl = QLabel(
            '<p>' + _('Create a virtual library based on: ') +
            ('<a href="author.{0}">{0}</a>, '
             '<a href="tag.{1}">{1}</a>, '
             '<a href="publisher.{2}">{2}</a>, '
             '<a href="series.{3}">{3}</a>, '
             '<a href="search.{4}">{4}</a>.').format(_('Authors'), _(
                 'Tags'), _('Publishers'), _('Series'), _('Saved searches')))
        sl.setWordWrap(True)
        sl.setTextInteractionFlags(Qt.LinksAccessibleByMouse)
        sl.linkActivated.connect(self.link_activated)
        gl.addWidget(sl, 3, 0, 1, 2)
        gl.setRowStretch(3, 10)

        self.hl = hl = QLabel(
            _('''
            <h2>Virtual libraries</h2>

            <p>Using <i>virtual libraries</i> you can restrict calibre to only show
            you books that match a search. When a virtual library is in effect, calibre
            behaves as though the library contains only the matched books. The Tag browser
            display only the tags/authors/series/etc. that belong to the matched books and any searches
            you do will only search within the books in the virtual library. This
            is a good way to partition your large library into smaller and easier to work with subsets.</p>

            <p>For example you can use a Virtual library to only show you books with the Tag <i>"Unread"</i>
            or only books by <i>"My favorite author"</i> or only books in a particular series.</p>

            <p>More information and examples are available in the
            <a href="%s">User Manual</a>.</p>
            ''') % localize_user_manual_link(
                'https://manual.calibre-ebook.com/virtual_libraries.html'))
        hl.setWordWrap(True)
        hl.setOpenExternalLinks(True)
        hl.setFrameStyle(hl.StyledPanel)
        gl.addWidget(hl, 0, 3, 4, 1)

        bb = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
        bb.accepted.connect(self.accept)
        bb.rejected.connect(self.reject)
        gl.addWidget(bb, 4, 0, 1, 0)

        if editing:
            db = self.gui.current_db
            virt_libs = db.prefs.get('virtual_libraries', {})
            for dex, vl in enumerate(
                    sorted(list(virt_libs.keys()), key=sort_key)):
                self.vl_name.addItem(vl, virt_libs.get(vl, ''))
                if vl == editing:
                    self.vl_name.setCurrentIndex(dex)
                    self.original_index = dex
            self.original_search = virt_libs.get(editing, '')
            self.vl_text.setText(self.original_search)
            self.new_name = editing
            self.vl_name.currentIndexChanged[int].connect(
                self.name_index_changed)
            self.vl_name.lineEdit().textEdited.connect(self.name_text_edited)

        self.resize(self.sizeHint() + QSize(150, 25))
Ejemplo n.º 35
0
 def __init__(self, *args):
     QComboBox.__init__(self, *args)
     self.setEditable(True)
     self.setInsertPolicy(self.NoInsert)
     self.setMaxCount(10)
Ejemplo n.º 36
0
 def __init__(self, parent):
     QComboBox.__init__(self, parent)
     items = [_('All'), _('Installed'), _('Update available'), _('Not installed')]
     self.addItems(items)
Ejemplo n.º 37
0
 def hidePopup(self):
     QComboBox.hidePopup(self)
     self.set_state()
Ejemplo n.º 38
0
 def clear_history(self, *args):
     QComboBox.clear(self)
Ejemplo n.º 39
0
 def clear(self):
     QComboBox.clear(self)
     self.initialize_saved_search_names()
     self.setEditText('')
     self.setToolTip(self.tool_tip_text)
     self.line_edit.home(False)
Ejemplo n.º 40
0
    def __init__(self, gui, icon, do_user_config):
        QDialog.__init__(self, gui)
        self.gui = gui
        self.do_user_config = do_user_config

        self.db = gui.current_db.new_api

        # The model for the book list
        self.model = OpdsBooksModel(None, self.dummy_books(), self.db)
        self.searchproxymodel = QSortFilterProxyModel(self)
        self.searchproxymodel.setFilterCaseSensitivity(Qt.CaseInsensitive)
        self.searchproxymodel.setFilterKeyColumn(-1)
        self.searchproxymodel.setSourceModel(self.model)

        self.layout = QGridLayout()
        self.setLayout(self.layout)

        self.setWindowTitle('OPDS Client')
        self.setWindowIcon(icon)

        labelColumnWidths = []

        self.opdsUrlLabel = QLabel('OPDS URL: ')
        self.layout.addWidget(self.opdsUrlLabel, 0, 0)
        labelColumnWidths.append(
            self.layout.itemAtPosition(0, 0).sizeHint().width())

        config.convertSingleStringOpdsUrlPreferenceToListOfStringsPreference()
        self.opdsUrlEditor = QComboBox(self)
        self.opdsUrlEditor.activated.connect(self.opdsUrlEditorActivated)
        self.opdsUrlEditor.addItems(prefs['opds_url'])
        self.opdsUrlEditor.setEditable(True)
        self.opdsUrlEditor.setInsertPolicy(QComboBox.InsertAtTop)
        self.layout.addWidget(self.opdsUrlEditor, 0, 1, 1, 3)
        self.opdsUrlLabel.setBuddy(self.opdsUrlEditor)

        buttonColumnNumber = 7
        buttonColumnWidths = []
        self.about_button = QPushButton('About', self)
        self.about_button.setAutoDefault(False)
        self.about_button.clicked.connect(self.about)
        self.layout.addWidget(self.about_button, 0, buttonColumnNumber)
        buttonColumnWidths.append(
            self.layout.itemAtPosition(0,
                                       buttonColumnNumber).sizeHint().width())

        # Initially download the catalogs found in the root catalog of the URL
        # selected at startup.  Fail quietly on failing to open the URL
        catalogsTuple = self.model.downloadOpdsRootCatalog(
            self.gui, self.opdsUrlEditor.currentText(), False)
        print(catalogsTuple)
        firstCatalogTitle = catalogsTuple[0]
        self.currentOpdsCatalogs = catalogsTuple[
            1]  # A dictionary of title->feedURL

        self.opdsCatalogSelectorLabel = QLabel('OPDS Catalog:')
        self.layout.addWidget(self.opdsCatalogSelectorLabel, 1, 0)
        labelColumnWidths.append(
            self.layout.itemAtPosition(1, 0).sizeHint().width())

        self.opdsCatalogSelector = QComboBox(self)
        self.opdsCatalogSelector.setEditable(False)
        self.opdsCatalogSelectorModel = QStringListModel(
            self.currentOpdsCatalogs.keys())
        self.opdsCatalogSelector.setModel(self.opdsCatalogSelectorModel)
        self.opdsCatalogSelector.setCurrentText(firstCatalogTitle)
        self.layout.addWidget(self.opdsCatalogSelector, 1, 1, 1, 3)

        self.download_opds_button = QPushButton('Download OPDS', self)
        self.download_opds_button.setAutoDefault(False)
        self.download_opds_button.clicked.connect(self.download_opds)
        self.layout.addWidget(self.download_opds_button, 1, buttonColumnNumber)
        buttonColumnWidths.append(
            self.layout.itemAtPosition(1,
                                       buttonColumnNumber).sizeHint().width())

        # Search GUI
        self.searchEditor = QLineEdit(self)
        self.searchEditor.returnPressed.connect(self.searchBookList)
        self.layout.addWidget(self.searchEditor, 2, buttonColumnNumber - 2, 1,
                              2)

        self.searchButton = QPushButton('Search', self)
        self.searchButton.setAutoDefault(False)
        self.searchButton.clicked.connect(self.searchBookList)
        self.layout.addWidget(self.searchButton, 2, buttonColumnNumber)
        buttonColumnWidths.append(
            self.layout.itemAtPosition(2,
                                       buttonColumnNumber).sizeHint().width())

        # The main book list
        self.library_view = QTableView(self)
        self.library_view.setAlternatingRowColors(True)
        self.library_view.setModel(self.searchproxymodel)
        self.library_view.horizontalHeader().setSectionResizeMode(
            0, QHeaderView.Stretch)
        self.library_view.horizontalHeader().setSectionResizeMode(
            1, QHeaderView.Stretch)
        self.library_view.horizontalHeader().setSectionResizeMode(
            2, QHeaderView.Stretch)
        self.library_view.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.resizeAllLibraryViewLinesToHeaderHeight()
        self.library_view.resizeColumnsToContents()
        self.layout.addWidget(self.library_view, 3, 0, 3,
                              buttonColumnNumber + 1)

        self.hideNewsCheckbox = QCheckBox('Hide Newspapers', self)
        self.hideNewsCheckbox.clicked.connect(self.setHideNewspapers)
        self.hideNewsCheckbox.setChecked(prefs['hideNewspapers'])
        self.layout.addWidget(self.hideNewsCheckbox, 6, 0, 1, 3)

        self.hideBooksAlreadyInLibraryCheckbox = QCheckBox(
            'Hide books already in library', self)
        self.hideBooksAlreadyInLibraryCheckbox.clicked.connect(
            self.setHideBooksAlreadyInLibrary)
        self.hideBooksAlreadyInLibraryCheckbox.setChecked(
            prefs['hideBooksAlreadyInLibrary'])
        self.layout.addWidget(self.hideBooksAlreadyInLibraryCheckbox, 7, 0, 1,
                              3)

        # Let the checkbox initial state control the filtering
        self.model.setFilterBooksThatAreNewspapers(
            self.hideNewsCheckbox.isChecked())
        self.model.setFilterBooksThatAreAlreadyInLibrary(
            self.hideBooksAlreadyInLibraryCheckbox.isChecked())

        self.downloadButton = QPushButton('Download selected books', self)
        self.downloadButton.setAutoDefault(False)
        self.downloadButton.clicked.connect(self.downloadSelectedBooks)
        self.layout.addWidget(self.downloadButton, 6, buttonColumnNumber)
        buttonColumnWidths.append(
            self.layout.itemAtPosition(6,
                                       buttonColumnNumber).sizeHint().width())

        self.fixTimestampButton = QPushButton('Fix timestamps of selection',
                                              self)
        self.fixTimestampButton.setAutoDefault(False)
        self.fixTimestampButton.clicked.connect(self.fixBookTimestamps)
        self.layout.addWidget(self.fixTimestampButton, 7, buttonColumnNumber)
        buttonColumnWidths.append(
            self.layout.itemAtPosition(7,
                                       buttonColumnNumber).sizeHint().width())

        # Make all columns of the grid layout the same width as the button column
        buttonColumnWidth = max(buttonColumnWidths)
        for columnNumber in range(0, buttonColumnNumber):
            self.layout.setColumnMinimumWidth(columnNumber, buttonColumnWidth)

        # Make sure the first column isn't wider than the labels it holds
        labelColumnWidth = max(labelColumnWidths)
        self.layout.setColumnMinimumWidth(0, labelColumnWidth)

        self.resize(self.sizeHint())
Ejemplo n.º 41
0
class OpdsDialog(QDialog):
    def __init__(self, gui, icon, do_user_config):
        QDialog.__init__(self, gui)
        self.gui = gui
        self.do_user_config = do_user_config

        self.db = gui.current_db.new_api

        # The model for the book list
        self.model = OpdsBooksModel(None, self.dummy_books(), self.db)
        self.searchproxymodel = QSortFilterProxyModel(self)
        self.searchproxymodel.setFilterCaseSensitivity(Qt.CaseInsensitive)
        self.searchproxymodel.setFilterKeyColumn(-1)
        self.searchproxymodel.setSourceModel(self.model)

        self.layout = QGridLayout()
        self.setLayout(self.layout)

        self.setWindowTitle('OPDS Client')
        self.setWindowIcon(icon)

        labelColumnWidths = []

        self.opdsUrlLabel = QLabel('OPDS URL: ')
        self.layout.addWidget(self.opdsUrlLabel, 0, 0)
        labelColumnWidths.append(
            self.layout.itemAtPosition(0, 0).sizeHint().width())

        config.convertSingleStringOpdsUrlPreferenceToListOfStringsPreference()
        self.opdsUrlEditor = QComboBox(self)
        self.opdsUrlEditor.activated.connect(self.opdsUrlEditorActivated)
        self.opdsUrlEditor.addItems(prefs['opds_url'])
        self.opdsUrlEditor.setEditable(True)
        self.opdsUrlEditor.setInsertPolicy(QComboBox.InsertAtTop)
        self.layout.addWidget(self.opdsUrlEditor, 0, 1, 1, 3)
        self.opdsUrlLabel.setBuddy(self.opdsUrlEditor)

        buttonColumnNumber = 7
        buttonColumnWidths = []
        self.about_button = QPushButton('About', self)
        self.about_button.setAutoDefault(False)
        self.about_button.clicked.connect(self.about)
        self.layout.addWidget(self.about_button, 0, buttonColumnNumber)
        buttonColumnWidths.append(
            self.layout.itemAtPosition(0,
                                       buttonColumnNumber).sizeHint().width())

        # Initially download the catalogs found in the root catalog of the URL
        # selected at startup.  Fail quietly on failing to open the URL
        catalogsTuple = self.model.downloadOpdsRootCatalog(
            self.gui, self.opdsUrlEditor.currentText(), False)
        print(catalogsTuple)
        firstCatalogTitle = catalogsTuple[0]
        self.currentOpdsCatalogs = catalogsTuple[
            1]  # A dictionary of title->feedURL

        self.opdsCatalogSelectorLabel = QLabel('OPDS Catalog:')
        self.layout.addWidget(self.opdsCatalogSelectorLabel, 1, 0)
        labelColumnWidths.append(
            self.layout.itemAtPosition(1, 0).sizeHint().width())

        self.opdsCatalogSelector = QComboBox(self)
        self.opdsCatalogSelector.setEditable(False)
        self.opdsCatalogSelectorModel = QStringListModel(
            self.currentOpdsCatalogs.keys())
        self.opdsCatalogSelector.setModel(self.opdsCatalogSelectorModel)
        self.opdsCatalogSelector.setCurrentText(firstCatalogTitle)
        self.layout.addWidget(self.opdsCatalogSelector, 1, 1, 1, 3)

        self.download_opds_button = QPushButton('Download OPDS', self)
        self.download_opds_button.setAutoDefault(False)
        self.download_opds_button.clicked.connect(self.download_opds)
        self.layout.addWidget(self.download_opds_button, 1, buttonColumnNumber)
        buttonColumnWidths.append(
            self.layout.itemAtPosition(1,
                                       buttonColumnNumber).sizeHint().width())

        # Search GUI
        self.searchEditor = QLineEdit(self)
        self.searchEditor.returnPressed.connect(self.searchBookList)
        self.layout.addWidget(self.searchEditor, 2, buttonColumnNumber - 2, 1,
                              2)

        self.searchButton = QPushButton('Search', self)
        self.searchButton.setAutoDefault(False)
        self.searchButton.clicked.connect(self.searchBookList)
        self.layout.addWidget(self.searchButton, 2, buttonColumnNumber)
        buttonColumnWidths.append(
            self.layout.itemAtPosition(2,
                                       buttonColumnNumber).sizeHint().width())

        # The main book list
        self.library_view = QTableView(self)
        self.library_view.setAlternatingRowColors(True)
        self.library_view.setModel(self.searchproxymodel)
        self.library_view.horizontalHeader().setSectionResizeMode(
            0, QHeaderView.Stretch)
        self.library_view.horizontalHeader().setSectionResizeMode(
            1, QHeaderView.Stretch)
        self.library_view.horizontalHeader().setSectionResizeMode(
            2, QHeaderView.Stretch)
        self.library_view.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.resizeAllLibraryViewLinesToHeaderHeight()
        self.library_view.resizeColumnsToContents()
        self.layout.addWidget(self.library_view, 3, 0, 3,
                              buttonColumnNumber + 1)

        self.hideNewsCheckbox = QCheckBox('Hide Newspapers', self)
        self.hideNewsCheckbox.clicked.connect(self.setHideNewspapers)
        self.hideNewsCheckbox.setChecked(prefs['hideNewspapers'])
        self.layout.addWidget(self.hideNewsCheckbox, 6, 0, 1, 3)

        self.hideBooksAlreadyInLibraryCheckbox = QCheckBox(
            'Hide books already in library', self)
        self.hideBooksAlreadyInLibraryCheckbox.clicked.connect(
            self.setHideBooksAlreadyInLibrary)
        self.hideBooksAlreadyInLibraryCheckbox.setChecked(
            prefs['hideBooksAlreadyInLibrary'])
        self.layout.addWidget(self.hideBooksAlreadyInLibraryCheckbox, 7, 0, 1,
                              3)

        # Let the checkbox initial state control the filtering
        self.model.setFilterBooksThatAreNewspapers(
            self.hideNewsCheckbox.isChecked())
        self.model.setFilterBooksThatAreAlreadyInLibrary(
            self.hideBooksAlreadyInLibraryCheckbox.isChecked())

        self.downloadButton = QPushButton('Download selected books', self)
        self.downloadButton.setAutoDefault(False)
        self.downloadButton.clicked.connect(self.downloadSelectedBooks)
        self.layout.addWidget(self.downloadButton, 6, buttonColumnNumber)
        buttonColumnWidths.append(
            self.layout.itemAtPosition(6,
                                       buttonColumnNumber).sizeHint().width())

        self.fixTimestampButton = QPushButton('Fix timestamps of selection',
                                              self)
        self.fixTimestampButton.setAutoDefault(False)
        self.fixTimestampButton.clicked.connect(self.fixBookTimestamps)
        self.layout.addWidget(self.fixTimestampButton, 7, buttonColumnNumber)
        buttonColumnWidths.append(
            self.layout.itemAtPosition(7,
                                       buttonColumnNumber).sizeHint().width())

        # Make all columns of the grid layout the same width as the button column
        buttonColumnWidth = max(buttonColumnWidths)
        for columnNumber in range(0, buttonColumnNumber):
            self.layout.setColumnMinimumWidth(columnNumber, buttonColumnWidth)

        # Make sure the first column isn't wider than the labels it holds
        labelColumnWidth = max(labelColumnWidths)
        self.layout.setColumnMinimumWidth(0, labelColumnWidth)

        self.resize(self.sizeHint())

    def opdsUrlEditorActivated(self, text):
        prefs['opds_url'] = config.saveOpdsUrlCombobox(self.opdsUrlEditor)
        catalogsTuple = self.model.downloadOpdsRootCatalog(
            self.gui, self.opdsUrlEditor.currentText(), True)
        firstCatalogTitle = catalogsTuple[0]
        self.currentOpdsCatalogs = catalogsTuple[
            1]  # A dictionary of title->feedURL
        self.opdsCatalogSelectorModel.setStringList(
            self.currentOpdsCatalogs.keys())
        self.opdsCatalogSelector.setCurrentText(firstCatalogTitle)

    def setHideNewspapers(self, checked):
        prefs['hideNewspapers'] = checked
        self.model.setFilterBooksThatAreNewspapers(checked)
        self.resizeAllLibraryViewLinesToHeaderHeight()

    def setHideBooksAlreadyInLibrary(self, checked):
        prefs['hideBooksAlreadyInLibrary'] = checked
        self.model.setFilterBooksThatAreAlreadyInLibrary(checked)
        self.resizeAllLibraryViewLinesToHeaderHeight()

    def searchBookList(self):
        searchString = self.searchEditor.text()
        print("starting book list search for: %s" % searchString)
        self.searchproxymodel.setFilterFixedString(searchString)

    def about(self):
        text = get_resources('about.txt')
        QMessageBox.about(self, 'About the OPDS Client plugin',
                          text.decode('utf-8'))

    def download_opds(self):
        opdsCatalogUrl = self.currentOpdsCatalogs.get(
            self.opdsCatalogSelector.currentText(), None)
        if opdsCatalogUrl is None:
            # Just give up quietly
            return
        self.model.downloadOpdsCatalog(self.gui, opdsCatalogUrl)
        if self.model.isCalibreOpdsServer():
            self.model.downloadMetadataUsingCalibreRestApi(
                self.opdsUrlEditor.currentText())
        self.library_view.horizontalHeader().setSectionResizeMode(
            0, QHeaderView.Stretch)
        self.library_view.horizontalHeader().setSectionResizeMode(
            1, QHeaderView.Stretch)
        self.library_view.horizontalHeader().setSectionResizeMode(
            2, QHeaderView.Stretch)
        self.resizeAllLibraryViewLinesToHeaderHeight()
        self.resize(self.sizeHint())

    def config(self):
        self.do_user_config(parent=self)

    def downloadSelectedBooks(self):
        selectionmodel = self.library_view.selectionModel()
        if selectionmodel.hasSelection():
            rows = selectionmodel.selectedRows()
            for row in reversed(rows):
                book = row.data(Qt.UserRole)
                self.downloadBook(book)

    def downloadBook(self, book):
        if len(book.links) > 0:
            self.gui.download_ebook(book.links[0])

    def fixBookTimestamps(self):
        selectionmodel = self.library_view.selectionModel()
        if selectionmodel.hasSelection():
            rows = selectionmodel.selectedRows()
            for row in reversed(rows):
                book = row.data(Qt.UserRole)
                self.fixBookTimestamp(book)

    def fixBookTimestamp(self, book):
        bookTimestamp = book.timestamp
        identicalBookIds = self.findIdenticalBooksForBooksWithMultipleAuthors(
            book)
        bookIdToValMap = {}
        for identicalBookId in identicalBookIds:
            bookIdToValMap[identicalBookId] = bookTimestamp
        if len(bookIdToValMap) < 1:
            print("Failed to set timestamp of book: %s" % book)
        self.db.set_field('timestamp', bookIdToValMap)

    def findIdenticalBooksForBooksWithMultipleAuthors(self, book):
        authorsList = book.authors
        if len(authorsList) < 2:
            return self.db.find_identical_books(book)
        # Try matching the authors one by one
        identicalBookIds = set()
        for author in authorsList:
            singleAuthorBook = Metadata(book.title, [author])
            singleAuthorIdenticalBookIds = self.db.find_identical_books(
                singleAuthorBook)
            identicalBookIds = identicalBookIds.union(
                singleAuthorIdenticalBookIds)
        return identicalBookIds

    def dummy_books(self):
        dummy_author = ' ' * 40
        dummy_title = ' ' * 60
        books_list = []
        for line in range(1, 10):
            book = DynamicBook()
            book.author = dummy_author
            book.title = dummy_title
            book.updated = datetime.datetime.now().strftime(
                '%Y-%m-%dT%H:%M:%S+00:00')
            book.id = ''
            books_list.append(book)
        return books_list

    def resizeAllLibraryViewLinesToHeaderHeight(self):
        rowHeight = self.library_view.horizontalHeader().height()
        for rowNumber in range(0, self.library_view.model().rowCount()):
            self.library_view.setRowHeight(rowNumber, rowHeight)
Ejemplo n.º 42
0
class InsertSemantics(Dialog):
    def __init__(self, container, parent=None):
        self.container = container
        self.anchor_cache = {}
        self.original_type_map = {
            item.get('type', ''):
            (container.href_to_name(item.get('href'), container.opf_name),
             item.get('href', '').partition('#')[-1])
            for item in container.opf_xpath(
                '//opf:guide/opf:reference[@href and @type]')
        }
        self.final_type_map = self.original_type_map.copy()
        self.create_known_type_map()
        Dialog.__init__(self,
                        _('Set semantics'),
                        'insert-semantics',
                        parent=parent)

    def sizeHint(self):
        return QSize(800, 600)

    def create_known_type_map(self):
        _ = lambda x: x
        self.known_type_map = {
            'title-page': _('Title Page'),
            'toc': _('Table of Contents'),
            'index': _('Index'),
            'glossary': _('Glossary'),
            'acknowledgements': _('Acknowledgements'),
            'bibliography': _('Bibliography'),
            'colophon': _('Colophon'),
            'copyright-page': _('Copyright page'),
            'dedication': _('Dedication'),
            'epigraph': _('Epigraph'),
            'foreword': _('Foreword'),
            'loi': _('List of illustrations'),
            'lot': _('List of tables'),
            'notes': _('Notes'),
            'preface': _('Preface'),
            'text': _('Text'),
        }
        _ = __builtins__['_']
        type_map_help = {
            'title-page': _('Page with title, author, publisher, etc.'),
            'index': _('Back-of-book style index'),
            'text': _('First "real" page of content'),
        }
        t = _
        all_types = [
            (k, (('%s (%s)' %
                  (t(v), type_map_help[k])) if k in type_map_help else t(v)))
            for k, v in self.known_type_map.iteritems()
        ]
        all_types.sort(key=lambda x: sort_key(x[1]))
        self.all_types = OrderedDict(all_types)

    def setup_ui(self):
        self.l = l = QVBoxLayout(self)
        self.setLayout(l)

        self.tl = tl = QFormLayout()
        self.semantic_type = QComboBox(self)
        for key, val in self.all_types.iteritems():
            self.semantic_type.addItem(val, key)
        tl.addRow(_('Type of &semantics:'), self.semantic_type)
        self.target = t = QLineEdit(self)
        t.setPlaceholderText(_('The destination (href) for the link'))
        tl.addRow(_('&Target:'), t)
        l.addLayout(tl)

        self.hline = hl = QFrame(self)
        hl.setFrameStyle(hl.HLine)
        l.addWidget(hl)

        self.h = h = QHBoxLayout()
        l.addLayout(h)

        names = [n for n, linear in self.container.spine_names]
        fn, f = create_filterable_names_list(names,
                                             filter_text=_('Filter files'),
                                             parent=self)
        self.file_names, self.file_names_filter = fn, f
        fn.selectionModel().selectionChanged.connect(
            self.selected_file_changed)
        self.fnl = fnl = QVBoxLayout()
        self.la1 = la = QLabel(_('Choose a &file:'))
        la.setBuddy(fn)
        fnl.addWidget(la), fnl.addWidget(f), fnl.addWidget(fn)
        h.addLayout(fnl), h.setStretch(0, 2)

        fn, f = create_filterable_names_list([],
                                             filter_text=_('Filter locations'),
                                             parent=self)
        self.anchor_names, self.anchor_names_filter = fn, f
        fn.selectionModel().selectionChanged.connect(self.update_target)
        fn.doubleClicked.connect(self.accept, type=Qt.QueuedConnection)
        self.anl = fnl = QVBoxLayout()
        self.la2 = la = QLabel(_('Choose a &location (anchor) in the file:'))
        la.setBuddy(fn)
        fnl.addWidget(la), fnl.addWidget(f), fnl.addWidget(fn)
        h.addLayout(fnl), h.setStretch(1, 1)

        self.bb.addButton(self.bb.Help)
        self.bb.helpRequested.connect(self.help_requested)
        l.addWidget(self.bb)
        self.semantic_type_changed()
        self.semantic_type.currentIndexChanged.connect(
            self.semantic_type_changed)
        self.target.textChanged.connect(self.target_text_changed)

    def help_requested(self):
        d = info_dialog(
            self, _('About semantics'),
            _('Semantics refer to additional information about specific locations in the book.'
              ' For example, you can specify that a particular location is the dedication or the preface'
              ' or the table of contents and so on.\n\nFirst choose the type of semantic information, then'
              ' choose a file and optionally a location within the file to point to.\n\nThe'
              ' semantic information will be written in the <guide> section of the opf file.'
              ))
        d.resize(d.sizeHint())
        d.exec_()

    def semantic_type_changed(self):
        item_type = unicode(
            self.semantic_type.itemData(self.semantic_type.currentIndex())
            or '')
        name, frag = self.final_type_map.get(item_type, (None, None))
        self.show_type(name, frag)

    def show_type(self, name, frag):
        self.file_names_filter.clear(), self.anchor_names_filter.clear()
        self.file_names.clearSelection(), self.anchor_names.clearSelection()
        if name is not None:
            row = self.file_names.model().find_name(name)
            if row is not None:
                sm = self.file_names.selectionModel()
                sm.select(self.file_names.model().index(row),
                          sm.ClearAndSelect)
                if frag:
                    row = self.anchor_names.model().find_name(frag)
                    if row is not None:
                        sm = self.anchor_names.selectionModel()
                        sm.select(self.anchor_names.model().index(row),
                                  sm.ClearAndSelect)
        self.target.blockSignals(True)
        if name is not None:
            self.target.setText(name + (('#' + frag) if frag else ''))
        else:
            self.target.setText('')
        self.target.blockSignals(False)

    def target_text_changed(self):
        name, frag = unicode(self.target.text()).partition('#')[::2]
        item_type = unicode(
            self.semantic_type.itemData(self.semantic_type.currentIndex())
            or '')
        self.final_type_map[item_type] = (name, frag or None)

    def selected_file_changed(self, *args):
        rows = list(self.file_names.selectionModel().selectedRows())
        if not rows:
            self.anchor_names.model().set_names([])
        else:
            name, positions = self.file_names.model().data(
                rows[0], Qt.UserRole)
            self.populate_anchors(name)

    def populate_anchors(self, name):
        if name not in self.anchor_cache:
            from calibre.ebooks.oeb.base import XHTML_NS
            root = self.container.parsed(name)
            self.anchor_cache[name] = sorted((set(root.xpath('//*/@id')) | set(
                root.xpath('//h:a/@name', namespaces={'h': XHTML_NS}))) - {''},
                                             key=primary_sort_key)
        self.anchor_names.model().set_names(self.anchor_cache[name])
        self.update_target()

    def update_target(self):
        rows = list(self.file_names.selectionModel().selectedRows())
        if not rows:
            return
        name = self.file_names.model().data(rows[0], Qt.UserRole)[0]
        href = name
        frag = ''
        rows = list(self.anchor_names.selectionModel().selectedRows())
        if rows:
            anchor = self.anchor_names.model().data(rows[0], Qt.UserRole)[0]
            if anchor:
                frag = '#' + anchor
        href += frag
        self.target.setText(href or '#')

    @property
    def changed_type_map(self):
        return {
            k: v
            for k, v in self.final_type_map.iteritems()
            if v != self.original_type_map.get(k, None)
        }

    def apply_changes(self, container):
        from calibre.ebooks.oeb.polish.opf import set_guide_item, get_book_language
        from calibre.translations.dynamic import translate
        lang = get_book_language(container)
        for item_type, (name, frag) in self.changed_type_map.iteritems():
            title = self.known_type_map[item_type]
            if lang:
                title = translate(lang, title)
            set_guide_item(container, item_type, title, name, frag=frag)

    @classmethod
    def test(cls):
        import sys
        from calibre.ebooks.oeb.polish.container import get_container
        c = get_container(sys.argv[-1], tweak_mode=True)
        d = cls(c)
        if d.exec_() == d.Accepted:
            import pprint
            pprint.pprint(d.changed_type_map)
            d.apply_changes(d.container)
Ejemplo n.º 43
0
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        self.l = gl = QGridLayout(self)
        self.setLayout(gl)
        self.changed = False

        self.bars = b = QComboBox(self)
        b.addItem(_('Choose which toolbar you want to customize'))
        ft = _('Tools for %s editors')
        for name, text in (
            (
                'global_book_toolbar',
                _('Book wide actions'),
            ),
            (
                'global_tools_toolbar',
                _('Book wide tools'),
            ),
            (
                'global_plugins_toolbar',
                _('Book wide tools from third party plugins'),
            ),
            ('editor_common_toolbar', ft % _('all')),
            (
                'editor_html_toolbar',
                ft % 'HTML',
            ),
            (
                'editor_css_toolbar',
                ft % 'CSS',
            ),
            (
                'editor_xml_toolbar',
                ft % 'XML',
            ),
            (
                'editor_format_toolbar',
                _('Text formatting actions'),
            ),
        ):
            b.addItem(text, name)
        self.la = la = QLabel(_('&Toolbar to customize:'))
        la.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        la.setBuddy(b)
        gl.addWidget(la), gl.addWidget(b, 0, 1)
        self.sl = l = QGridLayout()
        gl.addLayout(l, 1, 0, 1, -1)

        self.gb1 = gb1 = QGroupBox(_('A&vailable actions'), self)
        self.gb2 = gb2 = QGroupBox(_('&Current actions'), self)
        gb1.setFlat(True), gb2.setFlat(True)
        gb1.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        gb2.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        l.addWidget(gb1, 0, 0, -1, 1), l.addWidget(gb2, 0, 2, -1, 1)
        self.available, self.current = ToolbarList(self), ToolbarList(self)
        self.ub = b = QToolButton(self)
        b.clicked.connect(partial(self.move, up=True))
        b.setToolTip(_('Move selected action up')), b.setIcon(
            QIcon(I('arrow-up.png')))
        self.db = b = QToolButton(self)
        b.clicked.connect(partial(self.move, up=False))
        b.setToolTip(_('Move selected action down')), b.setIcon(
            QIcon(I('arrow-down.png')))
        self.gl1 = gl1 = QVBoxLayout()
        gl1.addWidget(self.available), gb1.setLayout(gl1)
        self.gl2 = gl2 = QGridLayout()
        gl2.addWidget(self.current, 0, 0, -1, 1)
        gl2.addWidget(self.ub, 0, 1), gl2.addWidget(self.db, 2, 1)
        gb2.setLayout(gl2)
        self.lb = b = QToolButton(self)
        b.setToolTip(_('Add selected actions to toolbar')), b.setIcon(
            QIcon(I('forward.png')))
        l.addWidget(b, 1, 1), b.clicked.connect(self.add_action)
        self.rb = b = QToolButton(self)
        b.setToolTip(_('Remove selected actions from toolbar')), b.setIcon(
            QIcon(I('back.png')))
        l.addWidget(b, 3, 1), b.clicked.connect(self.remove_action)
        self.si = QSpacerItem(20,
                              10,
                              hPolicy=QSizePolicy.Preferred,
                              vPolicy=QSizePolicy.Expanding)
        l.setRowStretch(0, 10), l.setRowStretch(2, 10), l.setRowStretch(4, 10)
        l.addItem(self.si, 4, 1)

        self.read_settings()
        self.toggle_visibility(False)
        self.bars.currentIndexChanged.connect(self.bar_changed)
Ejemplo n.º 44
0
 def add_listbox(self, name, items, callback):
     self.listboxes[name] = listbox = QComboBox()
     listbox.addItems(items)
     listbox.currentIndexChanged.connect(callback)
     self.layout.addWidget(listbox)
Ejemplo n.º 45
0
 def showPopup(self):
     self.setItemText(0, '')
     QComboBox.showPopup(self)
Ejemplo n.º 46
0
    def _set_common_down_ui(self):
        slider_frame = QFrame()
        slider_layout = QGridLayout(slider_frame)
        self.layout.addWidget(slider_frame)

        label = QLabel(i18n[self.lang]['Speed'] + ':')
        self.slider_speed = QSlider(Qt.Horizontal)
        self.spinbox_speed = QSpinBox()
        self.slider_speed.setMinimum(1)
        self.slider_speed.setMaximum(1000)
        self.slider_speed.setValue(50)
        self.spinbox_speed.setSingleStep(1)
        self.spinbox_speed.setMinimum(1)
        self.spinbox_speed.setMaximum(1000)
        self.spinbox_speed.setValue(50)
        slider_layout.addWidget(label, 0, 0)
        slider_layout.addWidget(self.slider_speed, 0, 1)
        slider_layout.addWidget(self.spinbox_speed, 0, 2)

        label = QLabel(i18n[self.lang]['Acc'] + ':')
        self.slider_acc = QSlider(Qt.Horizontal)
        self.spinbox_acc = QSpinBox()
        self.slider_acc.setMinimum(1)
        self.slider_acc.setMaximum(100000)
        self.slider_acc.setValue(5000)
        self.spinbox_acc.setSingleStep(1)
        self.spinbox_acc.setMinimum(1)
        self.spinbox_acc.setMaximum(100000)
        self.spinbox_acc.setValue(5000)
        slider_layout.addWidget(label, 0, 3)
        slider_layout.addWidget(self.slider_acc, 0, 4)
        slider_layout.addWidget(self.spinbox_acc, 0, 5)

        common_frame = QFrame()
        common_layout = QGridLayout(common_frame)
        self.layout.addWidget(common_frame)

        self.btn_stop = QPushButton(i18n[self.lang]['Stop'])
        self.btn_clean = QPushButton(i18n[self.lang]['CleanErrorWarn'])
        self.btn_reset = QPushButton(i18n[self.lang]['Reset'])
        self.btn_get_servo_dbmsg = QPushButton(
            i18n[self.lang]['GetServoDebugMsg'])

        common_layout.addWidget(self.btn_stop, 0, 0)
        common_layout.addWidget(self.btn_clean, 0, 2)
        common_layout.addWidget(self.btn_reset, 0, 3)
        common_layout.addWidget(self.btn_get_servo_dbmsg, 0, 4)

        btn_frame = QFrame()
        btn_layout = QGridLayout(btn_frame)
        self.layout.addWidget(btn_frame)

        self.combobox_servo = QComboBox()
        self.combobox_servo.setStyleSheet('''color: blue;''')
        for item in [
                'axis-all', 'axis-1', 'axis-2', 'axis-3', 'axis-4', 'axis-5',
                'axis-6', 'axis-7'
        ]:
            self.combobox_servo.addItem(item)
        self.combobox_servo.setCurrentIndex(1)
        btn_layout.addWidget(self.combobox_servo, 0, 0)

        self.btn_motion_enable = QPushButton(i18n[self.lang]['MotionEnable'])
        self.btn_motion_disable = QPushButton(i18n[self.lang]['MotionDisable'])
        self.btn_servo_attach = QPushButton(i18n[self.lang]['ServoAttach'])
        self.btn_servo_detach = QPushButton(i18n[self.lang]['ServoDetach'])

        self.combobox_state = QComboBox()
        self.combobox_state.setStyleSheet('''color: blue;''')
        for item in ['sport', 'pause', 'stop']:
            self.combobox_state.addItem(item)
            self.combobox_state.setCurrentIndex(0)
        self.btn_set_state = QPushButton(i18n[self.lang]['SetState'])

        btn_layout.addWidget(self.btn_motion_enable, 0, 1)
        btn_layout.addWidget(self.btn_motion_disable, 0, 2)
        btn_layout.addWidget(self.btn_servo_attach, 0, 3)
        btn_layout.addWidget(self.btn_servo_detach, 0, 4)
        btn_layout.addWidget(self.combobox_state, 0, 5)
        btn_layout.addWidget(self.btn_set_state, 0, 6)

        self.lnt_servo_addr = QLineEdit('servo_addr')
        self.lnt_servo_addr_value = QLineEdit('value')
        self.btn_get_servo_addr16 = QPushButton(
            i18n[self.lang]['GetServoAddr16'])
        self.btn_set_servo_addr16 = QPushButton(
            i18n[self.lang]['SetServoAddr16'])
        self.btn_get_servo_addr32 = QPushButton(
            i18n[self.lang]['GetServoAddr32'])
        self.btn_set_servo_addr32 = QPushButton(
            i18n[self.lang]['SetServoAddr32'])
        self.btn_set_servo_zero = QPushButton(i18n[self.lang]['SetServoZero'])

        btn_layout.addWidget(self.lnt_servo_addr, 1, 0)
        btn_layout.addWidget(self.lnt_servo_addr_value, 1, 1)
        btn_layout.addWidget(self.btn_get_servo_addr16, 1, 2)
        btn_layout.addWidget(self.btn_set_servo_addr16, 1, 3)
        btn_layout.addWidget(self.btn_get_servo_addr32, 1, 4)
        btn_layout.addWidget(self.btn_set_servo_addr32, 1, 5)
        btn_layout.addWidget(self.btn_set_servo_zero, 1, 6)
Ejemplo n.º 47
0
class RuleEditor(QDialog):  # {{{
    @property
    def doing_multiple(self):
        return hasattr(
            self, 'multiple_icon_cb') and self.multiple_icon_cb.isChecked()

    def __init__(self, fm, pref_name, parent=None):
        QDialog.__init__(self, parent)
        self.fm = fm

        if pref_name == 'column_color_rules':
            self.rule_kind = 'color'
            rule_text = _('column coloring')
        elif pref_name == 'column_icon_rules':
            self.rule_kind = 'icon'
            rule_text = _('column icon')
        elif pref_name == 'cover_grid_icon_rules':
            self.rule_kind = 'emblem'
            rule_text = _('cover grid emblem')

        self.setWindowIcon(QIcon(I('format-fill-color.png')))
        self.setWindowTitle(_('Create/edit a {0} rule').format(rule_text))

        self.l = l = QGridLayout(self)
        self.setLayout(l)

        self.l1 = l1 = QLabel(
            _('Create a {0} rule by'
              ' filling in the boxes below'.format(rule_text)))
        l.addWidget(l1, 0, 0, 1, 8)

        self.f1 = QFrame(self)
        self.f1.setFrameShape(QFrame.HLine)
        l.addWidget(self.f1, 1, 0, 1, 8)

        self.l2 = l2 = QLabel(
            _('Add the emblem:') if self.rule_kind ==
            'emblem' else _('Set the'))
        l.addWidget(l2, 2, 0)

        if self.rule_kind == 'color':
            l.addWidget(QLabel(_('color')))
        elif self.rule_kind == 'icon':
            self.kind_box = QComboBox(self)
            for tt, t in icon_rule_kinds:
                self.kind_box.addItem(tt, t)
            l.addWidget(self.kind_box, 2, 1)
            self.kind_box.setToolTip(
                textwrap.fill(
                    _('If you choose composed icons and multiple rules match, then all the'
                      ' matching icons will be combined, otherwise the icon from the'
                      ' first rule to match will be used.')))
        else:
            pass

        self.l3 = l3 = QLabel(_('of the column:'))
        l.addWidget(l3, 2, 2)

        self.column_box = QComboBox(self)
        l.addWidget(self.column_box, 2, 3)

        self.l4 = l4 = QLabel(_('to'))
        l.addWidget(l4, 2, 4)
        if self.rule_kind == 'emblem':
            l3.setVisible(False), self.column_box.setVisible(
                False), l4.setVisible(False)

        def create_filename_box():
            self.filename_box = f = QComboBox()
            self.filenamebox_view = v = QListView()
            v.setIconSize(QSize(32, 32))
            self.filename_box.setView(v)
            self.orig_filenamebox_view = f.view()
            f.setMinimumContentsLength(20), f.setSizeAdjustPolicy(
                f.AdjustToMinimumContentsLengthWithIcon)
            self.populate_icon_filenames()

        if self.rule_kind == 'color':
            self.color_box = ColorButton(parent=self)
            self.color_label = QLabel('Sample text Sample text')
            self.color_label.setTextFormat(Qt.RichText)
            l.addWidget(self.color_box, 2, 5)
            l.addWidget(self.color_label, 2, 6)
            l.addItem(QSpacerItem(10, 10, QSizePolicy.Expanding), 2, 7)
        elif self.rule_kind == 'emblem':
            create_filename_box()
            self.update_filename_box()
            self.filename_button = QPushButton(QIcon(I('document_open.png')),
                                               _('&Add new image'))
            l.addWidget(self.filename_box)
            l.addWidget(self.filename_button, 2, 6)
            l.addWidget(QLabel(_('(Images should be square-ish)')), 2, 7)
            l.setColumnStretch(7, 10)
        else:
            create_filename_box()

            vb = QVBoxLayout()
            self.multiple_icon_cb = QCheckBox(_('Choose more than one icon'))
            vb.addWidget(self.multiple_icon_cb)
            self.update_filename_box()
            self.multiple_icon_cb.clicked.connect(self.multiple_box_clicked)
            vb.addWidget(self.filename_box)
            l.addLayout(vb, 2, 5)

            self.filename_button = QPushButton(QIcon(I('document_open.png')),
                                               _('&Add icon'))
            l.addWidget(self.filename_button, 2, 6)
            l.addWidget(QLabel(_('Icons should be square or landscape')), 2, 7)
            l.setColumnStretch(7, 10)

        self.l5 = l5 = QLabel(
            _('Only if the following conditions are all satisfied:'))
        l.addWidget(l5, 3, 0, 1, 7)

        self.scroll_area = sa = QScrollArea(self)
        sa.setMinimumHeight(300)
        sa.setMinimumWidth(950)
        sa.setWidgetResizable(True)
        l.addWidget(sa, 4, 0, 1, 8)

        self.add_button = b = QPushButton(QIcon(I('plus.png')),
                                          _('Add another condition'))
        l.addWidget(b, 5, 0, 1, 8)
        b.clicked.connect(self.add_blank_condition)

        self.l6 = l6 = QLabel(
            _('You can disable a condition by'
              ' blanking all of its boxes'))
        l.addWidget(l6, 6, 0, 1, 8)

        self.bb = bb = QDialogButtonBox(QDialogButtonBox.Ok
                                        | QDialogButtonBox.Cancel)
        bb.accepted.connect(self.accept)
        bb.rejected.connect(self.reject)
        l.addWidget(bb, 7, 0, 1, 8)
        if self.rule_kind != 'color':
            self.remove_button = b = bb.addButton(_('Remove image'),
                                                  bb.ActionRole)
            b.setIcon(QIcon(I('minus.png')))
            b.setMenu(QMenu())
            self.update_remove_button()

        self.conditions_widget = QWidget(self)
        sa.setWidget(self.conditions_widget)
        self.conditions_widget.setLayout(QVBoxLayout())
        self.conditions_widget.layout().setAlignment(Qt.AlignTop)
        self.conditions = []

        if self.rule_kind == 'color':
            for b in (self.column_box, ):
                b.setSizeAdjustPolicy(b.AdjustToMinimumContentsLengthWithIcon)
                b.setMinimumContentsLength(15)

        for key in sorted(displayable_columns(fm),
                          key=lambda (k): sort_key(fm[k]['name'])
                          if k != color_row_key else 0):
            if key == color_row_key and self.rule_kind != 'color':
                continue
            name = all_columns_string if key == color_row_key else fm[key][
                'name']
            if name:
                self.column_box.addItem(name, key)
        self.column_box.setCurrentIndex(0)

        if self.rule_kind == 'color':
            self.color_box.color = '#000'
            self.update_color_label()
            self.color_box.color_changed.connect(self.update_color_label)
        else:
            self.rule_icon_files = []
            self.filename_button.clicked.connect(self.filename_button_clicked)

        self.resize(self.sizeHint())

    def multiple_box_clicked(self):
        self.update_filename_box()
        self.update_icon_filenames_in_box()

    @property
    def icon_folder(self):
        return os.path.join(config_dir, 'cc_icons')

    def populate_icon_filenames(self):
        d = self.icon_folder
        self.icon_file_names = []
        if os.path.exists(d):
            for icon_file in os.listdir(d):
                icon_file = lower(icon_file)
                if os.path.exists(os.path.join(
                        d, icon_file)) and icon_file.endswith('.png'):
                    self.icon_file_names.append(icon_file)
        self.icon_file_names.sort(key=sort_key)

    def update_filename_box(self):
        doing_multiple = self.doing_multiple

        model = QStandardItemModel()
        self.filename_box.setModel(model)
        self.icon_file_names.sort(key=sort_key)
        if doing_multiple:
            item = QStandardItem(_('Open to see checkboxes'))
            item.setIcon(QIcon(I('blank.png')))
        else:
            item = QStandardItem('')
        item.setFlags(Qt.ItemFlag(0))
        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(
                QPixmap(os.path.join(self.icon_folder, filename)).scaled(
                    self.filenamebox_view.iconSize(),
                    transformMode=Qt.SmoothTransformation))
            item.setIcon(icon)
            model.appendRow(item)

    def update_color_label(self):
        pal = QApplication.palette()
        bg1 = unicode(pal.color(pal.Base).name())
        bg2 = unicode(pal.color(pal.AlternateBase).name())
        c = self.color_box.color
        self.color_label.setText('''
            <span style="color: {c}; background-color: {bg1}">&nbsp;{st}&nbsp;</span>
            <span style="color: {c}; background-color: {bg2}">&nbsp;{st}&nbsp;</span>
            '''.format(c=c, bg1=bg1, bg2=bg2, st=_('Sample Text')))

    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()
                    self.update_remove_button()
                    try:
                        p = QIcon(icon_path).pixmap(QSize(128, 128))
                        d = self.icon_folder
                        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.doing_multiple:
                    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

    def get_filenames_from_box(self):
        if self.doing_multiple:
            model = self.filename_box.model()
            fnames = []
            for i in range(1, model.rowCount()):
                item = model.item(i, 0)
                if item.checkState() == Qt.Checked:
                    fnames.append(lower(unicode(item.text())))
            fname = ' : '.join(fnames)
        else:
            fname = lower(unicode(self.filename_box.currentText()))
        return fname

    def update_icon_filenames_in_box(self):
        if self.rule_icon_files:
            if not self.doing_multiple:
                idx = self.filename_box.findText(self.rule_icon_files[0])
                if idx >= 0:
                    self.filename_box.setCurrentIndex(idx)
                else:
                    self.filename_box.setCurrentIndex(0)
            else:
                model = self.filename_box.model()
                for icon in self.rule_icon_files:
                    idx = self.filename_box.findText(icon)
                    if idx >= 0:
                        item = model.item(idx)
                        item.setCheckState(Qt.Checked)

    def update_remove_button(self):
        m = self.remove_button.menu()
        m.clear()
        for name in self.icon_file_names:
            m.addAction(QIcon(os.path.join(self.icon_folder, name)),
                        name).triggered.connect(
                            partial(self.remove_image, name))

    def remove_image(self, name):
        try:
            os.remove(os.path.join(self.icon_folder, name))
        except EnvironmentError:
            pass
        else:
            self.populate_icon_filenames()
            self.update_remove_button()
            self.update_filename_box()
            self.update_icon_filenames_in_box()

    def add_blank_condition(self):
        c = ConditionEditor(self.fm, parent=self.conditions_widget)
        self.conditions.append(c)
        self.conditions_widget.layout().addWidget(c)

    def apply_rule(self, kind, col, rule):
        if kind == 'color':
            if rule.color:
                self.color_box.color = rule.color
        else:
            if self.rule_kind == 'icon':
                for i, tup in enumerate(icon_rule_kinds):
                    if kind == tup[1]:
                        self.kind_box.setCurrentIndex(i)
                        break
            self.rule_icon_files = [ic.strip() for ic in rule.color.split(':')]
            if len(self.rule_icon_files) > 1:
                self.multiple_icon_cb.setChecked(True)
            self.update_filename_box()
            self.update_icon_filenames_in_box()

        for i in range(self.column_box.count()):
            c = unicode(self.column_box.itemData(i) or '')
            if col == c:
                self.column_box.setCurrentIndex(i)
                break

        for c in rule.conditions:
            ce = ConditionEditor(self.fm, parent=self.conditions_widget)
            self.conditions.append(ce)
            self.conditions_widget.layout().addWidget(ce)
            try:
                ce.condition = c
            except:
                import traceback
                traceback.print_exc()

    def accept(self):
        if self.rule_kind != 'color':
            fname = self.get_filenames_from_box()
            if not fname:
                error_dialog(self,
                             _('No icon selected'),
                             _('You must choose an icon for this rule'),
                             show=True)
                return
        if self.validate():
            QDialog.accept(self)

    def validate(self):
        r = Rule(self.fm)
        for c in self.conditions:
            condition = c.condition
            if condition is not None:
                try:
                    r.add_condition(*condition)
                except Exception as e:
                    import traceback
                    error_dialog(self,
                                 _('Invalid condition'),
                                 _('One of the conditions for this rule is'
                                   ' invalid: <b>%s</b>') % e,
                                 det_msg=traceback.format_exc(),
                                 show=True)
                    return False
        if len(r.conditions) < 1:
            error_dialog(self,
                         _('No conditions'),
                         _('You must specify at least one non-empty condition'
                           ' for this rule'),
                         show=True)
            return False
        return True

    @property
    def rule(self):
        r = Rule(self.fm)
        if self.rule_kind != 'color':
            r.color = self.get_filenames_from_box()
        else:
            r.color = self.color_box.color
        idx = self.column_box.currentIndex()
        col = unicode(self.column_box.itemData(idx) or '')
        for c in self.conditions:
            condition = c.condition
            if condition is not None:
                r.add_condition(*condition)
        if self.rule_kind == 'icon':
            kind = unicode(
                self.kind_box.itemData(self.kind_box.currentIndex()) or '')
        else:
            kind = self.rule_kind

        return kind, col, r
Ejemplo n.º 48
0
class XArmUI(object):
    def __init__(self, ui, layout):
        self.main_ui = ui
        self.layout = layout
        super(XArmUI, self).__init__()
        self.handler = XArmHandler(self)
        self.lang = self.main_ui.lang
        self.set_ui()
        self.set_disable(True)

    def set_ui(self):
        self._set_common_top_ui()
        self._set_tab()
        self._set_common_down_ui()
        self.connect_slot()

    def _set_common_top_ui(self):
        top_frame = QFrame()
        top_frame.setMaximumHeight(60)
        top_layout = QVBoxLayout(top_frame)
        self.layout.addWidget(top_frame)

        common_top_frame = QFrame()
        common_top_frame.setMinimumHeight(50)
        common_top_layout = QHBoxLayout(common_top_frame)
        top_layout.addWidget(common_top_frame)

        label_1 = QLabel(i18n[self.lang]['Connected'] + ':')
        self.label_connected = QLabel()
        img = QImage()
        self.label_connected.setMaximumHeight(20)
        self.label_connected.setMaximumWidth(20)
        self.label_connected.setScaledContents(True)
        if img.load(disconnect_icon_path):
            self.label_connected.setPixmap(QPixmap.fromImage(img))

        label_2 = QLabel(i18n[self.lang]['Reported'] + ':')
        self.label_reported = QLabel()
        img = QImage()
        self.label_reported.setMaximumHeight(20)
        self.label_reported.setMaximumWidth(20)
        self.label_reported.setScaledContents(True)
        if img.load(disconnect_icon_path):
            self.label_reported.setPixmap(QPixmap.fromImage(img))

        self.lnt_addr = QLineEdit('192.168.1.182')
        self.lnt_addr.setMaximumWidth(100)
        self.lnt_addr.setMinimumWidth(60)
        self.btn_connect = QPushButton(i18n[self.lang]['Connect'])
        # self.btn_connect.setMaximumWidth(50)

        # common_top_layout.addStretch(0)
        common_top_layout.setSpacing(10)
        common_top_layout.addWidget(label_1)
        common_top_layout.addWidget(self.label_connected)
        common_top_layout.addWidget(label_2)
        common_top_layout.addWidget(self.label_reported)
        common_top_layout.addWidget(self.lnt_addr)
        common_top_layout.addWidget(self.btn_connect)

        # common_down_frame = QFrame()
        # common_down_layout = QHBoxLayout(common_down_frame)
        # common_down_layout.setSpacing(0)
        # top_layout.addWidget(common_down_frame)
        common_down_layout = common_top_layout

        label = QLabel(i18n[self.lang]['WarnCode'] + ':')
        self.label_warn_code = QLabel('0')
        self.label_warn_code.setStyleSheet('''color: gray;font:bold;''')
        common_down_layout.addWidget(label)
        common_down_layout.addWidget(self.label_warn_code)

        label = QLabel(i18n[self.lang]['ErrorCode'] + ':')
        self.label_error_code = QLabel('0')
        self.label_error_code.setStyleSheet('''color: gray;font:bold;''')
        common_down_layout.addWidget(label)
        common_down_layout.addWidget(self.label_error_code)

        label = QLabel(i18n[self.lang]['CmdCount'] + ':')
        self.label_cmd_count = QLabel('0')
        self.label_cmd_count.setStyleSheet('''color: gray;font:bold;''')
        common_down_layout.addWidget(label)
        common_down_layout.addWidget(self.label_cmd_count)

        label = QLabel(i18n[self.lang]['State'] + ':')
        self.label_state = QLabel('4')
        self.label_state.setStyleSheet('''color: gray;font:bold;''')
        common_down_layout.addWidget(label)
        common_down_layout.addWidget(self.label_state)

        label = QLabel(i18n[self.lang]['Maable'] + ':')
        self.label_maable = QLabel('128')
        self.label_maable.setStyleSheet('''color: gray;font:bold;''')
        common_down_layout.addWidget(label)
        common_down_layout.addWidget(self.label_maable)

        label = QLabel(i18n[self.lang]['Mtbrake'] + ':')
        self.label_mtbrake = QLabel('128')
        self.label_mtbrake.setStyleSheet('''color: gray;font:bold;''')
        common_down_layout.addWidget(label)
        common_down_layout.addWidget(self.label_mtbrake)

    def _set_tab(self):
        tab_widget = QTabWidget()
        tab_widget.setMaximumHeight(self.main_ui.window.geometry().height() //
                                    2)
        self.layout.addWidget(tab_widget)

        toolBox1 = QToolBox()
        toolBox2 = QToolBox()

        groupBox1 = QGroupBox()
        groupBox2 = QGroupBox()

        toolBox1.addItem(groupBox1, "")
        toolBox2.addItem(groupBox2, "")

        tab_widget.addTab(toolBox1, i18n[self.lang]['Joint'])
        tab_widget.addTab(toolBox2, i18n[self.lang]['Cartesian'])

        joint_layout = QVBoxLayout(groupBox1)
        cartesian_layout = QVBoxLayout(groupBox2)

        self.cartesian_ui = CartesianUI(self, cartesian_layout)
        self.axis_ui = JointUI(self, joint_layout)

    def _set_common_down_ui(self):
        slider_frame = QFrame()
        slider_layout = QGridLayout(slider_frame)
        self.layout.addWidget(slider_frame)

        label = QLabel(i18n[self.lang]['Speed'] + ':')
        self.slider_speed = QSlider(Qt.Horizontal)
        self.spinbox_speed = QSpinBox()
        self.slider_speed.setMinimum(1)
        self.slider_speed.setMaximum(1000)
        self.slider_speed.setValue(50)
        self.spinbox_speed.setSingleStep(1)
        self.spinbox_speed.setMinimum(1)
        self.spinbox_speed.setMaximum(1000)
        self.spinbox_speed.setValue(50)
        slider_layout.addWidget(label, 0, 0)
        slider_layout.addWidget(self.slider_speed, 0, 1)
        slider_layout.addWidget(self.spinbox_speed, 0, 2)

        label = QLabel(i18n[self.lang]['Acc'] + ':')
        self.slider_acc = QSlider(Qt.Horizontal)
        self.spinbox_acc = QSpinBox()
        self.slider_acc.setMinimum(1)
        self.slider_acc.setMaximum(100000)
        self.slider_acc.setValue(5000)
        self.spinbox_acc.setSingleStep(1)
        self.spinbox_acc.setMinimum(1)
        self.spinbox_acc.setMaximum(100000)
        self.spinbox_acc.setValue(5000)
        slider_layout.addWidget(label, 0, 3)
        slider_layout.addWidget(self.slider_acc, 0, 4)
        slider_layout.addWidget(self.spinbox_acc, 0, 5)

        common_frame = QFrame()
        common_layout = QGridLayout(common_frame)
        self.layout.addWidget(common_frame)

        self.btn_stop = QPushButton(i18n[self.lang]['Stop'])
        self.btn_clean = QPushButton(i18n[self.lang]['CleanErrorWarn'])
        self.btn_reset = QPushButton(i18n[self.lang]['Reset'])
        self.btn_get_servo_dbmsg = QPushButton(
            i18n[self.lang]['GetServoDebugMsg'])

        common_layout.addWidget(self.btn_stop, 0, 0)
        common_layout.addWidget(self.btn_clean, 0, 2)
        common_layout.addWidget(self.btn_reset, 0, 3)
        common_layout.addWidget(self.btn_get_servo_dbmsg, 0, 4)

        btn_frame = QFrame()
        btn_layout = QGridLayout(btn_frame)
        self.layout.addWidget(btn_frame)

        self.combobox_servo = QComboBox()
        self.combobox_servo.setStyleSheet('''color: blue;''')
        for item in [
                'axis-all', 'axis-1', 'axis-2', 'axis-3', 'axis-4', 'axis-5',
                'axis-6', 'axis-7'
        ]:
            self.combobox_servo.addItem(item)
        self.combobox_servo.setCurrentIndex(1)
        btn_layout.addWidget(self.combobox_servo, 0, 0)

        self.btn_motion_enable = QPushButton(i18n[self.lang]['MotionEnable'])
        self.btn_motion_disable = QPushButton(i18n[self.lang]['MotionDisable'])
        self.btn_servo_attach = QPushButton(i18n[self.lang]['ServoAttach'])
        self.btn_servo_detach = QPushButton(i18n[self.lang]['ServoDetach'])

        self.combobox_state = QComboBox()
        self.combobox_state.setStyleSheet('''color: blue;''')
        for item in ['sport', 'pause', 'stop']:
            self.combobox_state.addItem(item)
            self.combobox_state.setCurrentIndex(0)
        self.btn_set_state = QPushButton(i18n[self.lang]['SetState'])

        btn_layout.addWidget(self.btn_motion_enable, 0, 1)
        btn_layout.addWidget(self.btn_motion_disable, 0, 2)
        btn_layout.addWidget(self.btn_servo_attach, 0, 3)
        btn_layout.addWidget(self.btn_servo_detach, 0, 4)
        btn_layout.addWidget(self.combobox_state, 0, 5)
        btn_layout.addWidget(self.btn_set_state, 0, 6)

        self.lnt_servo_addr = QLineEdit('servo_addr')
        self.lnt_servo_addr_value = QLineEdit('value')
        self.btn_get_servo_addr16 = QPushButton(
            i18n[self.lang]['GetServoAddr16'])
        self.btn_set_servo_addr16 = QPushButton(
            i18n[self.lang]['SetServoAddr16'])
        self.btn_get_servo_addr32 = QPushButton(
            i18n[self.lang]['GetServoAddr32'])
        self.btn_set_servo_addr32 = QPushButton(
            i18n[self.lang]['SetServoAddr32'])
        self.btn_set_servo_zero = QPushButton(i18n[self.lang]['SetServoZero'])

        btn_layout.addWidget(self.lnt_servo_addr, 1, 0)
        btn_layout.addWidget(self.lnt_servo_addr_value, 1, 1)
        btn_layout.addWidget(self.btn_get_servo_addr16, 1, 2)
        btn_layout.addWidget(self.btn_set_servo_addr16, 1, 3)
        btn_layout.addWidget(self.btn_get_servo_addr32, 1, 4)
        btn_layout.addWidget(self.btn_set_servo_addr32, 1, 5)
        btn_layout.addWidget(self.btn_set_servo_zero, 1, 6)

    def connect_slot(self):
        self.btn_connect.clicked.connect(self.connect)
        self.slider_speed.valueChanged.connect(
            functools.partial(self.slider_spinbox_related,
                              slave=self.spinbox_speed,
                              scale=1))
        self.spinbox_speed.valueChanged.connect(
            functools.partial(self.slider_spinbox_related,
                              slave=self.slider_speed,
                              scale=1))
        self.slider_acc.valueChanged.connect(
            functools.partial(self.slider_spinbox_related,
                              slave=self.spinbox_acc,
                              scale=1))
        self.spinbox_acc.valueChanged.connect(
            functools.partial(self.slider_spinbox_related,
                              slave=self.slider_acc,
                              scale=1))
        self.btn_stop.clicked.connect(self.stop)
        self.btn_clean.clicked.connect(self.clean)
        self.btn_reset.clicked.connect(self.reset)
        self.btn_get_servo_dbmsg.clicked.connect(
            functools.partial(self.handler.get_servo_debug_msg,
                              only_log_error_servo=False))
        self.btn_motion_enable.clicked.connect(self.motion_enable)
        self.btn_motion_disable.clicked.connect(self.motion_disable)
        self.btn_servo_attach.clicked.connect(self.set_servo_attach)
        self.btn_servo_detach.clicked.connect(self.set_servo_detach)
        self.btn_set_state.clicked.connect(self.set_state)
        self.btn_get_servo_addr16.clicked.connect(self.get_servo_addr_16)
        self.btn_set_servo_addr16.clicked.connect(self.set_servo_addr_16)
        self.btn_get_servo_addr32.clicked.connect(self.get_servo_addr_32)
        self.btn_set_servo_addr32.clicked.connect(self.set_servo_addr_32)
        self.btn_set_servo_zero.clicked.connect(self.set_servo_zero)

    @staticmethod
    def slider_spinbox_related(value, master=None, slave=None, scale=1):
        try:
            slave.setValue(value * scale)
        except Exception as e:
            print(e)

    def reset_flag(self):
        self.cartesian_ui.reset_flag()
        self.axis_ui.reset_flag()

    def update_maable_mtbrake(self, maable, mtbrake):
        try:
            self.label_maable.setText(str(maable))
            self.label_mtbrake.setText(str(mtbrake))
            self.label_maable.setStyleSheet('''color: green;font:bold;''')
            self.label_mtbrake.setStyleSheet('''color: green;font:bold;''')
        except Exception as e:
            print(e)

    def update_cmd_count(self, cmdnum):
        try:
            self.label_cmd_count.setText(str(cmdnum))
            self.label_cmd_count.setStyleSheet('''color: green;font:bold;''')
        except Exception as e:
            print(e)

    def update_state(self, state):
        try:
            if state == 1:
                state_str = 'sport'
                self.label_state.setText(state_str)
                self.label_state.setStyleSheet('''color: green;font:bold;''')
            elif state == 2:
                state_str = 'sleep'
                self.label_state.setText(state_str)
                self.label_state.setStyleSheet('''color: gray;font:bold;''')
            elif state == 3:
                state_str = 'pause'
                self.label_state.setText(state_str)
                self.label_state.setStyleSheet('''color: orange;font:bold;''')
            elif state == 4:
                state_str = 'stop'
                self.label_state.setText(state_str)
                self.label_state.setStyleSheet('''color: red;font:bold;''')
        except Exception as e:
            print(e)
        # getattr(self, 'label_state').setText(state_str)
        # getattr(self, 'label_state').setText(str(state))
        if state != 1:
            self.reset_flag()

    def update_warn_error(self, item):
        try:
            warn, error = item
            self.label_warn_code.setText(str(warn))
            self.label_error_code.setText(str(error))
            if warn != 0:
                self.label_warn_code.setStyleSheet('''color: red;font:bold;''')
            else:
                self.label_warn_code.setStyleSheet(
                    '''color: green;font:bold;''')
            if error != 0:
                self.label_error_code.setStyleSheet(
                    '''color: red;font:bold;''')
            else:
                self.label_error_code.setStyleSheet(
                    '''color: green;font:bold;''')
        except Exception as e:
            print(e)

    def update_connect_status(self, item):
        try:
            img = QImage()
            if item[0]:
                logger.info('connect to {} success, report: {}'.format(
                    self.handler.addr, self.handler.report_type))
                if img.load(connect_icon_path):
                    self.label_connected.setPixmap(QPixmap.fromImage(img))
                    self.btn_connect.setText(i18n[self.lang]['Disconnect'])
                    self.btn_connect.setStyleSheet('''color: red;font:bold;''')
                self.set_disable(False)
            else:
                logger.info('disconnect from or failed connect {}'.format(
                    self.handler.addr))
                self.handler.cmd_que.queue.clear()
                if img.load(disconnect_icon_path):
                    self.label_connected.setPixmap(QPixmap.fromImage(img))
                    self.btn_connect.setText(i18n[self.lang]['Connect'])
                    self.btn_connect.setStyleSheet(
                        '''color: green;font:bold;''')
                self.set_disable(True)
            if item[1]:
                if img.load(connect_icon_path):
                    self.label_reported.setPixmap(QPixmap.fromImage(img))
            else:
                if img.load(disconnect_icon_path):
                    self.label_reported.setPixmap(QPixmap.fromImage(img))
        except Exception as e:
            print(e)

    def connect(self, event):
        try:
            if str(self.btn_connect.text()) == i18n[self.lang]['Connect']:
                addr = self.lnt_addr.text().strip()
                if addr == '192.168.1.':
                    addr = 'localhost'
                    report_type = 'normal'
                else:
                    tmp = addr.split(':')
                    addr = tmp[0]
                    report_type = tmp[1] if len(tmp) > 1 else 'normal'
                self.btn_connect.setText('Connecting')
                self.btn_connect.setStyleSheet('''color: orange;font:bold;''')
                self.handler.connect(addr, report_type=report_type)
                # if self.window.connect(addr, report_type=report_type):
                #     self.btn_connect.setText(self.disconnect_label)
                #     self.btn_connect.setStyleSheet('''color: red;font:bold;''')
            elif str(self.btn_connect.text()) == i18n[self.lang]['Disconnect']:
                self.handler.disconnect()
                self.btn_connect.setText(i18n[self.lang]['Connect'])
                self.btn_connect.setStyleSheet('''color: green;font:bold;''')
        except Exception as e:
            print(e)

    def stop(self, event):
        try:
            self.handler.cmd_que.queue.clear()
            if self.handler.xarm and self.handler.xarm.warn_code != 0:
                item = {
                    'cmd': 'clean_warn',
                }
                self.handler.put_cmd_que(item)
            if self.handler.xarm and self.handler.xarm.error_code != 0:
                item = {
                    'cmd': 'clean_error',
                }
                self.handler.put_cmd_que(item)
                item = {
                    'cmd': 'motion_enable',
                    'kwargs': {
                        'servo_id': 0,
                        'enable': True
                    }
                }
                self.handler.put_cmd_que(item)
            item = {
                'cmd': 'urgent_stop',
            }
            self.handler.put_cmd_que(item)
            self.reset_flag()
        except Exception as e:
            print(e)

    def clean(self, event):
        try:
            self.handler.cmd_que.queue.clear()
            if self.handler.xarm and self.handler.xarm.warn_code != 0:
                item = {
                    'cmd': 'clean_warn',
                }
                self.handler.put_cmd_que(item)
            if self.handler.xarm and self.handler.xarm.error_code != 0:
                item = {
                    'cmd': 'clean_error',
                }
                self.handler.put_cmd_que(item)
        except Exception as e:
            print(e)

    def reset(self, event):
        try:
            self.handler.cmd_que.queue.clear()
            if self.handler.xarm and self.handler.xarm.warn_code != 0:
                item = {
                    'cmd': 'clean_warn',
                }
                self.handler.put_cmd_que(item)
            if self.handler.xarm and self.handler.xarm.error_code != 0:
                item = {
                    'cmd': 'clean_error',
                }
                self.handler.put_cmd_que(item)
                item = {
                    'cmd': 'motion_enable',
                    'kwargs': {
                        'servo_id': 0,
                        'enable': True
                    }
                }
                self.handler.put_cmd_que(item)
                item = {'cmd': 'set_state', 'kwargs': {'state': 0}}
                self.handler.put_cmd_que(item)
            item = {
                'cmd': 'move_gohome',
                'kwargs': {
                    'speed': 30,
                    'mvacc': 5000,
                }
            }
            self.handler.put_cmd_que(item)
            self.reset_flag()
        except Exception as e:
            print(e)

    def get_servo_addr_16(self, event):
        try:
            addr = self.lnt_servo_addr.text().strip()
            try:
                if addr.lower().startswith('0x'):
                    addr = int(addr, base=16)
                else:
                    addr = int(addr)
            except:
                QMessageBox.warning(self.main_ui.window, '错误',
                                    '请输入正确的地址, 地址必须是u16类型')
                return
            text = self.combobox_servo.currentText()
            if text == 'axis-all':
                QMessageBox.warning(self.main_ui.window, '警告',
                                    '请选择其中一个电机,不能选择所有电机')
                return
            else:
                servo_id = int(text.split('-')[-1])
            tmp = '你确定要获取电机{}的地址{}的值吗?'.format(servo_id, addr)
            if QMessageBox.question(self.main_ui.window, '警告',
                                    tmp) == QMessageBox.Yes:
                item = {
                    'cmd': 'get_servo_addr_16',
                    'kwargs': {
                        'servo_id': servo_id,
                        'addr': addr
                    }
                }
                self.handler.put_cmd_que(item)
        except Exception as e:
            print(e)

    def get_servo_addr_32(self, event):
        try:
            addr = self.lnt_servo_addr.text().strip()
            try:
                if addr.lower().startswith('0x'):
                    addr = int(addr, base=16)
                else:
                    addr = int(addr)
            except:
                QMessageBox.warning(self.main_ui.window, '错误',
                                    '请输入正确的地址, 地址必须是u16类型')
                return
            text = self.combobox_servo.currentText()
            if text == 'axis-all':
                QMessageBox.warning(self.main_ui.window, '警告',
                                    '请选择其中一个电机,不能选择所有电机')
                return
            else:
                servo_id = int(text.split('-')[-1])
            tmp = '你确定要获取电机{}的地址{}的值吗?'.format(servo_id, addr)
            if QMessageBox.question(self.main_ui.window, '警告',
                                    tmp) == QMessageBox.Yes:
                item = {
                    'cmd': 'get_servo_addr_32',
                    'kwargs': {
                        'servo_id': servo_id,
                        'addr': addr
                    }
                }
                self.handler.put_cmd_que(item)
        except Exception as e:
            print(e)

    def set_servo_addr_16(self, event):
        try:
            addr = self.lnt_servo_addr.text().strip()
            try:
                if addr.lower().startswith('0x'):
                    addr = int(addr, base=16)
                else:
                    addr = int(addr)
            except:
                QMessageBox.warning(self.main_ui.window, '错误',
                                    '请输入正确的地址, 地址必须是u16类型')
                return
            value = self.lnt_servo_addr_value.text().strip()
            try:
                value = float(value)
            except:
                QMessageBox.warning(self.main_ui.window, '错误',
                                    '请输入正确的值, 值必须是float32类型')
                return
            text = self.combobox_servo.currentText()
            if text == 'axis-all':
                QMessageBox.warning(self.main_ui.window, '警告',
                                    '请选择其中一个电机,不能选择所有电机')
                return
            else:
                servo_id = int(text.split('-')[-1])
            tmp = '你确定要设置电机{}的地址{}的值为{}吗?'.format(servo_id, addr, value)
            if QMessageBox.question(self.main_ui.window, '警告',
                                    tmp) == QMessageBox.Yes:
                item = {
                    'cmd': 'set_servo_addr_16',
                    'kwargs': {
                        'servo_id': servo_id,
                        'addr': addr,
                        'value': value
                    }
                }
                self.handler.put_cmd_que(item)
        except Exception as e:
            print(e)

    def set_servo_addr_32(self, event):
        try:
            addr = self.lnt_servo_addr.text().strip()
            try:
                if addr.lower().startswith('0x'):
                    addr = int(addr, base=16)
                else:
                    addr = int(addr)
            except:
                QMessageBox.warning(self.main_ui.window, '错误',
                                    '请输入正确的地址, 地址必须是u16类型')
                return
            value = self.lnt_servo_addr_value.text().strip()
            try:
                value = float(value)
            except:
                QMessageBox.warning(self.main_ui.window, '错误',
                                    '请输入正确的值, 值必须是float32类型')
                return
            text = self.combobox_servo.currentText()
            if text == 'axis-all':
                QMessageBox.warning(self.main_ui.window, '警告',
                                    '请选择其中一个电机,不能选择所有电机')
                return
            else:
                servo_id = int(text.split('-')[-1])

            tmp = '你确定要设置电机{}的地址{}的值为{}吗?'.format(servo_id, addr, value)
            if QMessageBox.question(self.main_ui.window, '警告',
                                    tmp) == QMessageBox.Yes:
                item = {
                    'cmd': 'set_servo_addr_32',
                    'kwargs': {
                        'servo_id': servo_id,
                        'addr': addr,
                        'value': value
                    }
                }
                self.handler.put_cmd_que(item)
        except Exception as e:
            print(e)

    def set_servo_zero(self, event):
        try:
            text = self.combobox_servo.currentText()
            if text == 'axis-all':
                servo_id = 8
            else:
                servo_id = int(text.split('-')[-1])
            if servo_id == 8:
                tmp = '你确定要设置所有电机的零点吗?'
            else:
                tmp = '你确定要设置电机{}的零点吗?'.format(servo_id)
            if QMessageBox.question(self.main_ui.window, '警告',
                                    tmp) == QMessageBox.Yes:
                item = {
                    'cmd': 'set_servo_zero',
                    'kwargs': {
                        'servo_id': servo_id
                    }
                }
                self.handler.put_cmd_que(item)
        except Exception as e:
            print(e)

    def set_servo_attach(self, event):
        try:
            text = self.combobox_servo.currentText()
            if text == 'axis-all':
                servo_id = 8
            else:
                servo_id = int(text.split('-')[-1])

            item = {
                'cmd': 'set_servo_attach',
                'kwargs': {
                    'servo_id': servo_id
                }
            }
            self.handler.put_cmd_que(item)
            item = {
                'cmd': 'motion_enable',
                'kwargs': {
                    'servo_id': servo_id,
                    'enable': True
                }
            }
            self.handler.put_cmd_que(item)
            item = {'cmd': 'set_state', 'kwargs': {'state': 0}}
            self.handler.put_cmd_que(item)
        except Exception as e:
            print(e)

    def set_servo_detach(self, event):
        try:
            text = self.combobox_servo.currentText()
            if text == 'axis-all':
                servo_id = 8
            else:
                servo_id = int(text.split('-')[-1])

            if servo_id == 8:
                tmp = '你确定要解锁所有电机吗?'
            else:
                tmp = '你确定要解锁电机{}吗?'.format(servo_id)
            if QMessageBox.question(self.main_ui.window, '警告',
                                    tmp) == QMessageBox.Yes:
                item = {
                    'cmd': 'set_servo_detach',
                    'kwargs': {
                        'servo_id': servo_id
                    }
                }
                self.handler.put_cmd_que(item)
        except Exception as e:
            print(e)

    def motion_enable(self, event):
        self._motion_enable(True)

    def motion_disable(self, event):
        self._motion_enable(False)

    def _motion_enable(self, enable=True):
        try:
            text = self.combobox_servo.currentText()
            if text == 'axis-all':
                servo_id = 8
            else:
                servo_id = int(text.split('-')[-1])
            item = {
                'cmd': 'motion_enable',
                'kwargs': {
                    'servo_id': servo_id,
                    'enable': enable
                }
            }
            self.handler.put_cmd_que(item)
        except Exception as e:
            print(e)

    def set_state(self, event):
        try:
            text = self.combobox_state.currentText()
            if text == 'sport':
                state = 0
            elif text == 'pause':
                state = 3
            elif text == 'stop':
                state = 4
            else:
                return
            if state in [0, 3, 4]:
                item = {'cmd': 'set_state', 'kwargs': {'state': state}}
                self.handler.put_cmd_que(item)
        except Exception as e:
            print(e)

    def set_disable(self, disable):
        try:
            self.btn_stop.setDisabled(disable)
            self.btn_clean.setDisabled(disable)
            self.btn_reset.setDisabled(disable)
            self.btn_get_servo_dbmsg.setDisabled(disable)
            self.combobox_servo.setDisabled(disable)
            self.combobox_state.setDisabled(disable)
            self.btn_motion_enable.setDisabled(disable)
            self.btn_motion_disable.setDisabled(disable)
            self.btn_servo_attach.setDisabled(disable)
            self.btn_servo_detach.setDisabled(disable)
            self.btn_set_state.setDisabled(disable)
            self.lnt_servo_addr.setDisabled(disable)
            self.lnt_servo_addr_value.setDisabled(disable)
            self.btn_get_servo_addr16.setDisabled(disable)
            self.btn_set_servo_addr16.setDisabled(disable)
            self.btn_get_servo_addr32.setDisabled(disable)
            self.btn_set_servo_addr32.setDisabled(disable)
            self.btn_set_servo_zero.setDisabled(disable)

            self.slider_speed.setDisabled(disable)
            self.spinbox_speed.setDisabled(disable)
            self.slider_acc.setDisabled(disable)
            self.spinbox_acc.setDisabled(disable)

            self.axis_ui.set_disable(disable)
            self.cartesian_ui.set_disable(disable)
        except Exception as e:
            print(e)
Ejemplo n.º 49
0
class CreateVirtualLibrary(QDialog):  # {{{
    def __init__(self, gui, existing_names, editing=None):
        QDialog.__init__(self, gui)

        self.gui = gui
        self.existing_names = existing_names

        if editing:
            self.setWindowTitle(_('Edit virtual library'))
        else:
            self.setWindowTitle(_('Create virtual library'))
        self.setWindowIcon(QIcon(I('lt.png')))

        gl = QGridLayout()
        self.setLayout(gl)
        self.la1 = la1 = QLabel(_('Virtual library &name:'))
        gl.addWidget(la1, 0, 0)
        self.vl_name = QComboBox()
        self.vl_name.setEditable(True)
        self.vl_name.lineEdit().setMaxLength(MAX_VIRTUAL_LIBRARY_NAME_LENGTH)
        la1.setBuddy(self.vl_name)
        gl.addWidget(self.vl_name, 0, 1)
        self.editing = editing

        self.saved_searches_label = sl = QTextBrowser(self)
        sl.viewport().setAutoFillBackground(False)
        gl.addWidget(sl, 2, 0, 1, 2)

        self.la2 = la2 = QLabel(_('&Search expression:'))
        gl.addWidget(la2, 1, 0)
        self.vl_text = QLineEdit()
        self.vl_text.textChanged.connect(self.search_text_changed)
        la2.setBuddy(self.vl_text)
        gl.addWidget(self.vl_text, 1, 1)
        self.vl_text.setText(_build_full_search_string(self.gui))

        self.sl = sl = QLabel(
            '<p>' + _('Create a virtual library based on: ') +
            ('<a href="author.{0}">{0}</a>, '
             '<a href="tag.{1}">{1}</a>, '
             '<a href="publisher.{2}">{2}</a>, '
             '<a href="series.{3}">{3}</a>, '
             '<a href="search.{4}">{4}</a>.').format(_('Authors'), _(
                 'Tags'), _('Publishers'), _('Series'), _('Saved searches')))
        sl.setWordWrap(True)
        sl.setTextInteractionFlags(Qt.LinksAccessibleByMouse)
        sl.linkActivated.connect(self.link_activated)
        gl.addWidget(sl, 3, 0, 1, 2)
        gl.setRowStretch(3, 10)

        self.hl = hl = QLabel(
            _('''
            <h2>Virtual libraries</h2>

            <p>Using <i>virtual libraries</i> you can restrict calibre to only show
            you books that match a search. When a virtual library is in effect, calibre
            behaves as though the library contains only the matched books. The Tag browser
            display only the tags/authors/series/etc. that belong to the matched books and any searches
            you do will only search within the books in the virtual library. This
            is a good way to partition your large library into smaller and easier to work with subsets.</p>

            <p>For example you can use a Virtual library to only show you books with the Tag <i>"Unread"</i>
            or only books by <i>"My favorite author"</i> or only books in a particular series.</p>

            <p>More information and examples are available in the
            <a href="%s">User Manual</a>.</p>
            ''') % localize_user_manual_link(
                'https://manual.calibre-ebook.com/virtual_libraries.html'))
        hl.setWordWrap(True)
        hl.setOpenExternalLinks(True)
        hl.setFrameStyle(hl.StyledPanel)
        gl.addWidget(hl, 0, 3, 4, 1)

        bb = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
        bb.accepted.connect(self.accept)
        bb.rejected.connect(self.reject)
        gl.addWidget(bb, 4, 0, 1, 0)

        if editing:
            db = self.gui.current_db
            virt_libs = db.prefs.get('virtual_libraries', {})
            for dex, vl in enumerate(
                    sorted(list(virt_libs.keys()), key=sort_key)):
                self.vl_name.addItem(vl, virt_libs.get(vl, ''))
                if vl == editing:
                    self.vl_name.setCurrentIndex(dex)
                    self.original_index = dex
            self.original_search = virt_libs.get(editing, '')
            self.vl_text.setText(self.original_search)
            self.new_name = editing
            self.vl_name.currentIndexChanged[int].connect(
                self.name_index_changed)
            self.vl_name.lineEdit().textEdited.connect(self.name_text_edited)

        self.resize(self.sizeHint() + QSize(150, 25))

    def search_text_changed(self, txt):
        db = self.gui.current_db
        searches = [_('Saved searches recognized in the expression:')]
        txt = str(txt)
        while txt:
            p = txt.partition('search:')
            if p[1]:  # found 'search:'
                possible_search = p[2]
                if possible_search:  # something follows the 'search:'
                    if possible_search[0] == '"':  # strip any quotes
                        possible_search = possible_search[1:].partition('"')
                    else:  # find end of the search name. Is EOL, space, rparen
                        sp = possible_search.find(' ')
                        pp = possible_search.find(')')
                        if pp < 0 or (sp > 0 and sp <= pp):
                            # space in string before rparen, or neither found
                            possible_search = possible_search.partition(' ')
                        else:
                            # rparen in string before space
                            possible_search = possible_search.partition(')')
                    txt = possible_search[2]  # grab remainder of the string
                    search_name = possible_search[0]
                    if search_name.startswith('='):
                        search_name = search_name[1:]
                    if search_name in db.saved_search_names():
                        searches.append(search_name + '=' +
                                        db.saved_search_lookup(search_name))
                else:
                    txt = ''
            else:
                txt = ''
        if len(searches) > 1:
            self.saved_searches_label.setPlainText('\n'.join(searches))
        else:
            self.saved_searches_label.setPlainText('')

    def name_text_edited(self, new_name):
        self.new_name = str(new_name)

    def name_index_changed(self, dex):
        if self.editing and (self.vl_text.text() != self.original_search
                             or self.new_name != self.editing):
            if not question_dialog(
                    self.gui,
                    _('Search text changed'),
                    _('The virtual library name or the search text has changed. '
                      'Do you want to discard these changes?'),
                    default_yes=False):
                self.vl_name.blockSignals(True)
                self.vl_name.setCurrentIndex(self.original_index)
                self.vl_name.lineEdit().setText(self.new_name)
                self.vl_name.blockSignals(False)
                return
        self.new_name = self.editing = self.vl_name.currentText()
        self.original_index = dex
        self.original_search = str(self.vl_name.itemData(dex) or '')
        self.vl_text.setText(self.original_search)

    def link_activated(self, url):
        db = self.gui.current_db
        f, txt = str(url).partition('.')[0::2]
        if f == 'search':
            names = db.saved_search_names()
        else:
            names = getattr(db, 'all_%s_names' % f)()
        d = SelectNames(names, txt, parent=self)
        if d.exec_() == d.Accepted:
            prefix = f + 's' if f in {'tag', 'author'} else f
            if f == 'search':
                search = [
                    '(%s)' % (db.saved_search_lookup(x)) for x in d.names
                ]
            else:
                search = [
                    '%s:"=%s"' % (prefix, x.replace('"', '\\"'))
                    for x in d.names
                ]
            if search:
                if not self.editing:
                    self.vl_name.lineEdit().setText(next(d.names))
                    self.vl_name.lineEdit().setCursorPosition(0)
                self.vl_text.setText(d.match_type.join(search))
                self.vl_text.setCursorPosition(0)

    def accept(self):
        n = str(self.vl_name.currentText()).strip()
        if not n:
            error_dialog(
                self.gui,
                _('No name'),
                _('You must provide a name for the new virtual library'),
                show=True)
            return

        if n.startswith('*'):
            error_dialog(self.gui,
                         _('Invalid name'),
                         _('A virtual library name cannot begin with "*"'),
                         show=True)
            return

        if n in self.existing_names and n != self.editing:
            if not question_dialog(
                    self.gui,
                    _('Name already in use'),
                    _('That name is already in use. Do you want to replace it '
                      'with the new search?'),
                    default_yes=False):
                return

        v = str(self.vl_text.text()).strip()
        if not v:
            error_dialog(
                self.gui,
                _('No search string'),
                _('You must provide a search to define the new virtual library'
                  ),
                show=True)
            return

        try:
            db = self.gui.library_view.model().db
            recs = db.data.search_getting_ids('',
                                              v,
                                              use_virtual_library=False,
                                              sort_results=False)
        except ParseException as e:
            error_dialog(self.gui,
                         _('Invalid search'),
                         _('The search in the search box is not valid'),
                         det_msg=e.msg,
                         show=True)
            return

        if not recs and not question_dialog(
                self.gui,
                _('Search found no books'),
                _('The search found no books, so the virtual library '
                  'will be empty. Do you really want to use that search?'),
                default_yes=False):
            return

        self.library_name = n
        self.library_search = v
        QDialog.accept(self)
Ejemplo n.º 50
0
 def __init__(self, *args):
     QComboBox.__init__(self, *args)
     self.setLineEdit(EnLineEdit(self))
     self.completer().setCaseSensitivity(Qt.CaseInsensitive)
     self.setMinimumContentsLength(20)
Ejemplo n.º 51
0
 def __init__(self, parent, custom_columns={}, selected_column=''):
     QComboBox.__init__(self, parent)
     self.populate_combo(custom_columns, selected_column)
Ejemplo n.º 52
0
 def focusOutEvent(self, e):
     QComboBox.focusOutEvent(self, e)
     if not (self.hasFocus() or self.view().hasFocus()):
         self.lost_focus.emit()
    def __init__(self, extra_customization_message,
                 extra_customization_choices, device_settings):
        super(ExtraCustomization, self).__init__()

        debug_print(
            "ExtraCustomization.__init__ - extra_customization_message=",
            extra_customization_message)
        debug_print(
            "ExtraCustomization.__init__ - extra_customization_choices=",
            extra_customization_choices)
        debug_print(
            "ExtraCustomization.__init__ - device_settings.extra_customization=",
            device_settings.extra_customization)
        debug_print("ExtraCustomization.__init__ - device_settings=",
                    device_settings)
        self.extra_customization_message = extra_customization_message

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

        options_group = QGroupBox(_("Extra driver customization options"),
                                  self)
        self.l.addWidget(options_group)
        self.extra_layout = QGridLayout()
        self.extra_layout.setObjectName("extra_layout")
        options_group.setLayout(self.extra_layout)

        if extra_customization_message:
            extra_customization_choices = extra_customization_choices or {}

            def parse_msg(m):
                msg, _, tt = m.partition(':::') if m else ('', '', '')
                return msg.strip(), textwrap.fill(tt.strip(), 100)

            if isinstance(extra_customization_message, list):
                self.opt_extra_customization = []
                if len(extra_customization_message) > 6:
                    row_func = lambda x, y: ((x / 2) * 2) + y
                    col_func = lambda x: x % 2
                else:
                    row_func = lambda x, y: x * 2 + y
                    col_func = lambda x: 0

                for i, m in enumerate(extra_customization_message):
                    label_text, tt = parse_msg(m)
                    if not label_text:
                        self.opt_extra_customization.append(None)
                        continue
                    if isinstance(device_settings.extra_customization[i],
                                  bool):
                        self.opt_extra_customization.append(
                            QCheckBox(label_text))
                        self.opt_extra_customization[-1].setToolTip(tt)
                        self.opt_extra_customization[i].setChecked(
                            bool(device_settings.extra_customization[i]))
                    elif i in extra_customization_choices:
                        cb = QComboBox(self)
                        self.opt_extra_customization.append(cb)
                        l = QLabel(label_text)
                        l.setToolTip(tt), cb.setToolTip(tt), l.setBuddy(
                            cb), cb.setToolTip(tt)
                        for li in sorted(extra_customization_choices[i]):
                            self.opt_extra_customization[i].addItem(li)
                        cb.setCurrentIndex(
                            max(
                                0,
                                cb.findText(
                                    device_settings.extra_customization[i])))
                    else:
                        self.opt_extra_customization.append(QLineEdit(self))
                        l = QLabel(label_text)
                        l.setToolTip(tt)
                        self.opt_extra_customization[i].setToolTip(tt)
                        l.setBuddy(self.opt_extra_customization[i])
                        l.setWordWrap(True)
                        self.opt_extra_customization[i].setText(
                            device_settings.extra_customization[i])
                        self.opt_extra_customization[i].setCursorPosition(0)
                        self.extra_layout.addWidget(l, row_func(i + 2, 0),
                                                    col_func(i))
                    self.extra_layout.addWidget(
                        self.opt_extra_customization[i], row_func(i + 2, 1),
                        col_func(i))
                spacerItem1 = QSpacerItem(10, 10, QSizePolicy.Minimum,
                                          QSizePolicy.Expanding)
                self.extra_layout.addItem(spacerItem1, row_func(i + 2 + 2, 1),
                                          0, 1, 2)
                self.extra_layout.setRowStretch(row_func(i + 2 + 2, 1), 2)
            else:
                self.opt_extra_customization = QLineEdit()
                label_text, tt = parse_msg(extra_customization_message)
                l = QLabel(label_text)
                l.setToolTip(tt)
                l.setBuddy(self.opt_extra_customization)
                l.setWordWrap(True)
                if device_settings.extra_customization:
                    self.opt_extra_customization.setText(
                        device_settings.extra_customization)
                    self.opt_extra_customization.setCursorPosition(0)
                self.opt_extra_customization.setCursorPosition(0)
                self.extra_layout.addWidget(l, 0, 0)
                self.extra_layout.addWidget(self.opt_extra_customization, 1, 0)
Ejemplo n.º 54
0
 def __init__(self, parent=None):
     QComboBox.__init__(self, parent)
     self.currentIndexChanged[int].connect(self.index_changed)
     self.help_text = ''
     self.state_set = False
Ejemplo n.º 55
0
 def __init__(self, parent, values, selected_key):
     QComboBox.__init__(self, parent)
     self.values = values
     self.populate_combo(selected_key)
Ejemplo n.º 56
0
 def currentText(self):
     if self.currentIndex() == 0:
         return ''
     return QComboBox.currentText(self)
Ejemplo n.º 57
0
    def initialize(self):
        def field_cmp(x, y):
            if x.startswith('#'):
                if y.startswith('#'):
                    return cmp(x.lower(), y.lower())
                else:
                    return 1
            elif y.startswith('#'):
                return -1
            else:
                return cmp(x.lower(), y.lower())

        ConfigWidgetBase.initialize(self)

        self.current_plugboards = copy.deepcopy(
            self.db.prefs.get('plugboards', {}))
        self.current_device = None
        self.current_format = None

        if self.gui.device_manager.connected_device is not None:
            self.device_label.setText(
                _('Device currently connected: ') +
                self.gui.device_manager.connected_device.__class__.__name__)
        else:
            self.device_label.setText(_('Device currently connected: None'))

        self.devices = ['', 'APPLE', 'FOLDER_DEVICE']
        self.device_to_formats_map = {}
        for device in device_plugins():
            n = device_name_for_plugboards(device)
            self.device_to_formats_map[n] = set(device.settings().format_map)
            if getattr(device, 'CAN_DO_DEVICE_DB_PLUGBOARD', False):
                self.device_to_formats_map[n].add('device_db')
            if n not in self.devices:
                self.devices.append(n)
        self.devices.sort(cmp=lambda x, y: cmp(x.lower(), y.lower()))
        self.devices.insert(1, plugboard_save_to_disk_value)
        self.devices.insert(1, plugboard_content_server_value)
        self.device_to_formats_map[plugboard_content_server_value] = \
                        plugboard_content_server_formats
        self.devices.insert(1, plugboard_email_value)
        self.device_to_formats_map[plugboard_email_value] = \
                        plugboard_email_formats
        self.devices.insert(1, plugboard_any_device_value)
        self.new_device.addItems(self.devices)

        self.formats = ['']
        for w in metadata_writers():
            if not is_disabled(w):
                for f in w.file_types:
                    if not f in self.formats:
                        self.formats.append(f)
        self.formats.append('device_db')
        self.formats.sort()
        self.formats.insert(1, plugboard_any_format_value)
        self.new_format.addItems(self.formats)

        self.dest_fields = [
            '', 'authors', 'author_sort', 'language', 'publisher', 'tags',
            'title', 'title_sort'
        ]

        self.source_widgets = []
        self.dest_widgets = []
        for i in range(0, len(self.dest_fields) - 1):
            w = TemplateLineEditor(self)
            self.source_widgets.append(w)
            self.fields_layout.addWidget(w, 5 + i, 0, 1, 1)
            w = QComboBox(self)
            self.dest_widgets.append(w)
            self.fields_layout.addWidget(w, 5 + i, 1, 1, 1)

        self.edit_device.currentIndexChanged[str].connect(
            self.edit_device_changed)
        self.edit_format.currentIndexChanged[str].connect(
            self.edit_format_changed)
        self.new_device.currentIndexChanged[str].connect(
            self.new_device_changed)
        self.new_format.currentIndexChanged[str].connect(
            self.new_format_changed)
        self.existing_plugboards.itemClicked.connect(self.existing_pb_clicked)
        self.ok_button.clicked.connect(self.ok_clicked)
        self.del_button.clicked.connect(self.del_clicked)

        self.refilling = False
        self.refill_all_boxes()
Ejemplo n.º 58
0
 def itemText(self, idx):
     if idx == 0:
         return ''
     return QComboBox.itemText(self, idx)
Ejemplo n.º 59
0
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        self.l = l = QVBoxLayout(self)
        self.h = h = QHBoxLayout()

        self.la = la = QLabel(self.MSG)
        la.setWordWrap(True)
        l.addWidget(la)
        l.addLayout(h)
        english_sentence = '{preamble} {property} {match_type} {query}'
        sentence = _('{preamble} {property} {match_type} {query}')
        if set(sentence.split()) != set(english_sentence.split()):
            sentence = english_sentence
        parts = sentence.split()
        for clause in parts:
            if clause == '{preamble}':
                self.preamble = w = QLabel(_('If the &property:'))
            elif clause == '{property}':
                self.property = w = QLineEdit(self)
                w.setToolTip(_('The name of a CSS property, for example: font-size\n'
                               'Do not use shorthand properties, they will not work.\n'
                               'For instance use margin-top, not margin.'))
            elif clause == '{match_type}':
                self.match_type = w = QComboBox(self)
                for action, text in iteritems(MATCH_TYPE_MAP):
                    w.addItem(text, action)
                w.currentIndexChanged.connect(self.update_state)
            elif clause == '{query}':
                self.query = w = QLineEdit(self)
            h.addWidget(w)
            if clause is not parts[-1]:
                h.addWidget(QLabel('\xa0'))
        self.preamble.setBuddy(self.property)

        self.h2 = h = QHBoxLayout()
        l.addLayout(h)
        english_sentence = '{action} {action_data}'
        sentence = _('{action} {action_data}')
        if set(sentence.split()) != set(english_sentence.split()):
            sentence = english_sentence
        parts = sentence.split()
        for clause in parts:
            if clause == '{action}':
                self.action = w = QComboBox(self)
                for action, text in iteritems(ACTION_MAP):
                    w.addItem(text, action)
                w.currentIndexChanged.connect(self.update_state)
            elif clause == '{action_data}':
                self.action_data = w = QLineEdit(self)
            h.addWidget(w)
            if clause is not parts[-1]:
                h.addWidget(QLabel('\xa0'))

        self.regex_help = la = QLabel('<p>' + RE.REGEXP_HELP_TEXT % localize_user_manual_link(
        'https://manual.calibre-ebook.com/regexp.html'))
        la.setOpenExternalLinks(True)
        la.setWordWrap(True)
        l.addWidget(la)
        l.addStretch(10)

        self.update_state()
Ejemplo n.º 60
0
 def __init__(self, *args):
     QComboBox.__init__(self, *args)
     self.setEditable(True)
     self.setInsertPolicy(self.NoInsert)
     self.setMaxCount(10)
     self.setClearButtonEnabled = self.lineEdit().setClearButtonEnabled