예제 #1
0
 def __init__(self,
              completer_widget,
              max_visible_items=7,
              sort_func=sort_key,
              strip_completion_entries=True):
     QListView.__init__(self, completer_widget)
     self.disable_popup = False
     self.setWindowFlags(Qt.WindowType.Popup)
     self.max_visible_items = max_visible_items
     self.setEditTriggers(QAbstractItemView.EditTrigger.NoEditTriggers)
     self.setHorizontalScrollBarPolicy(
         Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
     self.setSelectionBehavior(
         QAbstractItemView.SelectionBehavior.SelectRows)
     self.setSelectionMode(QAbstractItemView.SelectionMode.SingleSelection)
     self.setUniformItemSizes(True)
     self.setAlternatingRowColors(True)
     self.setModel(
         CompleteModel(self,
                       sort_func=sort_func,
                       strip_completion_entries=strip_completion_entries))
     self.setMouseTracking(True)
     self.activated.connect(self.item_chosen)
     self.pressed.connect(self.item_chosen)
     self.installEventFilter(self)
     self.setFocusPolicy(Qt.FocusPolicy.NoFocus)
예제 #2
0
 def __init__(self, parent=None):
     QListView.__init__(self, parent)
     self.setSizePolicy(QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Expanding)
     self.setAlternatingRowColors(True)
     self.setSpacing(5)
     self.setVerticalScrollMode(QAbstractItemView.ScrollMode.ScrollPerPixel)
     self.setMinimumWidth(300)
예제 #3
0
 def __init__(self, parent=None):
     QListView.__init__(self, parent)
     self.setSizePolicy(QSizePolicy.Policy.MinimumExpanding,
                        QSizePolicy.Policy.Expanding)
     f = self.font()
     f.setBold(True)
     self.setFont(f)
     self.setIconSize(QSize(48, 48))
     self.setFlow(QListView.Flow.TopToBottom)
     self.setSpacing(10)
예제 #4
0
파일: tweaks.py 프로젝트: cbhaley/calibre
 def __init__(self, parent=None):
     QListView.__init__(self, parent)
     self.setSizePolicy(QSizePolicy.Policy.Minimum,
                        QSizePolicy.Policy.Expanding)
     self.setAlternatingRowColors(True)
     self.setVerticalScrollMode(QAbstractItemView.ScrollMode.ScrollPerPixel)
     self.setMinimumWidth(300)
     self.setStyleSheet(
         'QListView::item { padding-top: 0.75ex; padding-bottom: 0.75ex; }')
     self.setWordWrap(True)
예제 #5
0
 def __init__(self, model, parent=None):
     QWidget.__init__(self, parent)
     self._layout = QHBoxLayout()
     self.setLayout(self._layout)
     self.view = QListView(self)
     self._layout.addWidget(self.view)
     self.view.setModel(model)
     self.delegate = Delegate()
     self.view.setItemDelegate(self.delegate)
     self.delegate.sizeHintChanged.connect(
         self.scrollTo, type=Qt.ConnectionType.QueuedConnection)
class SelectNames(QDialog):  # {{{
    def __init__(self, names, txt, parent=None):
        QDialog.__init__(self, parent)
        self.l = l = QVBoxLayout(self)
        self.setLayout(l)

        self.la = la = QLabel(_('Create a Virtual library based on %s') % txt)
        l.addWidget(la)

        self.filter = f = QLineEdit(self)
        f.setPlaceholderText(_('Filter {}').format(txt))
        f.setClearButtonEnabled(True)
        l.addWidget(f)

        self.model = QStringListModel(sorted(names, key=sort_key))
        self.pmodel = QSortFilterProxyModel(self)
        self.pmodel.setFilterCaseSensitivity(
            Qt.CaseSensitivity.CaseInsensitive)
        f.textChanged.connect(self.pmodel.setFilterFixedString)
        self.pmodel.setSourceModel(self.model)
        self._names = QListView(self)
        self._names.setModel(self.pmodel)
        self._names.setSelectionMode(
            QAbstractItemView.SelectionMode.MultiSelection)
        l.addWidget(self._names)

        self._or = QRadioButton(_('Match any of the selected %s') % txt)
        self._and = QRadioButton(_('Match all of the selected %s') % txt)
        self._or.setChecked(True)
        l.addWidget(self._or)
        l.addWidget(self._and)

        self.bb = QDialogButtonBox(QDialogButtonBox.StandardButton.Ok
                                   | QDialogButtonBox.StandardButton.Cancel)
        self.bb.accepted.connect(self.accept)
        self.bb.rejected.connect(self.reject)
        l.addWidget(self.bb)

        self.resize(self.sizeHint())

    @property
    def names(self):
        for index in self._names.selectedIndexes():
            yield index.data(Qt.ItemDataRole.DisplayRole) or ''

    @property
    def match_type(self):
        return ' and ' if self._and.isChecked() else ' or '
예제 #7
0
 def mouseMoveEvent(self, ev):
     idx = self.indexAt(ev.pos())
     if idx.isValid():
         ci = self.currentIndex()
         if idx.row() != ci.row():
             self.setCurrentIndex(idx)
     return QListView.mouseMoveEvent(self, ev)
예제 #8
0
 def handle_mouse_press_event(self, ev):
     if QApplication.keyboardModifiers(
     ) & Qt.KeyboardModifier.ShiftModifier:
         # Shift-Click in QListView is broken. It selects extra items in
         # various circumstances, for example, click on some item in the
         # middle of a row then click on an item in the next row, all items
         # in the first row will be selected instead of only items after the
         # middle item.
         index = self.indexAt(ev.pos())
         if not index.isValid():
             return
         ci = self.currentIndex()
         sm = self.selectionModel()
         sm.setCurrentIndex(index,
                            QItemSelectionModel.SelectionFlag.NoUpdate)
         if not ci.isValid():
             return
         if not sm.hasSelection():
             sm.select(index,
                       QItemSelectionModel.SelectionFlag.ClearAndSelect)
             return
         cr = ci.row()
         tgt = index.row()
         top = self.model().index(min(cr, tgt), 0)
         bottom = self.model().index(max(cr, tgt), 0)
         sm.select(QItemSelection(top, bottom),
                   QItemSelectionModel.SelectionFlag.Select)
     else:
         return QListView.mousePressEvent(self, ev)
예제 #9
0
    def __init__(self, model, parent=None):
        QWidget.__init__(self, parent)
        self.l = l = QGridLayout(self)
        self.setLayout(l)
        self.setContentsMargins(0, 0, 0, 0)

        self.view = v = QListView(self)
        self.d = SpacedDelegate(v)
        v.doubleClicked.connect(self.double_clicked)
        v.setItemDelegate(self.d)
        v.setModel(model)
        l.addWidget(v, 0, 0, 1, -1)
        model.dataChanged.connect(self.data_changed)

        self.rb = b = QPushButton(QIcon(I('edit-undo.png')), _('&Revert to'),
                                  self)
        b.setToolTip(_('Revert the book to the selected checkpoint'))
        b.clicked.connect(self.revert_clicked)
        l.addWidget(b, 1, 1)

        self.cb = b = QPushButton(QIcon(I('diff.png')), _('&Compare'), self)
        b.setToolTip(
            _('Compare the state of the book at the selected checkpoint with the current state'
              ))
        b.clicked.connect(self.compare_clicked)
        l.addWidget(b, 1, 0)
예제 #10
0
 def keyPressEvent(self, ev):
     if handle_enter_press(self, ev, self.start_view_animation, False):
         return
     k = ev.key()
     if ev.modifiers() & Qt.KeyboardModifier.ShiftModifier and k in (Qt.Key.Key_Left, Qt.Key.Key_Right, Qt.Key.Key_Up, Qt.Key.Key_Down):
         ci = self.currentIndex()
         if not ci.isValid():
             return
         c = ci.row()
         ncols = self.number_of_columns() or 1
         delta = {Qt.Key.Key_Left: -1, Qt.Key.Key_Right: 1, Qt.Key.Key_Up: -ncols, Qt.Key.Key_Down: ncols}[k]
         n = max(0, min(c + delta, self.model().rowCount(None) - 1))
         if n == c:
             return
         sm = self.selectionModel()
         rows = {i.row() for i in sm.selectedIndexes()}
         if rows:
             mi, ma = min(rows), max(rows)
             end = mi if c == ma else ma if c == mi else c
         else:
             end = c
         top = self.model().index(min(n, end), 0)
         bottom = self.model().index(max(n, end), 0)
         sm.select(QItemSelection(top, bottom), QItemSelectionModel.SelectionFlag.ClearAndSelect)
         sm.setCurrentIndex(self.model().index(n, 0), QItemSelectionModel.SelectionFlag.NoUpdate)
     else:
         return QListView.keyPressEvent(self, ev)
예제 #11
0
 def viewportEvent(self, ev):
     try:
         ret = self.gesture_manager.handle_event(ev)
     except AttributeError:
         ret = None
     if ret is not None:
         return ret
     return QListView.viewportEvent(self, ev)
예제 #12
0
 def moveCursor(self, action, modifiers):
     index = QListView.moveCursor(self, action, modifiers)
     if action in (QAbstractItemView.CursorAction.MoveLeft, QAbstractItemView.CursorAction.MoveRight) and index.isValid():
         ci = self.currentIndex()
         if ci.isValid() and index.row() == ci.row():
             nr = index.row() + (1 if action == QAbstractItemView.CursorAction.MoveRight else -1)
             if 0 <= nr < self.model().rowCount(QModelIndex()):
                 index = self.model().index(nr, 0)
     return index
예제 #13
0
    def __init__(self, parent, model):
        QWidget.__init__(self, parent)

        self.l = l = QHBoxLayout(self)

        self.view = v = QListView(self)
        v.doubleClicked.connect(self.item_activated)
        v.setModel(CustomRecipeModel(model))
        l.addWidget(v)

        self.stacks = s = QStackedWidget(self)
        l.addWidget(s, stretch=10, alignment=Qt.AlignmentFlag.AlignTop)

        self.first_msg = la = QLabel(
            _('Create a new news source by clicking one of the buttons below'))
        la.setWordWrap(True)
        s.addWidget(la)

        self.w = w = QWidget(self)
        w.l = l = QVBoxLayout(w)
        l.setContentsMargins(0, 0, 0, 0)
        s.addWidget(w)

        self.title = la = QLabel(w)
        la.setAlignment(Qt.AlignmentFlag.AlignHCenter
                        | Qt.AlignmentFlag.AlignTop)
        l.addWidget(la)
        l.setSpacing(20)

        self.edit_button = b = QPushButton(QIcon(I('modified.png')),
                                           _('&Edit this recipe'), w)
        b.setSizePolicy(
            QSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed))
        b.clicked.connect(self.edit_requested)
        l.addWidget(b)
        self.remove_button = b = QPushButton(QIcon(I('list_remove.png')),
                                             _('&Remove this recipe'), w)
        b.clicked.connect(self.remove)
        b.setSizePolicy(
            QSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed))
        l.addWidget(b)
        self.export_button = b = QPushButton(QIcon(I('save.png')),
                                             _('S&ave recipe as file'), w)
        b.setSizePolicy(
            QSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed))
        b.clicked.connect(self.save_recipe)
        l.addWidget(b)
        self.download_button = b = QPushButton(
            QIcon(I('download-metadata.png')), _('&Download this recipe'), w)
        b.clicked.connect(self.download)
        b.setSizePolicy(
            QSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed))
        l.addWidget(b)

        self.select_row()
        v.selectionModel().currentRowChanged.connect(self.recipe_selected)
