mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-08 18:54:09 -04:00
Allow using textures for cover grid background
Cover grid: Allow using images as the background for the cover grid. To choose an image, go to Preferences->Look & Feel->Cover Grid. Fixes #1239194 [[Ideas] -->book grid](https://bugs.launchpad.net/calibre/+bug/1239194) [[Ideas] -->book grid](https://bugs.launchpad.net/calibre/+bug/1239194) The builtin textures come from subtlepatterns.com
This commit is contained in:
parent
2277ed4b17
commit
a43941dc0d
BIN
resources/images/textures/dark_cloth.png
Normal file
BIN
resources/images/textures/dark_cloth.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 19 KiB |
BIN
resources/images/textures/dark_wood.png
Normal file
BIN
resources/images/textures/dark_wood.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 132 KiB |
BIN
resources/images/textures/grey_wash_wall.png
Normal file
BIN
resources/images/textures/grey_wash_wall.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 46 KiB |
BIN
resources/images/textures/light_wood.png
Normal file
BIN
resources/images/textures/light_wood.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 168 KiB |
BIN
resources/images/textures/subtle_wood.png
Normal file
BIN
resources/images/textures/subtle_wood.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 100 KiB |
@ -118,6 +118,7 @@ defs['cover_grid_color'] = (80, 80, 80)
|
|||||||
defs['cover_grid_cache_size'] = 100
|
defs['cover_grid_cache_size'] = 100
|
||||||
defs['cover_grid_disk_cache_size'] = 2500
|
defs['cover_grid_disk_cache_size'] = 2500
|
||||||
defs['cover_grid_show_title'] = False
|
defs['cover_grid_show_title'] = False
|
||||||
|
defs['cover_grid_texture'] = None
|
||||||
defs['show_vl_tabs'] = False
|
defs['show_vl_tabs'] = False
|
||||||
del defs
|
del defs
|
||||||
# }}}
|
# }}}
|
||||||
|
@ -19,7 +19,7 @@ from PyQt4.Qt import (
|
|||||||
QTimer, QPalette, QColor, QItemSelection, QPixmap, QMenu, QApplication,
|
QTimer, QPalette, QColor, QItemSelection, QPixmap, QMenu, QApplication,
|
||||||
QMimeData, QUrl, QDrag, QPoint, QPainter, QRect, pyqtProperty, QEvent,
|
QMimeData, QUrl, QDrag, QPoint, QPainter, QRect, pyqtProperty, QEvent,
|
||||||
QPropertyAnimation, QEasingCurve, pyqtSlot, QHelpEvent, QAbstractItemView,
|
QPropertyAnimation, QEasingCurve, pyqtSlot, QHelpEvent, QAbstractItemView,
|
||||||
QStyleOptionViewItem, QToolTip, QByteArray, QBuffer)
|
QStyleOptionViewItem, QToolTip, QByteArray, QBuffer, QBrush)
|
||||||
|
|
||||||
from calibre import fit_image, prints, prepare_string_for_xml
|
from calibre import fit_image, prints, prepare_string_for_xml
|
||||||
from calibre.ebooks.metadata import fmt_sidx
|
from calibre.ebooks.metadata import fmt_sidx
|
||||||
@ -586,6 +586,12 @@ class GridView(QListView):
|
|||||||
pal = QPalette()
|
pal = QPalette()
|
||||||
col = QColor(r, g, b)
|
col = QColor(r, g, b)
|
||||||
pal.setColor(pal.Base, col)
|
pal.setColor(pal.Base, col)
|
||||||
|
tex = gprefs['cover_grid_texture']
|
||||||
|
if tex:
|
||||||
|
from calibre.gui2.preferences.texture_chooser import texture_path
|
||||||
|
path = texture_path(tex)
|
||||||
|
if path:
|
||||||
|
pal.setBrush(pal.Base, QBrush(QPixmap(path)))
|
||||||
dark = (r + g + b)/3.0 < 128
|
dark = (r + g + b)/3.0 < 128
|
||||||
pal.setColor(pal.Text, QColor(Qt.white if dark else Qt.black))
|
pal.setColor(pal.Text, QColor(Qt.white if dark else Qt.black))
|
||||||
self.setPalette(pal)
|
self.setPalette(pal)
|
||||||
|
@ -8,13 +8,15 @@ __docformat__ = 'restructuredtext en'
|
|||||||
from threading import Thread
|
from threading import Thread
|
||||||
from functools import partial
|
from functools import partial
|
||||||
|
|
||||||
from PyQt4.Qt import (QApplication, QFont, QFontInfo, QFontDialog, QColorDialog,
|
from PyQt4.Qt import (
|
||||||
QAbstractListModel, Qt, QIcon, QKeySequence, QPalette, QColor, pyqtSignal)
|
QApplication, QFont, QFontInfo, QFontDialog, QColorDialog, QPainter,
|
||||||
|
QAbstractListModel, Qt, QIcon, QKeySequence, QColor, pyqtSignal,
|
||||||
|
QWidget, QSizePolicy, QBrush, QPixmap, QSize, QPushButton)
|
||||||
|
|
||||||
from calibre import human_readable
|
from calibre import human_readable
|
||||||
from calibre.gui2.preferences import ConfigWidgetBase, test_widget, CommaSeparatedList
|
from calibre.gui2.preferences import ConfigWidgetBase, test_widget, CommaSeparatedList
|
||||||
from calibre.gui2.preferences.look_feel_ui import Ui_Form
|
from calibre.gui2.preferences.look_feel_ui import Ui_Form
|
||||||
from calibre.gui2 import config, gprefs, qt_app, NONE, open_local_file
|
from calibre.gui2 import config, gprefs, qt_app, NONE, open_local_file, question_dialog
|
||||||
from calibre.utils.localization import (available_translations,
|
from calibre.utils.localization import (available_translations,
|
||||||
get_language, get_lang)
|
get_language, get_lang)
|
||||||
from calibre.utils.config import prefs
|
from calibre.utils.config import prefs
|
||||||
@ -98,6 +100,33 @@ class DisplayedFields(QAbstractListModel): # {{{
|
|||||||
|
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
|
class Background(QWidget): # {{{
|
||||||
|
|
||||||
|
def __init__(self, parent):
|
||||||
|
QWidget.__init__(self, parent)
|
||||||
|
self.bcol = QColor(*gprefs['cover_grid_color'])
|
||||||
|
self.btex = gprefs['cover_grid_texture']
|
||||||
|
self.update_brush()
|
||||||
|
self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
|
||||||
|
|
||||||
|
def update_brush(self):
|
||||||
|
self.brush = QBrush(self.bcol)
|
||||||
|
if self.btex:
|
||||||
|
from calibre.gui2.preferences.texture_chooser import texture_path
|
||||||
|
path = texture_path(self.btex)
|
||||||
|
if path:
|
||||||
|
self.brush.setTexture(QPixmap(path))
|
||||||
|
self.update()
|
||||||
|
|
||||||
|
def sizeHint(self):
|
||||||
|
return QSize(200, 120)
|
||||||
|
|
||||||
|
def paintEvent(self, ev):
|
||||||
|
painter = QPainter(self)
|
||||||
|
painter.fillRect(ev.rect(), self.brush)
|
||||||
|
painter.end()
|
||||||
|
# }}}
|
||||||
|
|
||||||
class ConfigWidget(ConfigWidgetBase, Ui_Form):
|
class ConfigWidget(ConfigWidgetBase, Ui_Form):
|
||||||
|
|
||||||
size_calculated = pyqtSignal(object)
|
size_calculated = pyqtSignal(object)
|
||||||
@ -209,10 +238,24 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
|
|||||||
keys = [unicode(x.toString(QKeySequence.NativeText)) for x in keys]
|
keys = [unicode(x.toString(QKeySequence.NativeText)) for x in keys]
|
||||||
self.fs_help_msg.setText(unicode(self.fs_help_msg.text())%(
|
self.fs_help_msg.setText(unicode(self.fs_help_msg.text())%(
|
||||||
_(' or ').join(keys)))
|
_(' or ').join(keys)))
|
||||||
self.cover_grid_color_button.clicked.connect(self.change_cover_grid_color)
|
|
||||||
self.cover_grid_default_color_button.clicked.connect(self.restore_cover_grid_color)
|
|
||||||
self.size_calculated.connect(self.update_cg_cache_size, type=Qt.QueuedConnection)
|
self.size_calculated.connect(self.update_cg_cache_size, type=Qt.QueuedConnection)
|
||||||
self.tabWidget.currentChanged.connect(self.tab_changed)
|
self.tabWidget.currentChanged.connect(self.tab_changed)
|
||||||
|
|
||||||
|
l = self.cg_background_box.layout()
|
||||||
|
self.cg_bg_widget = w = Background(self)
|
||||||
|
l.addWidget(w, 0, 0, 3, 1)
|
||||||
|
self.cover_grid_color_button = b = QPushButton(_('Change &color'), self)
|
||||||
|
b.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
|
||||||
|
l.addWidget(b, 0, 1)
|
||||||
|
b.clicked.connect(self.change_cover_grid_color)
|
||||||
|
self.cover_grid_texture_button = b = QPushButton(_('Change &background image'), self)
|
||||||
|
b.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
|
||||||
|
l.addWidget(b, 1, 1)
|
||||||
|
b.clicked.connect(self.change_cover_grid_texture)
|
||||||
|
self.cover_grid_default_appearance_button = b = QPushButton(_('Restore &default appearance'), self)
|
||||||
|
b.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
|
||||||
|
l.addWidget(b, 2, 1)
|
||||||
|
b.clicked.connect(self.restore_cover_grid_appearance)
|
||||||
self.cover_grid_empty_cache.clicked.connect(self.empty_cache)
|
self.cover_grid_empty_cache.clicked.connect(self.empty_cache)
|
||||||
self.cover_grid_open_cache.clicked.connect(self.open_cg_cache)
|
self.cover_grid_open_cache.clicked.connect(self.open_cg_cache)
|
||||||
self.cover_grid_smaller_cover.clicked.connect(partial(self.resize_cover, True))
|
self.cover_grid_smaller_cover.clicked.connect(partial(self.resize_cover, True))
|
||||||
@ -270,6 +313,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
|
|||||||
self.edit_rules.initialize(db.field_metadata, db.prefs, mi, 'column_color_rules')
|
self.edit_rules.initialize(db.field_metadata, db.prefs, mi, 'column_color_rules')
|
||||||
self.icon_rules.initialize(db.field_metadata, db.prefs, mi, 'column_icon_rules')
|
self.icon_rules.initialize(db.field_metadata, db.prefs, mi, 'column_icon_rules')
|
||||||
self.set_cg_color(gprefs['cover_grid_color'])
|
self.set_cg_color(gprefs['cover_grid_color'])
|
||||||
|
self.set_cg_texture(gprefs['cover_grid_texture'])
|
||||||
self.update_aspect_ratio()
|
self.update_aspect_ratio()
|
||||||
|
|
||||||
def open_cg_cache(self):
|
def open_cg_cache(self):
|
||||||
@ -292,9 +336,12 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
|
|||||||
self.size_calculated.emit(self.gui.grid_view.thumbnail_cache.current_size)
|
self.size_calculated.emit(self.gui.grid_view.thumbnail_cache.current_size)
|
||||||
|
|
||||||
def set_cg_color(self, val):
|
def set_cg_color(self, val):
|
||||||
pal = QPalette()
|
self.cg_bg_widget.bcol = QColor(*val)
|
||||||
pal.setColor(QPalette.Window, QColor(*val))
|
self.cg_bg_widget.update_brush()
|
||||||
self.cover_grid_color_label.setPalette(pal)
|
|
||||||
|
def set_cg_texture(self, val):
|
||||||
|
self.cg_bg_widget.btex = val
|
||||||
|
self.cg_bg_widget.update_brush()
|
||||||
|
|
||||||
def empty_cache(self):
|
def empty_cache(self):
|
||||||
self.gui.grid_view.thumbnail_cache.empty()
|
self.gui.grid_view.thumbnail_cache.empty()
|
||||||
@ -312,17 +359,32 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
|
|||||||
self.icon_rules.clear()
|
self.icon_rules.clear()
|
||||||
self.changed_signal.emit()
|
self.changed_signal.emit()
|
||||||
self.set_cg_color(gprefs.defaults['cover_grid_color'])
|
self.set_cg_color(gprefs.defaults['cover_grid_color'])
|
||||||
|
self.set_cg_texture(gprefs.defaults['cover_grid_texture'])
|
||||||
|
|
||||||
def change_cover_grid_color(self):
|
def change_cover_grid_color(self):
|
||||||
col = QColorDialog.getColor(self.cover_grid_color_label.palette().color(QPalette.Window),
|
col = QColorDialog.getColor(self.cg_bg_widget.bcol,
|
||||||
self.gui, _('Choose background color for cover grid'))
|
self.gui, _('Choose background color for cover grid'))
|
||||||
if col.isValid():
|
if col.isValid():
|
||||||
col = tuple(col.getRgb())[:3]
|
col = tuple(col.getRgb())[:3]
|
||||||
self.set_cg_color(col)
|
self.set_cg_color(col)
|
||||||
self.changed_signal.emit()
|
self.changed_signal.emit()
|
||||||
|
if self.cg_bg_widget.btex:
|
||||||
|
if question_dialog(
|
||||||
|
self, _('Remove background image?'),
|
||||||
|
_('There is currently a background image set, so the color'
|
||||||
|
' you have chosen will not be visible. Remove the background image?')):
|
||||||
|
self.set_cg_texture(None)
|
||||||
|
|
||||||
def restore_cover_grid_color(self):
|
def change_cover_grid_texture(self):
|
||||||
|
from calibre.gui2.preferences.texture_chooser import TextureChooser
|
||||||
|
d = TextureChooser(parent=self, initial=self.cg_bg_widget.btex)
|
||||||
|
if d.exec_() == d.Accepted:
|
||||||
|
self.set_cg_texture(d.texture)
|
||||||
|
self.changed_signal.emit()
|
||||||
|
|
||||||
|
def restore_cover_grid_appearance(self):
|
||||||
self.set_cg_color(gprefs.defaults['cover_grid_color'])
|
self.set_cg_color(gprefs.defaults['cover_grid_color'])
|
||||||
|
self.set_cg_texture(gprefs.defaults['cover_grid_texture'])
|
||||||
self.changed_signal.emit()
|
self.changed_signal.emit()
|
||||||
|
|
||||||
def build_font_obj(self):
|
def build_font_obj(self):
|
||||||
@ -383,7 +445,8 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
|
|||||||
self.display_model.commit()
|
self.display_model.commit()
|
||||||
self.edit_rules.commit(self.gui.current_db.prefs)
|
self.edit_rules.commit(self.gui.current_db.prefs)
|
||||||
self.icon_rules.commit(self.gui.current_db.prefs)
|
self.icon_rules.commit(self.gui.current_db.prefs)
|
||||||
gprefs['cover_grid_color'] = tuple(self.cover_grid_color_label.palette().color(QPalette.Window).getRgb())[:3]
|
gprefs['cover_grid_color'] = tuple(self.cg_bg_widget.bcol.getRgb())[:3]
|
||||||
|
gprefs['cover_grid_texture'] = self.cg_bg_widget.btex
|
||||||
return rr
|
return rr
|
||||||
|
|
||||||
def refresh_gui(self, gui):
|
def refresh_gui(self, gui):
|
||||||
|
@ -312,61 +312,12 @@
|
|||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
<widget class="QGroupBox" name="cg_background_box">
|
||||||
<item>
|
<property name="title">
|
||||||
<widget class="QLabel" name="label_14">
|
<string>Background for the cover grid</string>
|
||||||
<property name="text">
|
</property>
|
||||||
<string>Background color for the cover grid:</string>
|
<layout class="QGridLayout" name="gridLayout_5"/>
|
||||||
</property>
|
</widget>
|
||||||
<property name="buddy">
|
|
||||||
<cstring>cover_grid_color_button</cstring>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="cover_grid_color_label">
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>50</width>
|
|
||||||
<height>50</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="autoFillBackground">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="cover_grid_color_button">
|
|
||||||
<property name="text">
|
|
||||||
<string>Change &color</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="cover_grid_default_color_button">
|
|
||||||
<property name="text">
|
|
||||||
<string>Restore &default color</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<spacer name="horizontalSpacer_2">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>40</width>
|
|
||||||
<height>20</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="groupBox_4">
|
<widget class="QGroupBox" name="groupBox_4">
|
||||||
|
146
src/calibre/gui2/preferences/texture_chooser.py
Normal file
146
src/calibre/gui2/preferences/texture_chooser.py
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# vim:fileencoding=utf-8
|
||||||
|
from __future__ import (unicode_literals, division, absolute_import,
|
||||||
|
print_function)
|
||||||
|
|
||||||
|
__license__ = 'GPL v3'
|
||||||
|
__copyright__ = '2013, Kovid Goyal <kovid at kovidgoyal.net>'
|
||||||
|
|
||||||
|
import glob, os, string, shutil
|
||||||
|
from functools import partial
|
||||||
|
from PyQt4.Qt import (
|
||||||
|
QDialog, QVBoxLayout, QListWidget, QListWidgetItem, Qt, QIcon,
|
||||||
|
QApplication, QSize, QPixmap, QDialogButtonBox, QTimer)
|
||||||
|
|
||||||
|
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.QueuedConnection)
|
||||||
|
il.setIconSize(QSize(256, 256))
|
||||||
|
il.setViewMode(il.IconMode)
|
||||||
|
il.setFlow(il.LeftToRight)
|
||||||
|
il.setSpacing(20)
|
||||||
|
il.setSelectionMode(il.SingleSelection)
|
||||||
|
il.itemSelectionChanged.connect(self.update_remove_state)
|
||||||
|
l.addWidget(il)
|
||||||
|
|
||||||
|
self.bb = bb = QDialogButtonBox(QDialogButtonBox.Ok|QDialogButtonBox.Cancel)
|
||||||
|
bb.accepted.connect(self.accept)
|
||||||
|
bb.rejected.connect(self.reject)
|
||||||
|
b = self.add_button = bb.addButton(_('Add texture'), bb.ActionRole)
|
||||||
|
b.setIcon(QIcon(I('plus.png')))
|
||||||
|
b.clicked.connect(self.add_texture)
|
||||||
|
b = self.remove_button = bb.addButton(_('Remove texture'), bb.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(string.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']))
|
||||||
|
|
||||||
|
map(self.create_item, images)
|
||||||
|
self.update_remove_state()
|
||||||
|
|
||||||
|
if initial:
|
||||||
|
existing = {unicode(i.data(Qt.UserRole).toString()):i for i in (self.images.item(c) for c in xrange(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(QPixmap(x['path']).scaled(256, 256, transformMode=Qt.SmoothTransformation)), x['name'], self.images)
|
||||||
|
i.setData(Qt.UserRole, x['fname'])
|
||||||
|
i.setData(Qt.UserRole+1, x['path'])
|
||||||
|
return i
|
||||||
|
|
||||||
|
def update_remove_state(self):
|
||||||
|
removeable = bool(self.selected_fname and not self.selected_fname.startswith(':'))
|
||||||
|
self.remove_button.setEnabled(removeable)
|
||||||
|
|
||||||
|
@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 = {unicode(i.data(Qt.UserRole).toString()):i for i in (self.images.item(c) for c in xrange(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 unicode(self.selected_item.data(Qt.UserRole).toString())
|
||||||
|
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 remover builtin textures'), show=True)
|
||||||
|
self.images.takeItem(self.images.row(self.selected_item))
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
app = QApplication([]) # noqa
|
||||||
|
d = TextureChooser()
|
||||||
|
d.exec_()
|
||||||
|
print (d.texture)
|
Loading…
x
Reference in New Issue
Block a user