mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-08 10:44:09 -04:00
Copy to library: Add a action to show a dialog that allows for easy selection of libraries for copy/move. Useful when there are a large number of libraries to choose from. Fixes #1706198 [[Enhancement] Provide users the ability to remove/hide popup menu option copy to library, leaving only Delete After Copy option visible](https://bugs.launchpad.net/calibre/+bug/1706198)
This commit is contained in:
parent
0f6d873070
commit
a74d0546eb
@ -12,8 +12,9 @@ from contextlib import closing
|
||||
from collections import defaultdict
|
||||
|
||||
from PyQt5.Qt import (
|
||||
QToolButton, QDialog, QGridLayout, QIcon, QLabel, QDialogButtonBox, QApplication,
|
||||
QFormLayout, QCheckBox, QWidget, QScrollArea, QVBoxLayout, Qt, QListWidgetItem, QListWidget)
|
||||
QToolButton, QDialog, QGridLayout, QIcon, QLabel, QDialogButtonBox,
|
||||
QApplication, QLineEdit, QHBoxLayout, QFormLayout, QCheckBox, QWidget,
|
||||
QScrollArea, QVBoxLayout, Qt, QListWidgetItem, QListWidget, QSize)
|
||||
|
||||
from calibre import as_unicode
|
||||
from calibre.constants import isosx
|
||||
@ -22,10 +23,10 @@ from calibre.gui2.actions import InterfaceAction
|
||||
from calibre.gui2 import (error_dialog, Dispatcher, warning_dialog, gprefs,
|
||||
info_dialog, choose_dir)
|
||||
from calibre.gui2.dialogs.progress import ProgressDialog
|
||||
from calibre.gui2.widgets import HistoryLineEdit
|
||||
from calibre.gui2.widgets2 import Dialog
|
||||
from calibre.utils.config import prefs, tweaks
|
||||
from calibre.utils.date import now
|
||||
from calibre.utils.icu import sort_key
|
||||
from calibre.utils.icu import sort_key, numeric_sort_key
|
||||
|
||||
|
||||
def ask_about_cc_mismatch(gui, db, newdb, missing_cols, incompatible_cols): # {{{
|
||||
@ -257,28 +258,52 @@ class Worker(Thread): # {{{
|
||||
|
||||
# }}}
|
||||
|
||||
class ChooseLibrary(QDialog): # {{{
|
||||
class ChooseLibrary(Dialog): # {{{
|
||||
|
||||
def __init__(self, parent):
|
||||
super(ChooseLibrary, self).__init__(parent)
|
||||
d = self
|
||||
d.l = l = QGridLayout()
|
||||
d.setLayout(l)
|
||||
d.setWindowTitle(_('Choose library'))
|
||||
la = d.la = QLabel(_('Library &path:'))
|
||||
l.addWidget(la, 0, 0)
|
||||
le = d.le = HistoryLineEdit(d)
|
||||
le.initialize('choose_library_for_copy')
|
||||
l.addWidget(le, 0, 1)
|
||||
def __init__(self, parent, locations):
|
||||
self.locations = locations
|
||||
Dialog.__init__(self, _('Choose library'), 'copy_to_choose_library_dialog', parent)
|
||||
self.resort()
|
||||
self.current_changed()
|
||||
|
||||
def resort(self):
|
||||
if self.sort_alphabetically.isChecked():
|
||||
sorted_locations = sorted(self.locations, key=lambda (name, loc): numeric_sort_key(name))
|
||||
else:
|
||||
sorted_locations = self.locations
|
||||
self.items.clear()
|
||||
for name, loc in sorted_locations:
|
||||
i = QListWidgetItem(name, self.items)
|
||||
i.setData(Qt.UserRole, loc)
|
||||
self.items.setCurrentRow(0)
|
||||
|
||||
def setup_ui(self):
|
||||
self.l = l = QGridLayout(self)
|
||||
self.items = i = QListWidget(self)
|
||||
i.setSelectionMode(i.SingleSelection)
|
||||
i.currentItemChanged.connect(self.current_changed)
|
||||
l.addWidget(i)
|
||||
self.v = v = QVBoxLayout()
|
||||
l.addLayout(v, 0, 1)
|
||||
self.sort_alphabetically = sa = QCheckBox(_('&Sort libraries alphabetically'))
|
||||
v.addWidget(sa)
|
||||
sa.setChecked(bool(gprefs.get('copy_to_library_choose_library_sort_alphabetically', True)))
|
||||
sa.stateChanged.connect(self.resort)
|
||||
sa.stateChanged.connect(lambda: gprefs.set('copy_to_library_choose_library_sort_alphabetically', bool(self.sort_alphabetically.isChecked())))
|
||||
la = self.la = QLabel(_('Library &path:'))
|
||||
v.addWidget(la)
|
||||
le = self.le = QLineEdit(self)
|
||||
la.setBuddy(le)
|
||||
b = d.b = QToolButton(d)
|
||||
b = self.b = QToolButton(self)
|
||||
b.setIcon(QIcon(I('document_open.png')))
|
||||
b.setToolTip(_('Browse for library'))
|
||||
b.clicked.connect(self.browse)
|
||||
l.addWidget(b, 0, 2)
|
||||
self.bb = bb = QDialogButtonBox(QDialogButtonBox.Cancel)
|
||||
bb.accepted.connect(self.accept)
|
||||
bb.rejected.connect(self.reject)
|
||||
h = QHBoxLayout()
|
||||
h.addWidget(le), h.addWidget(b)
|
||||
v.addLayout(h)
|
||||
v.addStretch(10)
|
||||
bb = self.bb
|
||||
bb.setStandardButtons(QDialogButtonBox.Cancel)
|
||||
self.delete_after_copy = False
|
||||
b = bb.addButton(_('&Copy'), bb.AcceptRole)
|
||||
b.setIcon(QIcon(I('edit-copy.png')))
|
||||
@ -288,9 +313,16 @@ class ChooseLibrary(QDialog): # {{{
|
||||
b2.setIcon(QIcon(I('edit-cut.png')))
|
||||
b2.setToolTip(_('Copy to the specified library and delete from the current library'))
|
||||
b.setDefault(True)
|
||||
l.addWidget(bb, 1, 0, 1, 3)
|
||||
le.setMinimumWidth(350)
|
||||
self.resize(self.sizeHint())
|
||||
l.addWidget(bb, 1, 0, 1, 2)
|
||||
self.items.setFocus(Qt.OtherFocusReason)
|
||||
|
||||
def sizeHint(self):
|
||||
return QSize(800, 550)
|
||||
|
||||
def current_changed(self):
|
||||
i = self.items.currentItem() or self.items.item(0)
|
||||
loc = i.data(Qt.UserRole)
|
||||
self.le.setText(loc)
|
||||
|
||||
def browse(self):
|
||||
d = choose_dir(self, 'choose_library_for_copy',
|
||||
@ -396,8 +428,7 @@ class CopyToLibraryAction(InterfaceAction):
|
||||
return
|
||||
db = self.gui.library_view.model().db
|
||||
locations = list(self.stats.locations(db))
|
||||
if len(locations) > 50:
|
||||
self.menu.addAction(_('Choose library by path...'), self.choose_library)
|
||||
self.menu.addAction(_('Choose library...'), self.choose_library)
|
||||
self.menu.addSeparator()
|
||||
for name, loc in locations:
|
||||
name = name.replace('&', '&&')
|
||||
@ -407,15 +438,15 @@ class CopyToLibraryAction(InterfaceAction):
|
||||
partial(self.copy_to_library, loc, delete_after=True))
|
||||
self.menu.addSeparator()
|
||||
|
||||
if len(locations) <= 50:
|
||||
self.menu.addAction(_('Choose library by path...'), self.choose_library)
|
||||
self.qaction.setVisible(bool(locations))
|
||||
if isosx:
|
||||
# The cloned action has to have its menu updated
|
||||
self.qaction.changed.emit()
|
||||
|
||||
def choose_library(self):
|
||||
d = ChooseLibrary(self.gui)
|
||||
db = self.gui.library_view.model().db
|
||||
locations = list(self.stats.locations(db))
|
||||
d = ChooseLibrary(self.gui, locations)
|
||||
if d.exec_() == d.Accepted:
|
||||
path, delete_after = d.args
|
||||
if not path:
|
||||
|
Loading…
x
Reference in New Issue
Block a user