1""" 2Preview item model. 3""" 4import os 5import logging 6 7from AnyQt.QtGui import ( 8 QStandardItemModel, QStandardItem, QIcon 9) 10from AnyQt.QtCore import Qt, QTimer 11from AnyQt.QtCore import pyqtSlot as Slot 12 13from ..gui.svgiconengine import SvgIconEngine 14from . import scanner 15 16 17log = logging.getLogger(__name__) 18 19# Preview Data Roles 20#################### 21 22# Name of the item, (same as `Qt.DisplayRole`) 23NameRole = Qt.DisplayRole 24 25# Items description (items long description) 26DescriptionRole = Qt.UserRole + 1 27 28# Items url/path (where previewed resource is located). 29PathRole = Qt.UserRole + 2 30 31# Items preview SVG contents string 32ThumbnailSVGRole = Qt.UserRole + 3 33 34 35UNKNOWN_SVG = \ 36"""<?xml version="1.0" encoding="UTF-8" standalone="no"?> 37<svg width="161.8mm" height="100.0mm" 38 xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" 39 version="1.2" baseProfile="tiny"> 40</svg> 41""" 42 43 44class PreviewModel(QStandardItemModel): 45 """A model for preview items. 46 """ 47 48 def __init__(self, parent=None, items=None): 49 super().__init__(parent) 50 self.__preview_index = -1 51 if items is not None: 52 self.insertColumn(0, items) 53 54 self.__timer = QTimer(self) 55 self.__timer.timeout.connect(self.__process_next) 56 57 def delayedScanUpdate(self, delay=10): 58 """Run a delayed preview item scan update. 59 """ 60 self.__preview_index = -1 61 self.__timer.start(delay) 62 log.debug("delayedScanUpdate: Start") 63 64 @Slot() 65 def __process_next(self): 66 index = self.__preview_index 67 log.debug("delayedScanUpdate: Next %i", index + 1) 68 if not 0 <= index + 1 < self.rowCount(): 69 self.__timer.stop() 70 log.debug("delayedScanUpdate: Stop") 71 return 72 73 self.__preview_index = index = index + 1 74 75 assert 0 <= index < self.rowCount() 76 item = self.item(index) 77 if os.path.isfile(item.path()): 78 try: 79 scanner.scan_update(item) 80 except Exception: 81 log.error("An unexpected error occurred while " 82 "scanning '%s'.", item.text(), exc_info=True) 83 item.setEnabled(False) 84 85 86class PreviewItem(QStandardItem): 87 """A preview item. 88 """ 89 def __init__(self, name=None, description=None, thumbnail=None, 90 icon=None, path=None): 91 super().__init__() 92 93 self.__name = "" 94 95 if name is None: 96 name = "Untitled" 97 98 self.setName(name) 99 100 if description is None: 101 description = "No description." 102 self.setDescription(description) 103 104 if thumbnail is None: 105 thumbnail = UNKNOWN_SVG 106 self.setThumbnail(thumbnail) 107 108 if icon is not None: 109 self.setIcon(icon) 110 111 if path is not None: 112 self.setPath(path) 113 114 def name(self): 115 """Return the name (title) of the item (same as `text()`. 116 """ 117 return self.__name 118 119 def setName(self, value): 120 """Set the item name. `value` if not empty will be used as 121 the items DisplayRole otherwise an 'untitled' placeholder will 122 be used. 123 124 """ 125 self.__name = value 126 127 if not value: 128 self.setText("untitled") 129 else: 130 self.setText(value) 131 132 def description(self): 133 """Return the detailed description for the item. 134 135 This is stored as `DescriptionRole`, if no data is set then 136 return the string for `WhatsThisRole`. 137 138 """ 139 desc = self.data(DescriptionRole) 140 141 if desc is not None: 142 return str(desc) 143 144 whatsthis = self.data(Qt.WhatsThisRole) 145 if whatsthis is not None: 146 return str(whatsthis) 147 else: 148 return "" 149 150 def setDescription(self, description): 151 self.setData(description, DescriptionRole) 152 self.setWhatsThis(description) 153 154 def thumbnail(self): 155 """Return the thumbnail SVG string for the preview item. 156 157 This is stored as `ThumbnailSVGRole` 158 """ 159 thumb = self.data(ThumbnailSVGRole) 160 if thumb is not None: 161 return str(thumb) 162 else: 163 return "" 164 165 def setThumbnail(self, thumbnail): 166 """Set the thumbnail SVG contents as a string. 167 168 When set it also overrides the icon role. 169 170 """ 171 self.setData(thumbnail, ThumbnailSVGRole) 172 engine = SvgIconEngine(thumbnail.encode("utf-8")) 173 self.setIcon(QIcon(engine)) 174 175 def path(self): 176 """Return the path item data. 177 """ 178 return str(self.data(PathRole)) 179 180 def setPath(self, path): 181 """Set the path data of the item. 182 183 .. note:: This also sets the Qt.StatusTipRole 184 185 """ 186 self.setData(path, PathRole) 187 self.setStatusTip(path) 188 self.setToolTip(path) 189