%PDF- %PDF-
| Direktori : /lib/calibre/calibre/gui2/preferences/ |
| Current File : //lib/calibre/calibre/gui2/preferences/texture_chooser.py |
#!/usr/bin/env python3
__license__ = 'GPL v3'
__copyright__ = '2013, Kovid Goyal <kovid at kovidgoyal.net>'
import glob, os, shutil
from functools import partial
from qt.core import (
QDialog, QVBoxLayout, QListWidget, QListWidgetItem, Qt, QIcon,
QApplication, QSize, QDialogButtonBox, QTimer, QLabel, QAbstractItemView, QListView)
from calibre.constants import config_dir
from calibre.gui2 import choose_files, error_dialog
from calibre.utils.icu import sort_key
def texture_dir():
ans = os.path.join(config_dir, 'textures')
if not os.path.exists(ans):
os.makedirs(ans)
return ans
def texture_path(fname):
if not fname:
return
if fname.startswith(':'):
return I('textures/%s' % fname[1:])
return os.path.join(texture_dir(), fname)
class TextureChooser(QDialog):
def __init__(self, parent=None, initial=None):
QDialog.__init__(self, parent)
self.setWindowTitle(_('Choose a texture'))
self.l = l = QVBoxLayout()
self.setLayout(l)
self.tdir = texture_dir()
self.images = il = QListWidget(self)
il.itemDoubleClicked.connect(self.accept, type=Qt.ConnectionType.QueuedConnection)
il.setIconSize(QSize(256, 256))
il.setViewMode(QListView.ViewMode.IconMode)
il.setFlow(QListView.Flow.LeftToRight)
il.setSpacing(20)
il.setSelectionMode(QAbstractItemView.SelectionMode.SingleSelection)
il.itemSelectionChanged.connect(self.update_remove_state)
l.addWidget(il)
self.ad = ad = QLabel(_('The builtin textures come from <a href="{}">subtlepatterns.com</a>.').format(
'https://www.toptal.com/designers/subtlepatterns/'))
ad.setOpenExternalLinks(True)
ad.setWordWrap(True)
l.addWidget(ad)
self.bb = bb = QDialogButtonBox(QDialogButtonBox.StandardButton.Ok|QDialogButtonBox.StandardButton.Cancel)
bb.accepted.connect(self.accept)
bb.rejected.connect(self.reject)
b = self.add_button = bb.addButton(_('Add texture'), QDialogButtonBox.ButtonRole.ActionRole)
b.setIcon(QIcon(I('plus.png')))
b.clicked.connect(self.add_texture)
b = self.remove_button = bb.addButton(_('Remove texture'), QDialogButtonBox.ButtonRole.ActionRole)
b.setIcon(QIcon(I('minus.png')))
b.clicked.connect(self.remove_texture)
l.addWidget(bb)
images = [{
'fname': ':'+os.path.basename(x),
'path': x,
'name': ' '.join(map(lambda s: s.capitalize(), os.path.splitext(os.path.basename(x))[0].split('_')))
} for x in glob.glob(I('textures/*.png'))] + [{
'fname': os.path.basename(x),
'path': x,
'name': os.path.splitext(os.path.basename(x))[0],
} for x in glob.glob(os.path.join(self.tdir, '*')) if x.rpartition('.')[-1].lower() in {'jpeg', 'png', 'jpg'}]
images.sort(key=lambda x:sort_key(x['name']))
for i in images:
self.create_item(i)
self.update_remove_state()
if initial:
existing = {str(i.data(Qt.ItemDataRole.UserRole) or ''):i for i in (self.images.item(c) for c in range(self.images.count()))}
item = existing.get(initial, None)
if item is not None:
item.setSelected(True)
QTimer.singleShot(100, partial(il.scrollToItem, item))
self.resize(QSize(950, 650))
def create_item(self, data):
x = data
i = QListWidgetItem(QIcon(x['path']), x['name'], self.images)
i.setData(Qt.ItemDataRole.UserRole, x['fname'])
i.setData(Qt.ItemDataRole.UserRole+1, x['path'])
return i
def update_remove_state(self):
removable = bool(self.selected_fname and not self.selected_fname.startswith(':'))
self.remove_button.setEnabled(removable)
@property
def texture(self):
return self.selected_fname
def add_texture(self):
path = choose_files(self, 'choose-texture-image', _('Choose image'),
filters=[(_('Images'), ['jpeg', 'jpg', 'png'])], all_files=False, select_only_single_file=True)
if not path:
return
path = path[0]
fname = os.path.basename(path)
name = fname.rpartition('.')[0]
existing = {str(i.data(Qt.ItemDataRole.UserRole) or ''):i for i in (self.images.item(c) for c in range(self.images.count()))}
dest = os.path.join(self.tdir, fname)
with open(path, 'rb') as s, open(dest, 'wb') as f:
shutil.copyfileobj(s, f)
if fname in existing:
self.takeItem(existing[fname])
data = {'fname': fname, 'path': dest, 'name': name}
i = self.create_item(data)
i.setSelected(True)
self.images.scrollToItem(i)
@property
def selected_item(self):
for x in self.images.selectedItems():
return x
@property
def selected_fname(self):
try:
return str(self.selected_item.data(Qt.ItemDataRole.UserRole) or '')
except (AttributeError, TypeError):
pass
def remove_texture(self):
if not self.selected_fname:
return
if self.selected_fname.startswith(':'):
return error_dialog(self, _('Cannot remove'),
_('Cannot remove builtin textures'), show=True)
os.remove(str(self.selected_item.data(Qt.ItemDataRole.UserRole+1) or ''))
self.images.takeItem(self.images.row(self.selected_item))
if __name__ == '__main__':
app = QApplication([]) # noqa
d = TextureChooser()
d.exec()
print(d.texture)