def __init__(self, wallpaper): QObject.__init__(self, wallpaper) self.cache = {} self.wallpaper = wallpaper self.rendering = 0 self._size = None self.currentPixmap = None self.currentPixmapId = -1 self.dirtyTimer = QTimer(self) self.dirtyTimer.setInterval(0) self.dirtyTimer.setSingleShot(True) self.connect(self.dirtyTimer, SIGNAL('timeout()'), self.checkDirtyImages) self.renderer = WallpaperRenderer(self) self.connect(self.renderer, SIGNAL('renderCompleted(int, const QImage&)'), \ self.renderCompleted, Qt.QueuedConnection)
class WallpaperCache(QObject): All = -sys.maxint - 1 # id Operation, Dirty, Image, Color, Method, Data = range(6) # id properties SingleImage, Blend, Stack, Manual = range(4) # operations OperationId = 0 Images = 1 # SingleImage operation Images, Amount = range(1, 3) # Blend operation Images = 1 # Stack operation ImageOperations = [Blend, Stack] TypesThatCauseDirtines = [Operation, Color, Method] def __init__(self, wallpaper): QObject.__init__(self, wallpaper) self.cache = {} self.wallpaper = wallpaper self.rendering = 0 self._size = None self.currentPixmap = None self.currentPixmapId = -1 self.dirtyTimer = QTimer(self) self.dirtyTimer.setInterval(0) self.dirtyTimer.setSingleShot(True) self.connect(self.dirtyTimer, SIGNAL('timeout()'), self.checkDirtyImages) self.renderer = WallpaperRenderer(self) self.connect(self.renderer, SIGNAL('renderCompleted(int, const QImage&)'), \ self.renderCompleted, Qt.QueuedConnection) def checkId(self, id): if id not in self.cache.keys(): self.cache[id] = [[self.Manual], True, None, Qt.black, \ Plasma.Wallpaper.ScaledResize, None] return False return True def initId(self, id, operation, color = Qt.black, \ method = Plasma.Wallpaper.ScaledResize, data = None): self.checkId(id) self.cache[id][self.Operation] = operation self.cache[id][self.Color] = color self.cache[id][self.Method] = method self.cache[id][self.Dirty] = False self.cache[id][self.Data] = data self.cache[id][self.Image] = None def value(self, id, type): self.checkId(id) return self.cache[id][type] def setValue(self, ids, type, value): #if isinstance(ids, int) and ids != self.All: # print '### setValue', ids, type, value, self.cache[ids][type] if isinstance(ids, int): if ids != self.All: self.checkId(ids) if self.cache[ids][type] != value: self.cache[ids][type] = value if type in self.TypesThatCauseDirtines: self.setDirty(ids) return True return False else: ids = self.cache.keys() r = False for id in ids: r |= self.setValue(id, type, value) return r def dirty(self, id): return self.value(id, self.Dirty) def setDirty(self, id, dirty = True): #print '### setDirty', id, dirty r = self.setValue(id, self.Dirty, dirty) if dirty: for key in self.cache.keys(): if self.operationParam(key, self.OperationId) in self.ImageOperations and \ id in self.operationParam(key, self.Images): #print ' ### And setDirty', key self.setDirty(key) self.dirtyTimer.start() return r def data(self, id): return self.value(id, self.Data) def setData(self, id, data): return self.setValue(id, self.Data, data) def color(self, id): return self.value(id, self.Color) def setColor(self, id, color): return self.setValue(id, self.Color, color) def method(self, id): return self.value(id, self.Method) def setMethod(self, id, method): return self.setValue(id, self.Method, method) def pixmap(self, id): #print '### pixmap', self.currentPixmapId, id if self.currentPixmapId != id: img = self.image(id) if img: self.currentPixmapId = id self.currentPixmap = QPixmap(img) else: if self.operationParam(id, self.OperationId) != self.Manual: self.setDirty(id) return self.currentPixmap def image(self, id): image = self.value(id, self.Image) return image def setImage(self, id, image): #print '### setImage', id, self.currentPixmapId, self._size if id == self.currentPixmapId: self.currentPixmapId = -1 self.setDirty(id, False) return self.setValue(id, self.Image, image) def operation(self, id): return self.value(id, self.Operation) def setOperation(self, id, operation): return self.setValue(id, self.Operation, operation) def operationParam(self, id, param): self.checkId(id) return self.value(id, self.Operation)[param] def setOperationParam(self, id, param, value): #print '### setOperationParam', id if isinstance(id, int): ids = [id] else: ids = id r = False for i in ids: v = copy(self.value(i, self.Operation)) v[param] = value r |= self.setValue(id, self.Operation, v) return r def size(self): return self._size def ratio(self): if self._size == None or self._size.isEmpty() or self._size.height() == 0: return 1.0 else: return self._size.width() / float(self._size.height()) def checkGeometry(self): #print '### checkGeometry', self._size, self.wallpaper.boundingRect().size().toSize() if self._size != self.wallpaper.boundingRect().size().toSize(): self._size = self.wallpaper.boundingRect().size().toSize() self.setDirty(self.All) return True return False def init(self): #print '### init' self.currentPixmapId = -1 self.checkGeometry() def checkImages(self, ids): for id in ids: if self.image(id) == None or self.dirty(id): #print ' ### dirty', id return False return True def _img(self, img): if isinstance(img, int): if self.image(img) == None or self.dirty(img): return self._job(img) else: return self.image(img) if isinstance(img, QImage): return img if os.path.isdir(img): package = Plasma.Package(img, \ self.wallpaper.packageStructure(self.wallpaper.wallpaper)) img = package.filePath('preferred') return U(img) def _job(self, cacheId): operation = self.cache[cacheId][self.Operation] operationId = operation[self.OperationId] if operation[self.OperationId] == self.SingleImage: job = SingleImageJob(cacheId, self._size, self._img(operation[self.Images]), \ QColor(self.color(cacheId)), self.method(cacheId)) elif operation[self.OperationId] == self.Blend: job = BlendJob(cacheId, self._size, self._img(operation[self.Images][0]), \ self._img(operation[self.Images][1]), operation[self.Amount], QColor(self.color(cacheId)), self.method(cacheId)) elif operation[self.OperationId] == self.Stack: job = StackJob(cacheId, self._size, [self._img(x) for x in operation[self.Images]], \ QColor(self.color(cacheId)), self.method(cacheId)) else: job = DummyJob(cacheId, self._size) self.setDirty(cacheId, False) self.rendering += 1 #print '++++++++++++++++', self.rendering return job def doJob(self, cacheId): self.renderer.render(self._job(cacheId)) def renderCompleted(self, jobId, image): #print '### renderCompleted', jobId, self.rendering, self.dirty(jobId), image.size() #image.save('/home/damu/test%d.png' % jobId) if image.isNull(): image = None if not self.dirty(jobId): self.setImage(jobId, image) self.rendering -= 1 #print '----------------', self.rendering self.dirtyTimer.start() def checkDirtyImages(self): #print '### checkDirtyImages', self.rendering if self.rendering > 0: return if self._size == None: return for id in self.cache.keys(): #print '### ID', id, self.dirty(id) if self.dirty(id): self.doJob(id) #print ' ### Waiting... ', id, self.dirty(id) return self.dirtyTimer.stop() #print '### renderingsCompleted' self.emit(SIGNAL('renderingsCompleted()'))