예제 #14
0
 def __init__(self, parent=None):
     self.last_mouse_idx = -1
     QListView.__init__(self, parent)
     self._model = CharModel(self)
     self.setModel(self._model)
     self.delegate = CharDelegate(self)
     self.setResizeMode(QListView.ResizeMode.Adjust)
     self.setItemDelegate(self.delegate)
     self.setFlow(QListView.Flow.LeftToRight)
     self.setWrapping(True)
     self.setMouseTracking(True)
     self.setSpacing(2)
     self.setUniformItemSizes(True)
     self.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
     self.customContextMenuRequested.connect(self.context_menu)
     self.showing_favorites = False
     set_no_activate_on_click(self)
     self.activated.connect(self.item_activated)
     self.clicked.connect(self.item_activated)
예제 #15
0
def create_filterable_names_list(names, filter_text=None, parent=None, model=NamesModel):
    nl = QListView(parent)
    nl.m = m = model(names, parent=nl)
    connect_lambda(m.filtered, nl, lambda nl, all_items: nl.scrollTo(m.index(0)))
    nl.setModel(m)
    if model is NamesModel:
        nl.d = NamesDelegate(nl)
        nl.setItemDelegate(nl.d)
    f = QLineEdit(parent)
    f.setPlaceholderText(filter_text or '')
    f.textEdited.connect(m.filter)
    return nl, f
