def __init__(self, parent, logger, smoothScaling, minOpacity, maxOpacity): super(RemotePicturesGui, self).__init__(parent) self.logger = logger self.good = True self.settings = None self.categoryPictures = {} self.currentCategory = None self.curPicIndex = 0 self.categoryModel = CategoriesModel(logger) self.sortProxy = None self.categoryView = QListView(self) self.categoryView.setViewMode(QListView.IconMode); self.categoryView.setIconSize(QSize(200,200)); self.categoryView.setResizeMode(QListView.Adjust); self.categoryView.doubleClicked.connect(self._itemDoubleClicked) self.categoryView.setFrameShape(QFrame.NoFrame) self.sortProxy = QSortFilterProxyModel(self) self.sortProxy.setSortCaseSensitivity(Qt.CaseInsensitive) self.sortProxy.setSortRole(CategoriesModel.SORT_ROLE) self.sortProxy.setDynamicSortFilter(True) self.sortProxy.setSourceModel(self.categoryModel) self.sortProxy.sort(0) self.categoryView.setModel(self.sortProxy) self.addWidget(self.categoryView) self.imageLabel = ResizingWebImageLabel(self, self.logger, smooth_scaling=smoothScaling) self.imageLabel.imageDownloaded.connect(self.pictureDownloadedSlot) self.imageLabel.setContextMenuPolicy(Qt.CustomContextMenu) self.imageLabel.customContextMenuRequested.connect(self._showImageContextMenu) imageViewerLayout = QVBoxLayout(self.imageLabel) imageViewerLayout.setContentsMargins(0, 0, 0, 0) imageViewerLayout.setSpacing(0) defaultFont = self.font() self.categoryLabel = HiddenLabel(self.imageLabel, self.logger, fontSize=16, fontOptions=QFont.Bold) topLayout = QHBoxLayout(self.categoryLabel) topLayout.setContentsMargins(0, 0, 0, 0) backButton = QToolButton(self.categoryLabel) backButton.setFont(QFont(defaultFont.family(), defaultFont.pointSize(), 0)) backButton.setFocusPolicy(Qt.NoFocus) backButton.setArrowType(Qt.LeftArrow) backButton.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) backButton.setText("Categories") topLayout.addWidget(backButton, 0, Qt.AlignLeft) imageViewerLayout.addWidget(self.categoryLabel, 0) navButtonsWidget = QWidget(self.imageLabel) navButtonsLayout = QHBoxLayout(navButtonsWidget) navButtonsLayout.setContentsMargins(0, 0, 0, 0) self.prevButton = HiddenToolButton(self.imageLabel, self.logger) self.prevButton.setArrowType(Qt.LeftArrow) self.prevButton.setEnabled(False) self.prevButton.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.MinimumExpanding) navButtonsLayout.addWidget(self.prevButton, 0, Qt.AlignLeft) self.nextButton = HiddenToolButton(self.imageLabel, self.logger) self.nextButton.setArrowType(Qt.RightArrow) self.nextButton.setEnabled(False) self.nextButton.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.MinimumExpanding) navButtonsLayout.addWidget(self.nextButton, 0, Qt.AlignRight) imageViewerLayout.addWidget(navButtonsWidget, 1) self.descriptionLabel = HiddenLabel(self.imageLabel, self.logger, fontSize=14) self.descriptionLabel.setWordWrap(True) imageViewerLayout.addWidget(self.descriptionLabel, 0) self.addWidget(self.imageLabel) self.nextButton.clicked.connect(self._displayNextImage) self.prevButton.clicked.connect(self._displayPreviousImage) backButton.clicked.connect(partial(self.setCurrentIndex, 0)) self._initializeHiddenWidget(self.categoryLabel) self._initializeHiddenWidget(self.prevButton) self._initializeHiddenWidget(self.nextButton) self._initializeHiddenWidget(self.descriptionLabel) self.minOpacityChanged.emit(float(minOpacity) / 100.) self.maxOpacityChanged.emit(float(maxOpacity) / 100.)
class RemotePicturesGui(QStackedWidget): openCategory = pyqtSignal(object) # category displayNext = pyqtSignal(object, int) # current category, current ID displayPrev = pyqtSignal(object, int) # current category, current ID pictureDownloaded = pyqtSignal(object, object, object) # current category, url, pic data minOpacityChanged = pyqtSignal(float) maxOpacityChanged = pyqtSignal(float) setCategoryThumbnail = pyqtSignal(object, QImage) # category, thumbnail pixmap _categoryOpened = pyqtSignal() # used to flash hidden widgets def __init__(self, parent, logger, smoothScaling, minOpacity, maxOpacity): super(RemotePicturesGui, self).__init__(parent) self.logger = logger self.good = True self.settings = None self.categoryPictures = {} self.currentCategory = None self.curPicIndex = 0 self.categoryModel = CategoriesModel(logger) self.sortProxy = None self.categoryView = QListView(self) self.categoryView.setViewMode(QListView.IconMode); self.categoryView.setIconSize(QSize(200,200)); self.categoryView.setResizeMode(QListView.Adjust); self.categoryView.doubleClicked.connect(self._itemDoubleClicked) self.categoryView.setFrameShape(QFrame.NoFrame) self.sortProxy = QSortFilterProxyModel(self) self.sortProxy.setSortCaseSensitivity(Qt.CaseInsensitive) self.sortProxy.setSortRole(CategoriesModel.SORT_ROLE) self.sortProxy.setDynamicSortFilter(True) self.sortProxy.setSourceModel(self.categoryModel) self.sortProxy.sort(0) self.categoryView.setModel(self.sortProxy) self.addWidget(self.categoryView) self.imageLabel = ResizingWebImageLabel(self, self.logger, smooth_scaling=smoothScaling) self.imageLabel.imageDownloaded.connect(self.pictureDownloadedSlot) self.imageLabel.setContextMenuPolicy(Qt.CustomContextMenu) self.imageLabel.customContextMenuRequested.connect(self._showImageContextMenu) imageViewerLayout = QVBoxLayout(self.imageLabel) imageViewerLayout.setContentsMargins(0, 0, 0, 0) imageViewerLayout.setSpacing(0) defaultFont = self.font() self.categoryLabel = HiddenLabel(self.imageLabel, self.logger, fontSize=16, fontOptions=QFont.Bold) topLayout = QHBoxLayout(self.categoryLabel) topLayout.setContentsMargins(0, 0, 0, 0) backButton = QToolButton(self.categoryLabel) backButton.setFont(QFont(defaultFont.family(), defaultFont.pointSize(), 0)) backButton.setFocusPolicy(Qt.NoFocus) backButton.setArrowType(Qt.LeftArrow) backButton.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) backButton.setText("Categories") topLayout.addWidget(backButton, 0, Qt.AlignLeft) imageViewerLayout.addWidget(self.categoryLabel, 0) navButtonsWidget = QWidget(self.imageLabel) navButtonsLayout = QHBoxLayout(navButtonsWidget) navButtonsLayout.setContentsMargins(0, 0, 0, 0) self.prevButton = HiddenToolButton(self.imageLabel, self.logger) self.prevButton.setArrowType(Qt.LeftArrow) self.prevButton.setEnabled(False) self.prevButton.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.MinimumExpanding) navButtonsLayout.addWidget(self.prevButton, 0, Qt.AlignLeft) self.nextButton = HiddenToolButton(self.imageLabel, self.logger) self.nextButton.setArrowType(Qt.RightArrow) self.nextButton.setEnabled(False) self.nextButton.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.MinimumExpanding) navButtonsLayout.addWidget(self.nextButton, 0, Qt.AlignRight) imageViewerLayout.addWidget(navButtonsWidget, 1) self.descriptionLabel = HiddenLabel(self.imageLabel, self.logger, fontSize=14) self.descriptionLabel.setWordWrap(True) imageViewerLayout.addWidget(self.descriptionLabel, 0) self.addWidget(self.imageLabel) self.nextButton.clicked.connect(self._displayNextImage) self.prevButton.clicked.connect(self._displayPreviousImage) backButton.clicked.connect(partial(self.setCurrentIndex, 0)) self._initializeHiddenWidget(self.categoryLabel) self._initializeHiddenWidget(self.prevButton) self._initializeHiddenWidget(self.nextButton) self._initializeHiddenWidget(self.descriptionLabel) self.minOpacityChanged.emit(float(minOpacity) / 100.) self.maxOpacityChanged.emit(float(maxOpacity) / 100.) def getCategoryIcon(self, cat): return self.categoryModel.getCategoryIcon(cat) @loggingSlot(QPoint) def _showImageContextMenu(self, _point): pixmap = self.imageLabel.getRawPixmap() if pixmap is None or pixmap.isNull(): return m = QMenu() m.addAction(u"Set as category thumbnail", self._setCurrentPictureAsThumbnail) m.exec_(QCursor.pos()) m.deleteLater() @loggingSlot() def _setCurrentPictureAsThumbnail(self): if self.currentCategory is None: self.logger.error("Current category is None") return pixmap = self.imageLabel.getRawPixmap() if pixmap is None or pixmap.isNull(): self.logger.warning("NULL pixmap") return image = pixmap.toImage() if image.isNull(): self.logger.error("Error converting pixmap to image") return self.setCategoryThumbnail.emit(self.currentCategory, image) def _initializeHiddenWidget(self, w): self._categoryOpened.connect(w.showTemporarily) self.minOpacityChanged.connect(w.setMinOpacity) self.maxOpacityChanged.connect(w.setMaxOpacity) @loggingSlot(QModelIndex) def _itemDoubleClicked(self, index): index = self.sortProxy.mapToSource(index) item = self.categoryModel.item(index.row()) cat = item.data(CategoriesModel.CAT_ROLE).toString() self.openCategory.emit(cat) def _deactivateButtons(self): self.nextButton.setEnabled(False) self.prevButton.setEnabled(False) @loggingSlot() def _displayNextImage(self): self._deactivateButtons() self.displayNext.emit(self.currentCategory, self.curPicIndex) @loggingSlot() def _displayPreviousImage(self): self._deactivateButtons() self.displayPrev.emit(self.currentCategory, self.curPicIndex) @loggingSlot(object, int, list, bool, bool) def displayImage(self, cat, picID, picRow, hasPrev, hasNext): cat = convert_string(cat) picURL = convert_string(picRow[RemotePicturesStorage.PIC_URL_COL]) picFile = convert_string(picRow[RemotePicturesStorage.PIC_FILE_COL]) picDesc = convert_string(picRow[RemotePicturesStorage.PIC_DESC_COL]) if picDesc is None: picDesc = u"" picSender = convert_string(picRow[RemotePicturesStorage.PIC_SENDER_COL]) picTime = picRow[RemotePicturesStorage.PIC_ADDED_COL] self.currentCategory = cat self.categoryLabel.setText(cat) self.curPicIndex = picID if picFile and os.path.exists(picFile): self.imageLabel.setImage(picFile) elif picURL: self.imageLabel.setURL(picURL) else: self.logger.warning("No image source specified") self.imageLabel.displayFallbackPic() if picSender: self.imageLabel.setToolTip(u"Sent to you by %s,\nSent %s" % (get_peers().getDisplayedPeerName(pID=picSender), formatTime(localtime(picTime)))) else: self.imageLabel.setToolTip(u"") self.descriptionLabel.setText(picDesc) self.setCurrentIndex(1) self.prevButton.setEnabled(hasPrev) self.nextButton.setEnabled(hasNext) self._categoryOpened.emit() def thumbnailSizeChanged(self, newValue): self.categoryModel.thumbnailSizeChanged(newValue) def setSmoothScaling(self, newValue): self.imageLabel.setSmoothScaling(newValue) def isShowingCategory(self, category): return self.currentIndex() == 1 and category == self.currentCategory def destroyWidget(self): pass @loggingSlot(object, object) def pictureDownloadedSlot(self, url, picData): if self.currentCategory is not None: self.pictureDownloaded.emit(self.currentCategory, url, picData)