예제 #16
0
 def __init__(self, parent):
     QListView.__init__(self, parent)
     self._ncols = None
     self.gesture_manager = GestureManager(self)
     setup_dnd_interface(self)
     self.setUniformItemSizes(True)
     self.setWrapping(True)
     self.setFlow(QListView.Flow.LeftToRight)
     # We cannot set layout mode to batched, because that breaks
     # restore_vpos()
     # self.setLayoutMode(QListView.ResizeMode.Batched)
     self.setResizeMode(QListView.ResizeMode.Adjust)
     self.setSelectionMode(
         QAbstractItemView.SelectionMode.ExtendedSelection)
     self.setVerticalScrollMode(QAbstractItemView.ScrollMode.ScrollPerPixel)
     self.delegate = CoverDelegate(self)
     self.delegate.animation.valueChanged.connect(
         self.animation_value_changed)
     self.delegate.animation.finished.connect(self.animation_done)
     self.setItemDelegate(self.delegate)
     self.setSpacing(self.delegate.spacing)
     self.set_color()
     self.ignore_render_requests = Event()
     dpr = self.device_pixel_ratio
     self.thumbnail_cache = ThumbnailCache(
         max_size=gprefs['cover_grid_disk_cache_size'],
         thumbnail_size=(int(dpr * self.delegate.cover_size.width()),
                         int(dpr * self.delegate.cover_size.height())))
     self.render_thread = None
     self.update_item.connect(self.re_render,
                              type=Qt.ConnectionType.QueuedConnection)
     self.doubleClicked.connect(self.double_clicked)
     self.setCursor(Qt.CursorShape.PointingHandCursor)
     self.gui = parent
     self.context_menu = None
     self.update_timer = QTimer(self)
     self.update_timer.setInterval(200)
     self.update_timer.timeout.connect(self.update_viewport)
     self.update_timer.setSingleShot(True)
     self.resize_timer = t = QTimer(self)
     t.setInterval(200), t.setSingleShot(True)
     t.timeout.connect(self.update_memory_cover_cache_size)
예제 #17
0
    def __init__(self, current_cover, parent=None):
        QListView.__init__(self, parent)
        self.m = CoversModel(current_cover, self)
        self.setModel(self.m)

        self.setFlow(QListView.Flow.LeftToRight)
        self.setWrapping(True)
        self.setResizeMode(QListView.ResizeMode.Adjust)
        self.setGridSize(QSize(190, 260))
        self.setIconSize(QSize(*CoverDelegate.ICON_SIZE))
        self.setSelectionMode(QAbstractItemView.SelectionMode.SingleSelection)
        self.setViewMode(QListView.ViewMode.IconMode)

        self.delegate = CoverDelegate(self)
        self.setItemDelegate(self.delegate)
        self.delegate.needs_redraw.connect(self.redraw_spinners,
                type=Qt.ConnectionType.QueuedConnection)

        self.doubleClicked.connect(self.chosen, type=Qt.ConnectionType.QueuedConnection)
        self.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
        self.customContextMenuRequested.connect(self.show_context_menu)
    def __init__(self,
                 fmt_count,
                 msg,
                 single=False,
                 parent=None,
                 exclude=False):
        QDialog.__init__(self, parent)
        self._l = QVBoxLayout(self)
        self.single_fmt = single
        self.setLayout(self._l)
        self.setWindowTitle(_('Choose formats'))
        self._m = QLabel(msg)
        self._m.setWordWrap(True)
        self._l.addWidget(self._m)
        self.formats = Formats(fmt_count)
        self.fview = QListView(self)
        self.fview.doubleClicked.connect(
            self.double_clicked, type=Qt.ConnectionType.QueuedConnection)
        if exclude:
            if QApplication.instance().is_dark_theme:
                sheet = 'background-color: #DAA520; color: black'
            else:
                sheet = 'background-color: #fae7b5'
            self.fview.setStyleSheet('QListView { %s }' % sheet)
        self._l.addWidget(self.fview)
        self.fview.setModel(self.formats)
        self.fview.setSelectionMode(
            QAbstractItemView.SelectionMode.SingleSelection
            if single else QAbstractItemView.SelectionMode.MultiSelection)
        self.bbox = \
        QDialogButtonBox(QDialogButtonBox.StandardButton.Ok|QDialogButtonBox.StandardButton.Cancel,
                Qt.Orientation.Horizontal, self)
        self._l.addWidget(self.bbox)
        self.bbox.accepted.connect(self.accept)
        self.bbox.rejected.connect(self.reject)
        self.fview.setIconSize(QSize(48, 48))
        self.fview.setSpacing(2)

        self.resize(350, 500)
        self.selected_formats = set()
예제 #19
0
    def setup_ui(self):
        from calibre.gui2.preferences.look_feel import (DisplayedFields,
                                                        move_field_down,
                                                        move_field_up)
        self.l = QVBoxLayout(self)
        self.field_display_order = fdo = QListView(self)
        self.model = DisplayedFields(self.db,
                                     fdo,
                                     pref_name='popup_book_display_fields')
        self.model.initialize()
        fdo.setModel(self.model)
        fdo.setAlternatingRowColors(True)
        del self.db
        self.l.addWidget(QLabel(_('Select displayed metadata')))
        h = QHBoxLayout()
        h.addWidget(fdo)
        v = QVBoxLayout()
        self.mub = b = QToolButton(self)
        connect_lambda(b.clicked, self,
                       lambda self: move_field_up(fdo, self.model))
        b.setIcon(QIcon(I('arrow-up.png')))
        b.setToolTip(_('Move the selected field up'))
        v.addWidget(b), v.addStretch(10)
        self.mud = b = QToolButton(self)
        b.setIcon(QIcon(I('arrow-down.png')))
        b.setToolTip(_('Move the selected field down'))
        connect_lambda(b.clicked, self,
                       lambda self: move_field_down(fdo, self.model))
        v.addWidget(b)
        h.addLayout(v)

        self.l.addLayout(h)
        self.l.addWidget(
            QLabel('<p>' + _(
                'Note that <b>comments</b> will always be displayed at the end, regardless of the order you assign here'
            )))

        b = self.bb.addButton(_('Restore &defaults'),
                              QDialogButtonBox.ButtonRole.ActionRole)
        b.clicked.connect(self.restore_defaults)
        b = self.bb.addButton(_('Select &all'),
                              QDialogButtonBox.ButtonRole.ActionRole)
        b.clicked.connect(self.select_all)
        b = self.bb.addButton(_('Select &none'),
                              QDialogButtonBox.ButtonRole.ActionRole)
        b.clicked.connect(self.select_none)
        self.l.addWidget(self.bb)
        self.setMinimumHeight(500)
예제 #20
0
 def mouseMoveEvent(self, ev):
     index = self.indexAt(ev.pos())
     if index.isValid():
         row = index.row()
         if row != self.last_mouse_idx:
             self.last_mouse_idx = row
             try:
                 char_code = int(self.model().data(index, Qt.ItemDataRole.UserRole))
             except (TypeError, ValueError):
                 pass
             else:
                 self.show_name.emit(char_code)
         self.setCursor(Qt.CursorShape.PointingHandCursor)
     else:
         self.setCursor(Qt.CursorShape.ArrowCursor)
         self.show_name.emit(-1)
         self.last_mouse_idx = -1
     return QListView.mouseMoveEvent(self, ev)
예제 #21
0
class ShortcutConfig(QWidget):
    def __init__(self, model, parent=None):
        QWidget.__init__(self, parent)
        self._layout = QHBoxLayout()
        self.setLayout(self._layout)
        self.view = QListView(self)
        self._layout.addWidget(self.view)
        self.view.setModel(model)
        self.delegate = Delegate()
        self.view.setItemDelegate(self.delegate)
        self.delegate.sizeHintChanged.connect(
            self.scrollTo, type=Qt.ConnectionType.QueuedConnection)

    def scrollTo(self, index):
        self.view.scrollTo(index, QAbstractItemView.ScrollHint.EnsureVisible)

    @property
    def is_editing(self):
        return self.view.state() == QAbstractItemView.State.EditingState
예제 #22
0
    def setupUi(self):
        self.setObjectName("Dialog")
        self.resize(1024, 700)
        self.setWindowIcon(QIcon(I('convert.png')))
        self.gridLayout = QGridLayout(self)
        self.gridLayout.setObjectName("gridLayout")
        self.horizontalLayout = QHBoxLayout()
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.input_label = QLabel(self)
        self.input_label.setObjectName("input_label")
        self.horizontalLayout.addWidget(self.input_label)
        self.input_formats = QComboBox(self)
        self.input_formats.setSizeAdjustPolicy(
            QComboBox.SizeAdjustPolicy.AdjustToMinimumContentsLengthWithIcon)
        self.input_formats.setMinimumContentsLength(5)
        self.input_formats.setObjectName("input_formats")
        self.horizontalLayout.addWidget(self.input_formats)
        self.opt_individual_saved_settings = QCheckBox(self)
        self.opt_individual_saved_settings.setObjectName(
            "opt_individual_saved_settings")
        self.horizontalLayout.addWidget(self.opt_individual_saved_settings)
        spacerItem = QSpacerItem(40, 20, QSizePolicy.Policy.Expanding,
                                 QSizePolicy.Policy.Minimum)
        self.horizontalLayout.addItem(spacerItem)
        self.label_2 = QLabel(self)
        self.label_2.setObjectName("label_2")
        self.horizontalLayout.addWidget(self.label_2)
        self.output_formats = QComboBox(self)
        self.output_formats.setSizeAdjustPolicy(
            QComboBox.SizeAdjustPolicy.AdjustToMinimumContentsLengthWithIcon)
        self.output_formats.setMinimumContentsLength(5)
        self.output_formats.setObjectName("output_formats")
        self.horizontalLayout.addWidget(self.output_formats)
        self.gridLayout.addLayout(self.horizontalLayout, 0, 0, 1, 2)
        self.groups = QListView(self)
        sizePolicy = QSizePolicy(QSizePolicy.Policy.Expanding,
                                 QSizePolicy.Policy.Expanding)
        sizePolicy.setHorizontalStretch(1)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.groups.sizePolicy().hasHeightForWidth())
        self.groups.setSizePolicy(sizePolicy)
        self.groups.setTabKeyNavigation(True)
        self.groups.setIconSize(QSize(48, 48))
        self.groups.setWordWrap(True)
        self.groups.setObjectName("groups")
        self.gridLayout.addWidget(self.groups, 1, 0, 3, 1)
        self.scrollArea = QScrollArea(self)
        sizePolicy = QSizePolicy(QSizePolicy.Policy.Expanding,
                                 QSizePolicy.Policy.Expanding)
        sizePolicy.setHorizontalStretch(4)
        sizePolicy.setVerticalStretch(10)
        sizePolicy.setHeightForWidth(
            self.scrollArea.sizePolicy().hasHeightForWidth())
        self.scrollArea.setSizePolicy(sizePolicy)
        self.scrollArea.setFrameShape(QFrame.Shape.NoFrame)
        self.scrollArea.setLineWidth(0)
        self.scrollArea.setWidgetResizable(True)
        self.scrollArea.setObjectName("scrollArea")
        self.page = QWidget()
        self.page.setObjectName("page")
        self.gridLayout.addWidget(self.scrollArea, 1, 1, 1, 1)
        self.buttonBox = QDialogButtonBox(self)
        self.buttonBox.setOrientation(Qt.Orientation.Horizontal)
        self.buttonBox.setStandardButtons(
            QDialogButtonBox.StandardButton.Cancel
            | QDialogButtonBox.StandardButton.Ok
            | QDialogButtonBox.StandardButton.RestoreDefaults)
        self.buttonBox.setObjectName("buttonBox")
        self.gridLayout.addWidget(self.buttonBox, 3, 1, 1, 1)
        self.help = QTextEdit(self)
        self.help.setReadOnly(True)
        sizePolicy = QSizePolicy(QSizePolicy.Policy.Expanding,
                                 QSizePolicy.Policy.Expanding)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.help.sizePolicy().hasHeightForWidth())
        self.help.setSizePolicy(sizePolicy)
        self.help.setMaximumHeight(80)
        self.help.setObjectName("help")
        self.gridLayout.addWidget(self.help, 2, 1, 1, 1)
        self.input_label.setBuddy(self.input_formats)
        self.label_2.setBuddy(self.output_formats)
        self.input_label.setText(_("&Input format:"))
        self.opt_individual_saved_settings.setText(
            _("Use &saved conversion settings for individual books"))
        self.label_2.setText(_("&Output format:"))

        self.buttonBox.accepted.connect(self.accept)
        self.buttonBox.rejected.connect(self.reject)
예제 #23
0
class Config(QDialog):
    '''
    Configuration dialog for single book conversion. If accepted, has the
    following important attributes

    output_format - Output format (without a leading .)
    input_format  - Input format (without a leading .)
    opf_path - Path to OPF file with user specified metadata
    cover_path - Path to user specified cover (can be None)
    recommendations - A pickled list of 3 tuples in the same format as the
    recommendations member of the Input/Output plugins.
    '''
    def __init__(self,
                 parent,
                 db,
                 book_id,
                 preferred_input_format=None,
                 preferred_output_format=None):
        QDialog.__init__(self, parent)
        self.widgets = []
        self.setupUi()
        self.opt_individual_saved_settings.setVisible(False)
        self.db, self.book_id = db, book_id

        self.setup_input_output_formats(self.db, self.book_id,
                                        preferred_input_format,
                                        preferred_output_format)
        self.setup_pipeline()

        self.input_formats.currentIndexChanged[native_string_type].connect(
            self.setup_pipeline)
        self.output_formats.currentIndexChanged[native_string_type].connect(
            self.setup_pipeline)
        self.groups.setSpacing(5)
        self.groups.entered[(QModelIndex)].connect(self.show_group_help)
        rb = self.buttonBox.button(
            QDialogButtonBox.StandardButton.RestoreDefaults)
        rb.setText(_('Restore &defaults'))
        rb.setIcon(QIcon(I('clear_left.png')))
        rb.clicked.connect(self.restore_defaults)
        self.groups.setMouseTracking(True)
        geom = gprefs.get('convert_single_dialog_geom', None)
        if geom:
            QApplication.instance().safe_restore_geometry(self, geom)
        else:
            self.resize(self.sizeHint())

    def current_group_changed(self, cur, prev):
        self.show_pane(cur)

    def setupUi(self):
        self.setObjectName("Dialog")
        self.resize(1024, 700)
        self.setWindowIcon(QIcon(I('convert.png')))
        self.gridLayout = QGridLayout(self)
        self.gridLayout.setObjectName("gridLayout")
        self.horizontalLayout = QHBoxLayout()
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.input_label = QLabel(self)
        self.input_label.setObjectName("input_label")
        self.horizontalLayout.addWidget(self.input_label)
        self.input_formats = QComboBox(self)
        self.input_formats.setSizeAdjustPolicy(
            QComboBox.SizeAdjustPolicy.AdjustToMinimumContentsLengthWithIcon)
        self.input_formats.setMinimumContentsLength(5)
        self.input_formats.setObjectName("input_formats")
        self.horizontalLayout.addWidget(self.input_formats)
        self.opt_individual_saved_settings = QCheckBox(self)
        self.opt_individual_saved_settings.setObjectName(
            "opt_individual_saved_settings")
        self.horizontalLayout.addWidget(self.opt_individual_saved_settings)
        spacerItem = QSpacerItem(40, 20, QSizePolicy.Policy.Expanding,
                                 QSizePolicy.Policy.Minimum)
        self.horizontalLayout.addItem(spacerItem)
        self.label_2 = QLabel(self)
        self.label_2.setObjectName("label_2")
        self.horizontalLayout.addWidget(self.label_2)
        self.output_formats = QComboBox(self)
        self.output_formats.setSizeAdjustPolicy(
            QComboBox.SizeAdjustPolicy.AdjustToMinimumContentsLengthWithIcon)
        self.output_formats.setMinimumContentsLength(5)
        self.output_formats.setObjectName("output_formats")
        self.horizontalLayout.addWidget(self.output_formats)
        self.gridLayout.addLayout(self.horizontalLayout, 0, 0, 1, 2)
        self.groups = QListView(self)
        sizePolicy = QSizePolicy(QSizePolicy.Policy.Expanding,
                                 QSizePolicy.Policy.Expanding)
        sizePolicy.setHorizontalStretch(1)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.groups.sizePolicy().hasHeightForWidth())
        self.groups.setSizePolicy(sizePolicy)
        self.groups.setTabKeyNavigation(True)
        self.groups.setIconSize(QSize(48, 48))
        self.groups.setWordWrap(True)
        self.groups.setObjectName("groups")
        self.gridLayout.addWidget(self.groups, 1, 0, 3, 1)
        self.scrollArea = QScrollArea(self)
        sizePolicy = QSizePolicy(QSizePolicy.Policy.Expanding,
                                 QSizePolicy.Policy.Expanding)
        sizePolicy.setHorizontalStretch(4)
        sizePolicy.setVerticalStretch(10)
        sizePolicy.setHeightForWidth(
            self.scrollArea.sizePolicy().hasHeightForWidth())
        self.scrollArea.setSizePolicy(sizePolicy)
        self.scrollArea.setFrameShape(QFrame.Shape.NoFrame)
        self.scrollArea.setLineWidth(0)
        self.scrollArea.setWidgetResizable(True)
        self.scrollArea.setObjectName("scrollArea")
        self.page = QWidget()
        self.page.setObjectName("page")
        self.gridLayout.addWidget(self.scrollArea, 1, 1, 1, 1)
        self.buttonBox = QDialogButtonBox(self)
        self.buttonBox.setOrientation(Qt.Orientation.Horizontal)
        self.buttonBox.setStandardButtons(
            QDialogButtonBox.StandardButton.Cancel
            | QDialogButtonBox.StandardButton.Ok
            | QDialogButtonBox.StandardButton.RestoreDefaults)
        self.buttonBox.setObjectName("buttonBox")
        self.gridLayout.addWidget(self.buttonBox, 3, 1, 1, 1)
        self.help = QTextEdit(self)
        self.help.setReadOnly(True)
        sizePolicy = QSizePolicy(QSizePolicy.Policy.Expanding,
                                 QSizePolicy.Policy.Expanding)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.help.sizePolicy().hasHeightForWidth())
        self.help.setSizePolicy(sizePolicy)
        self.help.setMaximumHeight(80)
        self.help.setObjectName("help")
        self.gridLayout.addWidget(self.help, 2, 1, 1, 1)
        self.input_label.setBuddy(self.input_formats)
        self.label_2.setBuddy(self.output_formats)
        self.input_label.setText(_("&Input format:"))
        self.opt_individual_saved_settings.setText(
            _("Use &saved conversion settings for individual books"))
        self.label_2.setText(_("&Output format:"))

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

    def sizeHint(self):
        geom = self.screen().availableSize()
        nh, nw = max(300, geom.height() - 100), max(400, geom.width() - 70)
        return QSize(nw, nh)

    def restore_defaults(self):
        delete_specifics(self.db, self.book_id)
        self.setup_pipeline()

    @property
    def input_format(self):
        return str(self.input_formats.currentText()).lower()

    @property
    def output_format(self):
        return str(self.output_formats.currentText()).lower()

    @property
    def manually_fine_tune_toc(self):
        for w in self.widgets:
            if hasattr(w, 'manually_fine_tune_toc'):
                return w.manually_fine_tune_toc.isChecked()

    def setup_pipeline(self, *args):
        oidx = self.groups.currentIndex().row()
        input_format = self.input_format
        output_format = self.output_format
        self.plumber = create_dummy_plumber(input_format, output_format)

        def widget_factory(cls):
            return cls(self, self.plumber.get_option_by_name,
                       self.plumber.get_option_help, self.db, self.book_id)

        self.mw = widget_factory(MetadataWidget)
        self.setWindowTitle(_('Convert') + ' ' + str(self.mw.title.text()))
        lf = widget_factory(LookAndFeelWidget)
        hw = widget_factory(HeuristicsWidget)
        sr = widget_factory(SearchAndReplaceWidget)
        ps = widget_factory(PageSetupWidget)
        sd = widget_factory(StructureDetectionWidget)
        toc = widget_factory(TOCWidget)
        from calibre.gui2.actions.toc_edit import SUPPORTED
        toc.manually_fine_tune_toc.setVisible(
            output_format.upper() in SUPPORTED)
        debug = widget_factory(DebugWidget)

        output_widget = self.plumber.output_plugin.gui_configuration_widget(
            self, self.plumber.get_option_by_name,
            self.plumber.get_option_help, self.db, self.book_id)
        input_widget = self.plumber.input_plugin.gui_configuration_widget(
            self, self.plumber.get_option_by_name,
            self.plumber.get_option_help, self.db, self.book_id)

        self.break_cycles()
        self.widgets = widgets = [self.mw, lf, hw, ps, sd, toc, sr]
        if input_widget is not None:
            widgets.append(input_widget)
        if output_widget is not None:
            widgets.append(output_widget)
        widgets.append(debug)
        for w in widgets:
            w.set_help_signal.connect(self.help.setPlainText)
            w.setVisible(False)

        self._groups_model = GroupModel(widgets)
        self.groups.setModel(self._groups_model)

        idx = oidx if -1 < oidx < self._groups_model.rowCount() else 0
        self.groups.setCurrentIndex(self._groups_model.index(idx))
        self.show_pane(idx)
        self.groups.selectionModel().currentChanged.connect(
            self.current_group_changed)
        try:
            shutil.rmtree(self.plumber.archive_input_tdir, ignore_errors=True)
        except Exception:
            pass

    def setup_input_output_formats(self, db, book_id, preferred_input_format,
                                   preferred_output_format):
        if preferred_output_format:
            preferred_output_format = preferred_output_format.upper()
        output_formats = get_output_formats(preferred_output_format)
        input_format, input_formats = get_input_format_for_book(
            db, book_id, preferred_input_format)
        preferred_output_format = preferred_output_format if \
            preferred_output_format in output_formats else \
            sort_formats_by_preference(output_formats,
                    [prefs['output_format']])[0]
        self.input_formats.addItems(str(x.upper()) for x in input_formats)
        self.output_formats.addItems(str(x.upper()) for x in output_formats)
        self.input_formats.setCurrentIndex(input_formats.index(input_format))
        self.output_formats.setCurrentIndex(
            output_formats.index(preferred_output_format))

    def show_pane(self, index):
        if hasattr(index, 'row'):
            index = index.row()
        ow = self.scrollArea.takeWidget()
        if ow:
            ow.setParent(self)
        for i, w in enumerate(self.widgets):
            if i == index:
                self.scrollArea.setWidget(w)
                w.show()
            else:
                w.setVisible(False)

    def accept(self):
        recs = GuiRecommendations()
        for w in self._groups_model.widgets:
            if not w.pre_commit_check():
                return
            x = w.commit(save_defaults=False)
            recs.update(x)
        self.opf_file, self.cover_file = self.mw.opf_file, self.mw.cover_file
        self._recommendations = recs
        if self.db is not None:
            recs['gui_preferred_input_format'] = self.input_format
            save_specifics(self.db, self.book_id, recs)
        self.break_cycles()
        QDialog.accept(self)

    def reject(self):
        self.break_cycles()
        QDialog.reject(self)

    def done(self, r):
        if self.isVisible():
            gprefs['convert_single_dialog_geom'] = \
                bytearray(self.saveGeometry())
        return QDialog.done(self, r)

    def break_cycles(self):
        for w in self.widgets:
            w.break_cycles()

    @property
    def recommendations(self):
        recs = [(k, v, OptionRecommendation.HIGH)
                for k, v in self._recommendations.items()]
        return recs

    def show_group_help(self, index):
        widget = self._groups_model.widgets[index.row()]
        self.help.setPlainText(widget.HELP)
예제 #24
0
 def currentChanged(self, current, previous):
     self.changed.emit()
     QListView.currentChanged(self, current, previous)
예제 #25
0
 def __init__(self, parent):
     QListView.__init__(self, parent)
     self.setSelectionMode(QAbstractItemView.SelectionMode.SingleSelection)
     self.setAlternatingRowColors(True)
     self.d = FontFamilyDelegate(self)
     self.setItemDelegate(self.d)
예제 #26
0
 def resizeEvent(self, ev):
     self._ncols = None
     self.resize_timer.start()
     return QListView.resizeEvent(self, ev)
예제 #27
0
    def setup_ui(self):
        self.l = l = QGridLayout(self)
        self.setLayout(l)

        self.la1 = la = QLabel(_('&Existing images in the book'))
        la.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed)
        l.addWidget(la, 0, 0, 1, 2)
        if self.for_browsing:
            la.setVisible(False)

        self.view = v = QListView(self)
        v.setViewMode(QListView.ViewMode.IconMode)
        v.setFlow(QListView.Flow.LeftToRight)
        v.setSpacing(4)
        v.setResizeMode(QListView.ResizeMode.Adjust)
        v.setUniformItemSizes(True)
        set_no_activate_on_click(v)
        v.activated.connect(self.activated)
        v.doubleClicked.connect(self.activated)
        self.d = ImageDelegate(v)
        v.setItemDelegate(self.d)
        self.model = Images(self.view)
        self.fm = fm = QSortFilterProxyModel(self.view)
        self.fm.setDynamicSortFilter(self.for_browsing)
        fm.setSourceModel(self.model)
        fm.setFilterCaseSensitivity(False)
        v.setModel(fm)
        l.addWidget(v, 1, 0, 1, 2)
        v.pressed.connect(self.pressed)
        la.setBuddy(v)

        self.filter = f = QLineEdit(self)
        f.setPlaceholderText(_('Search for image by file name'))
        l.addWidget(f, 2, 0)
        self.cb = b = QToolButton(self)
        b.setIcon(QIcon(I('clear_left.png')))
        b.clicked.connect(f.clear)
        l.addWidget(b, 2, 1)
        f.textChanged.connect(self.filter_changed)

        if self.for_browsing:
            self.bb.clear()
            self.bb.addButton(QDialogButtonBox.StandardButton.Close)
            b = self.refresh_button = self.bb.addButton(_('&Refresh'), QDialogButtonBox.ButtonRole.ActionRole)
            b.clicked.connect(self.refresh)
            b.setIcon(QIcon(I('view-refresh.png')))
            b.setToolTip(_('Refresh the displayed images'))
            self.setAttribute(Qt.WidgetAttribute.WA_DeleteOnClose, False)
        else:
            b = self.import_button = self.bb.addButton(_('&Import image'), QDialogButtonBox.ButtonRole.ActionRole)
            b.clicked.connect(self.import_image)
            b.setIcon(QIcon(I('view-image.png')))
            b.setToolTip(_('Import an image from elsewhere in your computer'))
            b = self.paste_button = self.bb.addButton(_('&Paste image'), QDialogButtonBox.ButtonRole.ActionRole)
            b.clicked.connect(self.paste_image)
            b.setIcon(QIcon(I('edit-paste.png')))
            b.setToolTip(_('Paste an image from the clipboard'))
            self.fullpage = f = QCheckBox(_('Full page image'), self)
            f.setToolTip(_('Insert the image so that it takes up an entire page when viewed in a reader'))
            f.setChecked(tprefs['insert_full_screen_image'])
            self.preserve_aspect_ratio = a = QCheckBox(_('Preserve aspect ratio'))
            a.setToolTip(_('Preserve the aspect ratio of the inserted image when rendering it full paged'))
            a.setChecked(tprefs['preserve_aspect_ratio_when_inserting_image'])
            f.toggled.connect(self.full_page_image_toggled)
            a.toggled.connect(self.par_toggled)
            a.setVisible(f.isChecked())
            h = QHBoxLayout()
            l.addLayout(h, 3, 0, 1, -1)
            h.addWidget(f), h.addStretch(10), h.addWidget(a)
        b = self.bb.addButton(_('&Zoom in'), QDialogButtonBox.ButtonRole.ActionRole)
        b.clicked.connect(self.zoom_in)
        b.setIcon(QIcon(I('plus.png')))
        b = self.bb.addButton(_('Zoom &out'), QDialogButtonBox.ButtonRole.ActionRole)
        b.clicked.connect(self.zoom_out)
        b.setIcon(QIcon(I('minus.png')))
        l.addWidget(self.bb, 4, 0, 1, 2)
예제 #28
0
 def keyPressEvent(self, ev):
     if ev.key() in (Qt.Key.Key_Enter, Qt.Key.Key_Return):
         self.chosen.emit()
         ev.accept()
         return
     return QListView.keyPressEvent(self, ev)
예제 #29
0
 def hide(self):
     self.setCurrentIndex(QModelIndex())
     QListView.hide(self)
예제 #30
0
 def currentChanged(self, cur, prev):
     QListView.currentChanged(self, cur, prev)
     self.current_changed.emit(cur, prev)