def __adjustText(self): """ 根据文本长度决定是否显示省略号 """ fontMetrics_1 = QFontMetrics(QFont('Microsoft YaHei', 17, 63)) self.songName = fontMetrics_1.elidedText(self.songName, Qt.ElideRight, 285) fontMetrics_2 = QFontMetrics(QFont('Microsoft YaHei', 9)) self.songerName = fontMetrics_2.elidedText(self.songerName, Qt.ElideRight, 290)
def setText(self): name_label = self.layout().itemAt(0).widget() content_label = self.layout().itemAt(1).widget() metrics = QFontMetrics(name_label.font()) elided_name = metrics.elidedText(self.note.name, Qt.ElideRight, self.width()) name_label.setText(elided_name) elided_content = metrics.elidedText(self.note.content, Qt.ElideRight, self.width()) content_label.setText(elided_content)
def __setLabelText(self): """设置用户名和个新签名标签的文字并根据字符串长短来添加省略号 """ # 调整个新签名 fontMetrics = QFontMetrics(QFont('Microsoft YaHei', 8)) newText = fontMetrics.elidedText(self.userInfo['personalSignature'], Qt.ElideRight, 250) self.personalSignatureLabel.setText(newText) self.personalSignatureLabel.adjustSize() # 调整用户名 newText = fontMetrics.elidedText(self.userInfo['userName'], Qt.ElideRight, 260) self.userNameLabel.setText(newText) self.userNameLabel.adjustSize()
def __setMessageText(self): """根据消息长短来添加省略号 """ # 调整消息 fontMetrics = QFontMetrics(QFont('Microsoft YaHei', 11)) newText = fontMetrics.elidedText(self.messageInfo['message'], Qt.ElideRight, 255) self.messageLabel.setText(newText) self.messageLabel.adjustSize() # 调整用户名 fontMetrics = QFontMetrics(QFont('Microsoft YaHei', 10)) newText = fontMetrics.elidedText(self.messageInfo['contactName'], Qt.ElideRight, 240) self.contactNameLabel.setText(newText) self.contactNameLabel.adjustSize()
def __adjustLabelText(self): """ 调整歌手名和年份流派标签长度和文本 """ maxWidth = self.width() - 40 - 294 fontMetrics = QFontMetrics(QFont('Microsoft YaHei', 9)) songerWidth = fontMetrics.width(self.songerName) yearTconWidth = fontMetrics.width(self.yearTconLabel.text()) self.songerNameLabel.setFixedWidth(min(maxWidth, songerWidth)) self.yearTconLabel.setFixedWidth(min(maxWidth, yearTconWidth)) # 加省略号 self.songerNameLabel.setText( fontMetrics.elidedText(self.songerName, Qt.ElideRight, maxWidth)) self.yearTconLabel.setText( fontMetrics.elidedText(self.yearTconLabel.text(), Qt.ElideRight, maxWidth))
class ElidingLabel(QtWidgets.QLabel): """A QLabel which elides text with an ellipsis if it is too long.""" def __init__(self, text="", prefix="", suffix="", elide=Qt.ElideRight, parent=None): super().__init__(text, parent) self._full_text = text self._prefix = prefix # those can be used for "<span></span>" self._suffix = suffix # because they are not elided! self._elide = elide self._font_metrics = QFontMetrics(self.font()) self.setText(text) def setText(self, text): self._full_text = text s = self._font_metrics.elidedText(text, self._elide, self.width()) if s != text: # Show tooltip. # TODO: linebreaks!!!!!!! self.setToolTip(text) else: self.setToolTip("") super().setText(self._prefix + s + self._suffix) def text(self): return self._full_text def resizeEvent(self, event): # Re-calculate elision. self.setText(self._full_text)
def paintEvent(self, event): painter = QPainter(self) metrics = QFontMetrics(self.font()) elided = metrics.elidedText(self.text(), Qt.ElideMiddle, self.width()) painter.drawText(self.rect(), self.alignment(), elided)
def resizeEvent(self, event): if not self._text: self._text = self.text() metrics = QFontMetrics(self.font()) elidedText = metrics.elidedText(self._text, Qt.ElideRight, self.width()) self.setElidedText(elidedText)
def __adjustLabelPos(self): """ 根据专辑名是否换行来调整标签位置 """ maxWidth = self.width() - 40 - 385 # 设置专辑名歌手名标签的长度 fontMetrics = QFontMetrics(QFont('Microsoft YaHei', 24, 63)) albumLabelWidth = sum([fontMetrics.width(i) for i in self.albumName]) self.albumNameLabel.setFixedWidth(min(maxWidth, albumLabelWidth)) newAlbumName_list = list(self.albumName) # type:list totalWidth = 0 isWrap = False for i in range(len(self.albumName)): totalWidth += fontMetrics.width(self.albumName[i]) if totalWidth > maxWidth: newAlbumName_list.insert(i, '\n') isWrap = True break if isWrap: index = newAlbumName_list.index('\n') # 再次根据换行后的长度决定是否使用省略号 newAlbumName = ''.join(newAlbumName_list) secondLineText = fontMetrics.elidedText(newAlbumName[index + 1:], Qt.ElideRight, maxWidth) newAlbumName = newAlbumName[:index + 1] + secondLineText self.albumNameLabel.setText(newAlbumName) self.albumNameLabel.setFixedSize(maxWidth, 110) self.songerNameLabel.move(self.albumNameLabel.x(), 155) self.yearTconLabel.move(self.albumNameLabel.x(), 177) else: self.albumNameLabel.setText(self.albumName) self.albumNameLabel.setFixedSize(totalWidth, 54) self.songerNameLabel.move(self.albumNameLabel.x(), 93) self.yearTconLabel.move(self.albumNameLabel.x(), 115)
def __adjustTitle(self): """ 调整标题标签 """ fontMetrics = QFontMetrics(QFont('Microsoft YaHei', 19, 75)) newText = fontMetrics.elidedText(self.contactName, Qt.ElideRight, self.width() - 240) self.contactNamesLabel.setText(newText) self.contactNamesLabel.adjustSize()
def text_omit(text: str, width: int) -> str: font = QFontMetrics(QFont(text)) font_size = font.width(text) resize_width = width if font_size > resize_width: text = font.elidedText(text, Qt.ElideRight, width) return text
def paintEvent(self, event): """QLineEdit.paintEvent implementation. Draws prompt """ QLineEdit.paintEvent(self, event) if self._promptText and not self.text() and self.isEnabled(): option = QStyleOptionFrameV3() self.initStyleOption(option) left, top, right, bottom = self.getTextMargins() va = self.style().visualAlignment(self.layoutDirection(), self.alignment()) rect = ( self.style() .subElementRect(QStyle.SE_LineEditContents, option, self) .adjusted(2, 0, 0, 0) .adjusted(left, top, -right, -bottom) ) fm = QFontMetrics(self.font()) text = fm.elidedText(self._promptText, Qt.ElideRight, rect.width()) painter = QPainter(self) painter.setPen(self.palette().color(QPalette.Disabled, QPalette.Text)) painter.drawText(rect, va, text)
def set_data(self, item, already_downloaded): for key in self.data_labels: label = self.root.findChild(QLabel, self.object_name_scope + key) text = str(item.get(key)) if key == 'size': text = str_filesize(text) text = text or 'unknown' if key not in self.except_elided: metrics = QFontMetrics(label.font()) text = metrics.elidedText(text, Qt.ElideRight, label.width() - 2) label.setText(text) self.id = item.get('id') self.progressbar = self.root.findChild( QProgressBar, self.object_name_scope + 'progress') self.progressbar.hide() self.download_button = self.root.findChild( QPushButton, self.object_name_scope + 'download') self.download_button.clicked.connect(self.download) self.download_button.setText('Download') self.enabled = not already_downloaded self.download_button.setEnabled(not already_downloaded) if already_downloaded: self.download_finished()
def paintEvent(self, event): maxWidth = self.maxWidth if self.maxWidth is not None else self.width() painter = QPainter(self) metrics = QFontMetrics(self.font()) elided = metrics.elidedText(self.text(), Qt.ElideRight, maxWidth) painter.drawText(self.rect(), self.alignment(), elided)
def started(self, title): self.lblState.setStyleSheet('color: #090') self.lblState.setText('Downloading...') self.btnStop.setEnabled(True) fm = QFontMetrics(self.lblTitle.font()) width = self.lblTitle.width() self.lblTitle.setText(fm.elidedText(title, Qt.ElideRight, width))
def labelResize(self, label, event, text): """ Change label's text due to its size. """ width = self.taskArea.width() - 320 # if get width from event: width = event.size().width() # resizing will stop when full text is shown in label metrics = QFontMetrics(label.font()) ellipsis = metrics.elidedText(text, Qt.ElideRight, width) label.setText(ellipsis)
def resizeEvent(self, event=None): # 判断是否文字过长,过长则显示省略号 self.setText(self.dsp_text) fontwidth = QFontMetrics(self.font()) text_width = fontwidth.width(self.dsp_text) # 文字长度 widget_width = self.size().width() # 控件长度 if text_width >= widget_width: self.setText( fontwidth.elidedText(self.dsp_text, Qt.ElideRight, widget_width))
def updateText(self): texts = [] for i in range(self.model().rowCount()): if self.model().item(i).checkState() == Qt.Checked: texts.append(self.model().item(i).text()) text = " " + ", ".join(texts) # Compute elided text (with "...") metrics = QFontMetrics(self.lineEdit().font()) elidedText = metrics.elidedText(text, Qt.ElideRight, self.lineEdit().width()) self.lineEdit().setText(elidedText)
def drawCellHeaderText(self, painter, rect): xMin, yMin, width, height = rect metrics = QFontMetrics(headerFont) minOffset = painter.pen().width() painter.setFont(headerFont) painter.setPen(QColor(80, 80, 80)) name = metrics.elidedText(self.glyph.name, Qt.ElideRight, width - 2) painter.drawText(1, 0, width - 2, height - minOffset, Qt.TextSingleLine | Qt.AlignCenter | Qt.AlignBottom, name)
def __adjustLabel(self): """ 根据专辑名的长度决定是否换行和添加省略号 """ newText, isWordWrap = autoWrap(self.albumNameLabel.text(), 22) if isWordWrap: # 添加省略号 index = newText.index('\n') fontMetrics = QFontMetrics(QFont('Microsoft YaHei', 10, 75)) secondLineText = fontMetrics.elidedText(newText[index + 1:], Qt.ElideRight, 200) newText = newText[:index + 1] + secondLineText self.albumNameLabel.setText(newText) # 给歌手名添加省略号 fontMetrics = QFontMetrics(QFont('Microsoft YaHei', 10, 25)) newSongerName = fontMetrics.elidedText(self.songerNameLabel.text(), Qt.ElideRight, 200) self.songerNameLabel.setText(newSongerName) self.songerNameLabel.adjustSize() self.albumNameLabel.adjustSize() self.songerNameLabel.move( 5, self.albumNameLabel.y() + self.albumNameLabel.height() - 4)
def drawCellHeaderText(self, painter, rect): xMin, yMin, width, height = rect metrics = QFontMetrics(headerFont) minOffset = painter.pen().width() painter.setFont(headerFont) painter.setPen(cellMetricsTextColor) name = metrics.elidedText( self.glyph.name, Qt.ElideRight, width - 2) painter.drawText( 1, 0, width - 2, height - minOffset, Qt.TextSingleLine | Qt.AlignCenter | Qt.AlignBottom, name)
def on_player_song_changed(self, song): source_name_map = { p.identifier: p.name for p in self._app.library.list() } font_metrics = QFontMetrics(QApplication.font()) text = '{} - {}'.format(song.title, song.artists_name) elided_text = font_metrics.elidedText( text, Qt.ElideRight, self.progress_slider.width() - 100) self.song_source_label.setText(source_name_map[song.source]) self.song_title_label.setText(elided_text)
def update(self): #图片 image = QImage(self._item_image) self._item_image_widget.setPixmap(QPixmap.fromImage(image.scaled(ITEM_IMAGE_WIDTH, ITEM_IMAGE_HEIGHT))) #名称 font_metrics = QFontMetrics(self.font()) self._item_name_widget.setText('<span style="color:red">%s</span>' % \ font_metrics.elidedText(self._item_name, Qt.ElideRight, \ self._item_name_widget.maximumWidth())) self._item_name_widget.setToolTip(self._item_name) #分类 self._item_category_widget.setText('<span style="color:olive">%s</span>' % \ font_metrics.elidedText(self._item_category, Qt.ElideRight, \ self._item_category_widget.maximumWidth())) self._item_category_widget.setToolTip(self._item_category) #数量 count_str = '%s(%s)' % (str(self._item_count), self._item_quantifier) self._item_count_widget.setText('<span style="color:green">%s</span>' % \ font_metrics.elidedText(count_str, Qt.ElideRight, \ self._item_count_widget.maximumWidth())) self._item_count_widget.setToolTip(count_str)
def __textLayout(self): fm = QFontMetrics(self.font()) text = six.text_type(self.defaultAction().iconText()) words = deque(text.split()) lines = [] curr_line = "" curr_line_word_count = 0 option = QStyleOptionToolButton() option.initFrom(self) margin = self.style().pixelMetric(QStyle.PM_ButtonMargin, option, self) width = self.width() - 2 * margin while words: w = words.popleft() if curr_line_word_count: line_extended = " ".join([curr_line, w]) else: line_extended = w line_w = fm.boundingRect(line_extended).width() if line_w >= width: if curr_line_word_count == 0 or len(lines) == 1: # A single word that is too long must be elided. # Also if the text overflows 2 lines # Warning: hardcoded max lines curr_line = fm.elidedText(line_extended, Qt.ElideRight, width) curr_line = six.text_type(curr_line) else: # Put the word back words.appendleft(w) lines.append(curr_line) curr_line = "" curr_line_word_count = 0 if len(lines) == 2: break else: curr_line = line_extended curr_line_word_count += 1 if curr_line: lines.append(curr_line) text = "\n".join(lines) self.__text = text
def on_player_song_changed(self, song): if song is None: self.song_source_label.setText('歌曲来源') self.song_title_label.setText('No song is playing.') return source_name_map = {p.identifier: p.name for p in self._app.library.list()} font_metrics = QFontMetrics(QApplication.font()) text = '{} - {}'.format(song.title, song.artists_name) elided_text = font_metrics.elidedText( text, Qt.ElideRight, self.progress_slider.width() - 100) self.song_source_label.setText(source_name_map[song.source]) self.song_title_label.setText(elided_text)
def open_file(self, bk): filePath, fileType = QFileDialog.getOpenFileName( self, "选取文件", os.path.join(bk._w.plugin_dir, 'AliasReplace'), "Csv file(*.csv)") #print(filePath) fontWidth = QFontMetrics(self.filepath_label.font()) elideNote = fontWidth.elidedText(filePath, Qt.ElideMiddle, 250) self.filepath_label.setText(elideNote) self.filepath_label.setToolTip(filePath) self.items['choice_filepath'] = filePath print('Chosen:', filePath)
def makeAction(self, icon, text, parent): """ Public method to create an action. @param icon icon of the action (QIcon) @param text text of the action (string) @param parent reference to the parent object (QObject) @return reference to the created action (QAction) """ fm = QFontMetrics(self.font()) if self.__maxWidth == -1: self.__maxWidth = fm.width('m') * 30 smallText = fm.elidedText(text, Qt.ElideMiddle, self.__maxWidth) return QAction(icon, smallText, parent)
def makeAction(self, icon, text, parent): """ Public method to create an action. @param icon icon of the action (QIcon) @param text text of the action (string) @param parent reference to the parent object (QObject) @return reference to the created action (QAction) """ fm = QFontMetrics(self.font()) if self.__maxWidth == -1: self.__maxWidth = fm.width('m') * 30 smallText = fm.elidedText(text, Qt.ElideMiddle, self.__maxWidth) return QAction(icon, smallText, parent)
def sync_ui(self, button, has_document, has_rows): "Sync state of actions" debug_print('CookieCutterWidget.sync_ui') current = cookie_cutter_choice().current has_current = cookie_cutter_choice().current is not None name = current.name if current else 'Cookie cutter' # Truncate text to fit button metrics = QFontMetrics(button.font()) elided = metrics.elidedText(name, Qt.ElideRight, button.width() - 25) button.setText(elided) self.save_to_new_action.setEnabled(has_rows) self.clear_action.setEnabled(has_current) self.reveal_action.setEnabled(has_current) self.apply_current_action.setEnabled(has_document and has_current)
def __adjustLabel(self): """ 调整标签的文本长度和位置 """ newText, isWordWrap = autoWrap(self.playlistName, 32) if isWordWrap: # 添加省略号 index = newText.index('\n') fontMetrics = QFontMetrics(QFont('Microsoft YaHei', 10, 75)) secondLineText = fontMetrics.elidedText(newText[index + 1:], Qt.ElideRight, 288) newText = newText[:index + 1] + secondLineText self.playlistNameLabel.setText(newText) self.playlistNameLabel.adjustSize() self.playlistLenLabel.adjustSize() self.playlistLenLabel.move( 5, self.playlistNameLabel.y() + self.playlistNameLabel.height() + 5)
def paintEvent(self, event): QLineEdit.paintEvent(self, event) if not self.text() and self.placeholderText() and \ not self.hasFocus(): p = QStylePainter(self) font = self.font() metrics = QFontMetrics(font) p.setFont(font) color = self.palette().color(QPalette.Mid) p.setPen(color) left, top, right, bottom = self.getTextMargins() contents = self.contentsRect() contents = contents.adjusted(left, top, -right, -bottom) text = metrics.elidedText(self.placeholderText(), Qt.ElideMiddle, contents.width()) p.drawText(contents, Qt.AlignLeft | Qt.AlignVCenter, text)
def paint(self, painter, option, index): painter.save() painter.setRenderHint(QPainter.Antialiasing) rect = option.rect text_rect_height = TextHeight cover_spacing = 0 text_y = rect.y() + rect.height() - text_rect_height cover_height = rect.height() - text_rect_height cover_width = rect.width() - cover_spacing cover_x = rect.x() + cover_spacing // 2 cover_y = rect.y() text_rect = QRectF(rect.x(), text_y, rect.width(), text_rect_height) obj = index.data(Qt.DecorationRole) if obj is None: painter.restore() return text_color = option.palette.color(QPalette.Text) if text_color.lightness() > 150: non_text_color = text_color.darker(140) else: non_text_color = text_color.lighter(150) non_text_color.setAlpha(100) painter.save() pen = painter.pen() pen.setColor(non_text_color) painter.setPen(pen) painter.translate(cover_x, cover_y) cover_rect = QRect(0, 0, cover_width, cover_height) if isinstance(obj, QColor): color = obj brush = QBrush(color) painter.setBrush(brush) else: pixmap = obj.scaledToWidth(cover_width, Qt.SmoothTransformation) brush = QBrush(pixmap) painter.setBrush(brush) painter.drawRoundedRect(cover_rect, 3, 3) painter.restore() option = QTextOption() option.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) album_name = index.data(Qt.DisplayRole) fm = QFontMetrics(painter.font()) elided_album_name = fm.elidedText(album_name, Qt.ElideRight, text_rect.width()) painter.drawText(text_rect, elided_album_name, option) painter.restore()
def on_player_song_changed(self, song): if song is None: self.song_source_label.setText('歌曲来源') self.song_title_label.setText('No song is playing.') return source_name_map = {p.identifier: p.name for p in self._app.library.list()} font_metrics = QFontMetrics(QApplication.font()) text = '{} - {}'.format(song.title_display, song.artists_name_display) # width -> three button + source label + text <= progress slider # three button: 63, source label: 150 elided_text = font_metrics.elidedText( text, Qt.ElideRight, self.progress_slider.width() - 200) self.song_source_label.setText(source_name_map[song.source]) self.song_title_label.setText(elided_text) loop = asyncio.get_event_loop() loop.create_task(self.update_mv_btn_status(song))
def sync_ui(self, button, has_document, has_rows): "Sync state of actions" debug_print('CookieCutterWidget.sync_ui') current = cookie_cutter_choice().current has_current = cookie_cutter_choice().current is not None name = current.name if current else 'Cookie cutter' # Truncate text to fit button metrics = QFontMetrics(button.font()) elided = metrics.elidedText( name, Qt.ElideRight, button.width() - 25 ) button.setText(elided) self.save_to_new_action.setEnabled(has_rows) self.clear_action.setEnabled(has_current) self.reveal_action.setEnabled(has_current) self.apply_current_action.setEnabled(has_document and has_current)
def on_player_media_changed(cls, music_model): artists = music_model['artists'] artists_name = '' for artist in artists: artists_name += artist['name'] title = music_model['name'] + ' - ' + artists_name cls.controller.desktop_mini.content.set_song_name(music_model['name']) cls.controller.desktop_mini.content.set_song_singer(artists_name) metrics = QFontMetrics(ViewOp.ui.TOP_WIDGET.font()) title = metrics.elidedText(title, Qt.ElideRight, 300 - 40) ViewOp.ui.SONG_NAME_LABEL.setText(title) cls.controller.lyric_widget.reset_lyric() ViewOp.ui.SONG_COUNTDOWN_LABEL.setText('00:00') ViewOp.ui.SONG_PROGRESS_SLIDER.setRange( 0, cls.controller.player.duration() / 1000) cls.controller.desktop_mini.content.set_duration( cls.controller.player.duration() / 1000) cls.controller.network_manager.get( QNetworkRequest( QUrl(music_model['album']['picUrl'] + "?param=200y200"))) cls.controller.network_manager.network_queue.put( ViewOp.set_music_cover_img) cls.controller.current_playlist_widget.add_item_from_model(music_model) cls.controller.current_playlist_widget.focus_cell_by_mid( music_model['id']) cls.controller.state['current_mid'] = music_model['id'] if MusicModel.mv_available(music_model): ViewOp.ui.PLAY_MV_BTN.show() else: ViewOp.ui.PLAY_MV_BTN.close() if cls.controller.state['is_login']: if cls.controller.api.is_favorite_music(music_model['id']): ViewOp.ui.LOVE_SONG_BTN.setChecked(True) cls.controller.desktop_mini.content.is_song_like = True else: ViewOp.ui.LOVE_SONG_BTN.setChecked(False) cls.controller.desktop_mini.content.is_song_like = False
def on_index_changed(self, index): if index < 0 or not self.themes: return metrics = QFontMetrics(self.font()) if self.themes[index] == self.current_theme: return self.current_theme = self.themes[index] name = '❀ ' + self.themes[index] width = metrics.width(name) if width < self.maximum_width: self.setFixedWidth(width + 10) self.setItemText(index, name) self.setToolTip(name) else: self.setFixedWidth(self.maximum_width) text = metrics.elidedText(name, Qt.ElideRight, self.width()) self.setItemText(index, text) self.setToolTip(text) self.signal_change_theme.emit(self.current_theme)
def paintEvent(self, event): painter = QPainter(self) if self.isEnabled() and not self.isDown() and not self.isChecked(): painter.save() hover_color = QColor("#424242") faded_hover_color = QColor(hover_color) faded_hover_color.setAlpha(int(self._fader * hover_color.alpha())) painter.fillRect(event.rect(), faded_hover_color) painter.restore() elif self.isDown() or self.isChecked(): painter.save() selected_color = QColor("#161719") painter.fillRect(event.rect(), selected_color) painter.restore() is_titled = bool(self.defaultAction().property("titled")) icon_rect = QRect(0, 0, 32, 32) icon_rect.moveCenter(event.rect().center()) if is_titled: font = painter.font() center_rect = event.rect() font.setPointSizeF(6) fm = QFontMetrics(font) line_height = fm.height() text_flags = Qt.AlignHCenter | Qt.AlignTop project_name = self.defaultAction().property("heading") if project_name is not None: center_rect.adjust(0, line_height, 0, 0) icon_rect.moveTop(center_rect.top()) else: icon_rect.moveCenter(center_rect.center()) self.icon().paint(painter, icon_rect, Qt.AlignCenter) painter.setFont(font) r = QRect(0, 5, self.rect().width(), line_height) painter.setPen(Qt.white) margin = 5 available_width = r.width() - margin ellided_project_name = fm.elidedText( project_name, Qt.ElideMiddle, available_width) painter.drawText(r, text_flags, ellided_project_name) else: self.icon().paint(painter, icon_rect, Qt.AlignCenter)
def renderCell(self, painter, rowStats, colStats, itemRect): rowIndex = rowStats.index colIndex = colStats.index if colStats is not None else 0 extraFlags = nonone(self.ds.data(rowIndex, colIndex, EXTRA_ROLE), 0) pixmap = self.ds.data(rowIndex, colIndex, Qt.DecorationRole) if pixmap: painter.drawPixmap(itemRect.topLeft(), pixmap) else: # we don't support drawing pixmap and text in the same cell (don't need it) bgbrush = self.ds.data(rowIndex, colIndex, Qt.BackgroundRole) if bgbrush is not None: painter.fillRect(itemRect, bgbrush) if rowStats.splitCount > 2 and colStats.col.name in {'from', 'to', 'transfer'}: text = '--split--' else: text = self.ds.data(rowIndex, colIndex, Qt.DisplayRole) if text: alignment = self.ds.data(rowIndex, colIndex, Qt.TextAlignmentRole) if not alignment: alignment = Qt.AlignLeft|Qt.AlignVCenter font = self.ds.data(rowIndex, colIndex, Qt.FontRole) if font is None: font = self.ds.rowFont() fm = QFontMetrics(font) # elidedText has a tendency to "over-elide" that's why we have "+1" text = fm.elidedText(text, Qt.ElideRight, itemRect.width()+1) painter.save() painter.setFont(font) painter.drawText(itemRect, alignment, text) painter.restore() if extraFlags & (EXTRA_UNDERLINED | EXTRA_UNDERLINED_DOUBLE): p1 = itemRect.bottomLeft() p2 = itemRect.bottomRight() # Things get crowded with double lines and we have to cheat a little bit on # item rects. p1.setY(p1.y()+2) p2.setY(p2.y()+2) painter.drawLine(p1, p2) if extraFlags & EXTRA_UNDERLINED_DOUBLE: p1.setY(p1.y()-3) p2.setY(p2.y()-3) painter.drawLine(p1, p2)
def on_index_changed(self, index): if index < 0 or not self.themes: return metrics = QFontMetrics(self.font()) if self.themes[index] == self.current_theme: return self.current_theme = self.themes[index] name = '❀ ' + self.themes[index] width = metrics.width(name) if width < self.maximum_width: self.setFixedWidth(width + 10) self.setItemText(index, name) self.setToolTip(name) else: self.setFixedWidth(self.maximum_width) text = metrics.elidedText(name, Qt.ElideRight, self.width()) self.setItemText(index, text) self.setToolTip(text) self.signal_change_theme.emit(self.current_theme)
def on_table_selection_changed(self): min_row, max_row, start, end = self.ui.tableMessages.selection_range() if min_row == -1: self.ui.lEncodingValue.setText("-") # self.ui.lEncodingValue.setToolTip("") self.label_list_model.message = None return container = self.table_model.protocol message = container.messages[min_row] self.label_list_model.message = message decoder_name = message.decoder.name metrics = QFontMetrics(self.ui.lEncodingValue.font()) elidedName = metrics.elidedText(decoder_name, Qt.ElideRight, self.ui.lEncodingValue.width()) self.ui.lEncodingValue.setText(elidedName) self.ui.lEncodingValue.setToolTip(decoder_name) self.ui.cBoxModulations.blockSignals(True) self.ui.cBoxModulations.setCurrentIndex(message.modulator_index) self.show_modulation_info() self.ui.cBoxModulations.blockSignals(False)
def on_player_media_changed(cls, music_model): artists = music_model["artists"] artists_name = "" for artist in artists: artists_name += artist["name"] title = music_model["name"] + " - " + artists_name cls.controller.desktop_mini.content.set_song_name(music_model["name"]) cls.controller.desktop_mini.content.set_song_singer(artists_name) metrics = QFontMetrics(ViewOp.ui.TOP_WIDGET.font()) title = metrics.elidedText(title, Qt.ElideRight, 300 - 40) ViewOp.ui.SONG_NAME_LABEL.setText(title) cls.controller.lyric_widget.reset_lyric() ViewOp.ui.SONG_COUNTDOWN_LABEL.setText("00:00") ViewOp.ui.SONG_PROGRESS_SLIDER.setRange(0, cls.controller.player.duration() / 1000) cls.controller.desktop_mini.content.set_duration(cls.controller.player.duration() / 1000) cls.controller.network_manager.get(QNetworkRequest(QUrl(music_model["album"]["picUrl"] + "?param=200y200"))) cls.controller.network_manager.network_queue.put(ViewOp.set_music_cover_img) cls.controller.current_playlist_widget.add_item_from_model(music_model) cls.controller.current_playlist_widget.focus_cell_by_mid(music_model["id"]) cls.controller.state["current_mid"] = music_model["id"] if MusicModel.mv_available(music_model): ViewOp.ui.PLAY_MV_BTN.show() else: ViewOp.ui.PLAY_MV_BTN.close() if cls.controller.state["is_login"]: if cls.controller.api.is_favorite_music(music_model["id"]): ViewOp.ui.LOVE_SONG_BTN.setChecked(True) cls.controller.desktop_mini.content.is_song_like = True else: ViewOp.ui.LOVE_SONG_BTN.setChecked(False) cls.controller.desktop_mini.content.is_song_like = False
def on_player_media_changed(cls, music_model): artists = music_model['artists'] artists_name = '' for artist in artists: artists_name += artist['name'] title = music_model['name'] + ' - ' + artists_name ControllerApi.desktop_mini.content.set_song_name(music_model['name']) ControllerApi.desktop_mini.content.set_song_singer(artists_name) metrics = QFontMetrics(ViewOp.ui.TOP_WIDGET.font()) title = metrics.elidedText(title, Qt.ElideRight, 300 - 40) ViewOp.ui.SONG_NAME_LABEL.setText(title) ControllerApi.lyric_widget.reset_lyric() ViewOp.ui.SONG_COUNTDOWN_LABEL.setText('00:00') ViewOp.ui.SONG_PROGRESS_SLIDER.setRange(0, ControllerApi.player.duration() / 1000) ControllerApi.desktop_mini.content.set_duration(ControllerApi.player.duration() / 1000) ControllerApi.network_manager.get(QNetworkRequest(QUrl(music_model['album']['picUrl'] + "?param=200y200"))) ControllerApi.network_manager.network_queue.put(ViewOp.set_music_icon) ControllerApi.current_playlist_widget.add_item_from_model(music_model) ControllerApi.current_playlist_widget.focus_cell_by_mid(music_model['id']) ControllerApi.state['current_mid'] = music_model['id'] if MusicModel.mv_available(music_model): ViewOp.ui.PLAY_MV_BTN.show() else: ViewOp.ui.PLAY_MV_BTN.close() if ControllerApi.state['is_login']: if ControllerApi.api.is_favorite_music(music_model['id']): ViewOp.ui.LOVE_SONG_BTN.setChecked(True) ControllerApi.desktop_mini.content.is_song_like = True else: ViewOp.ui.LOVE_SONG_BTN.setChecked(False) ControllerApi.desktop_mini.content.is_song_like = False
def paint_v2(self, p, option, index): # QStyledItemDelegate.paint(self, p, option, index) if not index.isValid(): return item = index.internalPointer() self.updateRects(option, index) colors = outlineItemColors(item) style = qApp.style() def _rotate(angle, rect=self.mainRect): p.translate(rect.center()) p.rotate(angle) p.translate(-rect.center()) def drawRect(r): p.save() p.setBrush(Qt.gray) p.drawRect(r) p.restore() # Draw background cg = QPalette.ColorGroup(QPalette.Normal if option.state & QStyle.State_Enabled else QPalette.Disabled) if cg == QPalette.Normal and not option.state & QStyle.State_Active: cg = QPalette.Inactive # Selection if option.state & QStyle.State_Selected: p.save() p.setBrush(option.palette.brush(cg, QPalette.Highlight)) p.setPen(Qt.NoPen) #p.drawRoundedRect(option.rect, 12, 12) p.drawRect(option.rect) p.restore() # Background p.save() if settings.viewSettings["Cork"]["Background"] != "Nothing": c = colors[settings.viewSettings["Cork"]["Background"]] if c == QColor(Qt.transparent): c = QColor(Qt.white) col = mixColors(c, QColor(Qt.white), .2) backgroundColor = col p.setBrush(col) else: p.setBrush(Qt.white) backgroundColor = QColor(Qt.white) # Cache background color self.bgColors[index] = backgroundColor.name() p.setPen(Qt.NoPen) p.drawRect(self.cardRect) if item.isFolder(): itemPoly = QPolygonF([ self.topRect.topLeft(), self.topRect.topLeft() + QPoint(self.topRect.width() * .35, 0), self.cardRect.topLeft() + QPoint(self.topRect.width() * .45, 0), self.cardRect.topRight(), self.cardRect.bottomRight(), self.cardRect.bottomLeft() ]) p.drawPolygon(itemPoly) p.restore() # Label color if settings.viewSettings["Cork"]["Corner"] != "Nothing": p.save() color = colors[settings.viewSettings["Cork"]["Corner"]] p.setPen(Qt.NoPen) p.setBrush(color) p.drawRect(self.labelRect) w = self.labelRect.width() poly = QPolygonF([ self.labelRect.bottomLeft() + QPointF(0, 1), self.labelRect.bottomLeft() + QPointF(0, w / 2), self.labelRect.bottomLeft() + QPointF(w / 2, 1), self.labelRect.bottomRight() + QPointF(1, w / 2), self.labelRect.bottomRight() + QPointF(1, 1), ]) p.drawPolygon(poly) p.restore() if settings.viewSettings["Cork"]["Corner"] == "Nothing" or \ color == Qt.transparent: # No corner, so title can be full width self.titleRect.setRight(self.mainRect.right()) # Draw the icon iconRect = self.iconRect mode = QIcon.Normal if not option.state & style.State_Enabled: mode = QIcon.Disabled elif option.state & style.State_Selected: mode = QIcon.Selected # index.data(Qt.DecorationRole).paint(p, iconRect, option.decorationAlignment, mode) icon = index.data(Qt.DecorationRole).pixmap(iconRect.size()) if settings.viewSettings["Cork"]["Icon"] != "Nothing": color = colors[settings.viewSettings["Cork"]["Icon"]] colorifyPixmap(icon, color) QIcon(icon).paint(p, iconRect, option.decorationAlignment, mode) # Draw title p.save() text = index.data() if text: p.setPen(Qt.black) textColor = QColor(Qt.black) if settings.viewSettings["Cork"]["Text"] != "Nothing": col = colors[settings.viewSettings["Cork"]["Text"]] if col == Qt.transparent: col = Qt.black # If title setting is compile, we have to hack the color # Or we won't see anything in some themes if settings.viewSettings["Cork"]["Text"] == "Compile": if item.compile() in [0, "0"]: col = mixColors(QColor(Qt.black), backgroundColor) else: col = Qt.black textColor = col p.setPen(col) f = QFont(option.font) f.setPointSize(f.pointSize() + 4) f.setBold(True) p.setFont(f) fm = QFontMetrics(f) elidedText = fm.elidedText(text, Qt.ElideRight, self.titleRect.width()) p.drawText(self.titleRect, Qt.AlignLeft | Qt.AlignVCenter, elidedText) p.restore() # One line summary background lineSummary = item.data(Outline.summarySentence) fullSummary = item.data(Outline.summaryFull) # Border if settings.viewSettings["Cork"]["Border"] != "Nothing": p.save() p.setBrush(Qt.NoBrush) pen = p.pen() pen.setWidth(2) col = colors[settings.viewSettings["Cork"]["Border"]] pen.setColor(col) p.setPen(pen) if item.isFolder(): p.drawPolygon(itemPoly) else: p.drawRect(self.cardRect) p.restore() # Draw status status = item.data(Outline.status) if status: it = mainWindow().mdlStatus.item(int(status), 0) if it != None: p.save() p.setClipRegion(QRegion(self.cardRect)) f = p.font() f.setPointSize(f.pointSize() + 12) f.setBold(True) p.setFont(f) p.setPen(QColor(Qt.red).lighter(170)) _rotate(-35, rect=self.cardRect) p.drawText(self.cardRect, Qt.AlignCenter, it.text()) p.restore() # Draw Summary # One line if lineSummary: p.save() f = QFont(option.font) f.setBold(True) p.setFont(f) p.setPen(textColor) fm = QFontMetrics(f) elidedText = fm.elidedText(lineSummary, Qt.ElideRight, self.mainLineRect.width()) p.drawText(self.mainLineRect, Qt.AlignLeft | Qt.AlignVCenter, elidedText) p.restore() # Full summary if fullSummary: p.save() p.setFont(option.font) p.setPen(textColor) p.drawText(self.mainTextRect, Qt.TextWordWrap, fullSummary) p.restore()
class PackageDelegate(QStyledItemDelegate): packageSelected=pyqtSignal([bool]) AppStyle = qApp.style def __init__(self, parent=None, mainWindow=None, showDetailsButton=True, animatable=True): super(PackageDelegate, self).__init__(parent) self.webDialog = WebDialog(mainWindow) self.show_details_button = showDetailsButton self.rowAnimator = RowAnimator(parent.packageList) self.defaultIcon = KIcon(('package-x-generic', 'package_applications'), 32) self.defaultInstalledIcon = QIcon(KIconLoader.loadOverlayed(('package-x-generic', 'package_applications'), CHECK_ICON, 32)) self.animatable = animatable self._max_height = ROW_HEIGHT self._rt_0 = QIcon(":/data/star_0.svg") self._rt_1 = QIcon(":/data/star_1.svg") self.types = {'critical':(RED, _translate("Packaga Manager",'critical')), 'security':(DARKRED, _translate("Packaga Manager",'security'))} self.font = Pds.settings('font','Sans,10').split(',')[0] self.normalFont = QFont(self.font, 10, QFont.Normal) self.boldFont = QFont(self.font, 11, QFont.Bold) self.normalDetailFont = QFont(self.font, 9, QFont.Normal) self.boldDetailFont = QFont(self.font, 9, QFont.Bold) self.tagFont = QFont(self.font, 7, QFont.Normal) self.tagFontFM = QFontMetrics(self.tagFont) self.boldFontFM = QFontMetrics(self.boldFont) self.boldDetailFontFM = QFontMetrics(self.boldDetailFont) self.normalFontFM = QFontMetrics(self.normalFont) self.normalDetailFontFM = QFontMetrics(self.normalDetailFont) self._titles = {'description': _translate("Packaga Manager","Description:"), 'website' : _translate("Packaga Manager","Website:"), 'release' : _translate("Packaga Manager","Release:"), 'repository' : _translate("Packaga Manager","Repository:"), 'size' : _translate("Packaga Manager","Package Size:"), 'installVers': _translate("Packaga Manager","Installed Version:")} self._titleFM = {} for key, value in self._titles.items(): self._titleFM[key] = self.boldDetailFontFM.width(value) + ICON_SIZE + 3 self.baseWidth = self.boldFontFM.width(max(self._titles.values(), key=len)) + ICON_SIZE self.parent = parent.packageList # Base style for some of important features # self.plastik = QStyleFactory.create('plastique') def paint(self, painter, option, index): if not index.isValid(): return super(PackageDelegate, self).paint(painter, option, index) if index.flags() & Qt.ItemIsUserCheckable: if index.column() == 0: self.paintCheckBoxColumn(painter, option, index) else: self.paintInfoColumn(painter, option, index) else: self.paintInfoColumn(painter, option, index, width_limit = 10) def paintCheckBoxColumn(self, painter, option, index): opt = QStyleOptionViewItem(option) buttonStyle = QStyleOptionButton() buttonStyle.state = QStyle.State_On if index.model().data(index, Qt.CheckStateRole) == QVariant(Qt.Checked) else QStyle.State_Off buttonStyle.state |= QStyle.State_Enabled if option.state & QStyle.State_MouseOver or option.state & QStyle.State_HasFocus: buttonStyle.state |= QStyle.State_HasFocus | QStyle.State_MouseOver buttonStyle.rect = opt.rect.adjusted(4, -opt.rect.height() + ROW_HEIGHT, 0, 0) PackageDelegate.AppStyle().drawControl(QStyle.CE_CheckBox, buttonStyle, painter, None) def paintInfoColumn(self, painter, option, index, width_limit = 0): left = option.rect.left() + 3 top = option.rect.top() width = option.rect.width() - width_limit pixmap = QPixmap(option.rect.size()) pixmap.fill(Qt.transparent) p = QPainter(pixmap) p.setRenderHint(QPainter.Antialiasing, True) p.translate(-option.rect.topLeft()) textInner = 2 * ICON_PADDING + ROW_HEIGHT - 10 itemHeight = ROW_HEIGHT + 2 * ICON_PADDING margin = left + ICON_PADDING - 10 title = QVariant.value(index.model().data(index, NameRole)) summary = QVariant.value(index.model().data(index, SummaryRole)) ptype = QVariant.value(index.model().data(index, TypeRole)) rate = int(QVariant.value(index.model().data(index, RateRole))) if QVariant.value(index.model().data(index, RateRole))!= None else 0 installed = True if QVariant.value(index.model().data(index, InstalledRole))=="True" else False # We need to request update if its not possible to get meta data about the package try: # Get Package Icon if exists _icon = QVariant.value(index.model().data(index, Qt.DecorationRole)) except: p.end() painter.drawPixmap(option.rect.topLeft(), pixmap) self.parent.requestUpdate() return icon = None if _icon: overlay = [CHECK_ICON] if installed else [] KIconLoader._forceCache = True pix = KIconLoader.loadOverlayed(_icon, overlay, 32) if not pix.isNull(): icon = QIcon(pix.scaled(QSize(32, 32), Qt.KeepAspectRatio, Qt.SmoothTransformation)) KIconLoader._forceCache = False if not icon: icon = self.defaultIcon if not installed else self.defaultInstalledIcon # Paint the Icon icon.paint(p, margin, top + ICON_PADDING, ROW_HEIGHT, ROW_HEIGHT, Qt.AlignCenter) fix_pos = 0 if index.model().columnCount() <= 1: fix_pos = 22 if config.USE_APPINFO: # Rating Stars for _rt_i in range(5): self._rt_0.paint(p, width + 10 * _rt_i - 30 - fix_pos, top + ROW_HEIGHT / 4, 10, 10, Qt.AlignCenter) for _rt_i in range(rate): self._rt_1.paint(p, width + 10 * _rt_i - 30 - fix_pos, top + ROW_HEIGHT / 4, 10, 10, Qt.AlignCenter) foregroundColor = option.palette.color(QPalette.Text) p.setPen(foregroundColor) # Package Name p.setFont(self.boldFont) p.drawText(left + textInner, top, width - textInner, itemHeight / 2,Qt.AlignBottom | Qt.AlignLeft, title) # tagWidth = 0 _component_width = 0 if self.parent.showComponents: component = str(QVariant.value(index.model().data(index, ComponentRole))) widthOfTitle = self.boldFontFM.width(title) + 6 + left + textInner p.setFont(self.tagFont) rect = self.tagFontFM.boundingRect(option.rect, Qt.TextWordWrap, component) p.setPen(LIGHTGREEN) p.setBrush(LIGHTGREEN) p.drawRoundedRect(widthOfTitle , top + 12, rect.width() + 4, rect.height(), 10, 10) p.setPen(DARKGREEN) p.drawText(widthOfTitle + 2, top + 12, rect.width(), rect.height(), Qt.AlignCenter, component) p.setPen(foregroundColor) _component_width = rect.width() + 8 if self.parent.showIsA: isa = str(QVariant.value(index.model().data(index, IsaRole))) if not isa == '': widthOfTitle = self.boldFontFM.width(title) + 6 + left + textInner + _component_width p.setFont(self.tagFont) rect = self.tagFontFM.boundingRect(option.rect, Qt.TextWordWrap, isa) p.setPen(LIGHTBLUE) p.setBrush(LIGHTBLUE) p.drawRoundedRect(widthOfTitle , top + 12, rect.width() + 4, rect.height(), 10, 10) p.setPen(DARKVIOLET) p.drawText(widthOfTitle + 2, top + 12, rect.width(), rect.height(), Qt.AlignCenter, isa) p.setPen(foregroundColor) _component_width += rect.width() + 8 if ptype not in ('None', 'normal'): widthOfTitle = self.boldFontFM.width(title) + 6 + left + textInner + _component_width p.setFont(self.tagFont) rect = self.tagFontFM.boundingRect(option.rect, Qt.TextWordWrap, self.types[ptype][1]) p.setPen(self.types[ptype][0]) p.setBrush(self.types[ptype][0]) p.drawRoundedRect(widthOfTitle, top + 12, rect.width() + 4, rect.height(), 10, 10) p.setPen(WHITE) p.drawText(widthOfTitle + 2, top + 12, rect.width(), rect.height(), Qt.AlignCenter, self.types[ptype][1]) p.setPen(foregroundColor) tagWidth = rect.width() # Package Summary p.setFont(self.normalFont) foregroundColor.setAlpha(160) p.setPen(foregroundColor) elided_summary = self.normalFontFM.elidedText(summary, Qt.ElideRight, width - textInner - tagWidth - 22) p.drawText(left + textInner, top + itemHeight / 2, width - textInner, itemHeight / 2, Qt.TextDontClip, elided_summary) foregroundColor.setAlpha(255) p.setPen(foregroundColor) buttonStyle = None if self.rowAnimator.currentRow() == index.row(): description = str(QVariant.value(index.model().data(index, DescriptionRole))) size = str(QVariant.value(index.model().data(index, SizeRole))) homepage = str(QVariant.value(index.model().data(index, HomepageRole))) installedVersion = str(QVariant.value(index.model().data(index, InstalledVersionRole))) version = str(QVariant.value(index.model().data(index, VersionRole))) # Package Detail Label position = top + ROW_HEIGHT p.setFont(self.normalDetailFont) baseRect = QRect(left, position, width - 8, option.rect.height()) rect = self.normalDetailFontFM.boundingRect(baseRect, Qt.TextWordWrap | Qt.TextDontClip, description) p.drawText(left + 2, position, width - 8, rect.height(), Qt.TextWordWrap | Qt.TextDontClip, description) # Package Detail Homepage position += rect.height() + 4 p.setFont(self.boldDetailFont) p.drawText(left + ICON_SIZE , position, width - textInner, itemHeight / 2, Qt.AlignLeft, self._titles['website']) p.setFont(self.normalDetailFont) homepage = self.normalDetailFontFM.elidedText(homepage, Qt.ElideRight, width - self._titleFM['website']) rect = self.normalDetailFontFM.boundingRect(option.rect, Qt.TextSingleLine, homepage) self.rowAnimator.hoverLinkFilter.link_rect = QRect(left + self._titleFM['website'] + 2, position + 2 + 32, rect.width(), rect.height()) p.setPen(option.palette.color(QPalette.Link)) p.drawText(left + self._titleFM['website'], position, width, rect.height(), Qt.TextSingleLine, homepage) p.setPen(foregroundColor) # Package Detail Version position += rect.height() p.setFont(self.boldDetailFont) p.drawText(left + ICON_SIZE , position, width - textInner, itemHeight / 2, Qt.AlignLeft, self._titles['release']) p.setFont(self.normalDetailFont) rect = self.normalDetailFontFM.boundingRect(option.rect, Qt.TextWordWrap, version) p.drawText(left + self._titleFM['release'], position, width, rect.height(), Qt.TextWordWrap, version) if not installedVersion == '' or not installedVersion == None: position += rect.height() p.setFont(self.boldDetailFont) p.drawText(left + ICON_SIZE , position, width - textInner, itemHeight / 2, Qt.AlignLeft, self._titles['installVers']) p.setFont(self.normalDetailFont) rect = self.normalDetailFontFM.boundingRect(option.rect, Qt.TextWordWrap, installedVersion) p.drawText(left + self._titleFM['installVers'], position, width, rect.height(), Qt.TextWordWrap, installedVersion) # Package Detail Repository repository = QVariant.value(index.model().data(index, RepositoryRole)) if not repository == '': repository = _translate("Packaga Manager",'Unknown') if repository == 'N/A' else repository position += rect.height() p.setFont(self.boldDetailFont) p.drawText(left + ICON_SIZE , position, width - textInner, itemHeight / 2, Qt.AlignLeft, self._titles['repository']) p.setFont(self.normalDetailFont) p.drawText(left + self._titleFM['repository'], position, width, itemHeight / 2, Qt.TextWordWrap, repository) # Package Detail Size position += rect.height() p.setFont(self.boldDetailFont) p.drawText(left + ICON_SIZE , position, width - textInner, itemHeight / 2, Qt.AlignLeft, self._titles['size']) p.setFont(self.normalDetailFont) p.drawText(left + self._titleFM['size'], position, width, itemHeight / 2, Qt.TextWordWrap, size) position += rect.height() self.rowAnimator.max_height = position - top + 8 # Package More info button opt = QStyleOptionViewItem(option) buttonStyle = QStyleOptionButton() if option.state & QStyle.State_MouseOver or option.state & QStyle.State_HasFocus: buttonStyle.state |= QStyle.State_HasFocus buttonStyle.state |= QStyle.State_Enabled buttonStyle.text = _translate("Packaga Manager","Details") buttonStyle.rect = QRect(width - 100, position - 22, 100, 22) p.end() # FIXME # if option.state & QStyle.State_HasFocus and self.animatable: # option.state |= QStyle.State_MouseOver # Use Plastique style to draw focus rect like MouseOver effect of Oxygen. # self.plastik.drawPrimitive(QStyle.PE_FrameLineEdit, option, painter, None) if not self.rowAnimator.running() and buttonStyle: if self.show_details_button and (installed or config.USE_APPINFO): PackageDelegate.AppStyle().drawControl(QStyle.CE_PushButton, buttonStyle, painter, None) self.rowAnimator.hoverLinkFilter.button_rect = QRect(buttonStyle.rect) painter.drawPixmap(option.rect.topLeft(), pixmap) del pixmap def editorEvent(self, event, model, option, index): #paket seçim olayında hata var seçim olayı gerçekleşiyor ama packageList sonraki seçimde görüyor #geçici çözümle giderildi tamamen çözülmeli if event.type() == QEvent.MouseButtonRelease and index.column() == 0 and index.flags() & Qt.ItemIsUserCheckable: toggled = Qt.Checked if model.data(index, Qt.CheckStateRole) == QVariant(Qt.Unchecked) else Qt.Unchecked self.packageSelected.emit(bool(toggled)) return model.setData(index, toggled, Qt.CheckStateRole) __event = QItemDelegate(self).editorEvent(event, model, option, index) animate_requested = False if event.type() == QEvent.MouseButtonRelease and self.animatable: if self.rowAnimator.row == index.row(): epos = event.pos() if self.rowAnimator.hoverLinkFilter.link_rect.contains(QPoint(epos.x(), epos.y() + 32)): url = QUrl(QVariant.value(model.data(index, HomepageRole))) QDesktopServices.openUrl(url) return __event elif self.rowAnimator.hoverLinkFilter.button_rect.contains(epos, True): self.showPackageDetails(model, index) return __event animate_requested = True elif event.type() == QEvent.KeyPress and self.animatable: # KeyCode 32 : Space key if event.key() == 32 and index.column() == index.model().columnCount() - 1: animate_requested = True if not QVariant.value(model.data(index, DescriptionRole)) == '' and animate_requested: self.rowAnimator.animate(index.row()) return __event def showPackageDetails(self, model, index): def _getter(role): return model.data(index, role) name = _getter(NameRole) summary = _getter(SummaryRole) description = _getter(DescriptionRole) installed = True if str(QVariant.value(model.data(index, InstalledRole)))=="True" else False self.webDialog.showPackageDetails(name, installed, summary, description) def sizeHint(self, option, index): if self.rowAnimator.currentRow() == index.row() and not index.row() == 0: return self.rowAnimator.size() else: width = ICON_SIZE if index.column() == 0 else 0 return QSize(width, ROW_HEIGHT) def setAnimatable(self, animatable): self.animatable = animatable def reset(self): self.rowAnimator.reset()
class GridDelegate(QStyledItemDelegate): "A custom delegate for the model/view framework" POPUP = pyqtSignal() CONTEXT_ON = False # Gallery states G_NORMAL, G_DOWNLOAD = range(2) def __init__(self, parent=None): super().__init__(parent) QPixmapCache.setCacheLimit(app_constants.THUMBNAIL_CACHE_SIZE[0]* app_constants.THUMBNAIL_CACHE_SIZE[1]) self._painted_indexes = {} #misc.FileIcon.refresh_default_icon() self.file_icons = misc.FileIcon() if app_constants.USE_EXTERNAL_VIEWER: self.external_icon = self.file_icons.get_external_file_icon() else: self.external_icon = self.file_icons.get_default_file_icon() self.font_size = app_constants.GALLERY_FONT[1] self.font_name =0 # app_constants.GALLERY_FONT[0] if not self.font_name: self.font_name = QWidget().font().family() self.title_font = QFont() self.title_font.setBold(True) self.title_font.setFamily(self.font_name) self.artist_font = QFont() self.artist_font.setFamily(self.font_name) if self.font_size is not 0: self.title_font.setPixelSize(self.font_size) self.artist_font.setPixelSize(self.font_size) self.title_font_m = QFontMetrics(self.title_font) self.artist_font_m = QFontMetrics(self.artist_font) t_h = self.title_font_m.height() a_h = self.artist_font_m.height() self.text_label_h = a_h + t_h * 2 self.W = app_constants.THUMB_W_SIZE self.H = app_constants.THUMB_H_SIZE + app_constants.GRIDBOX_LBL_H#self.text_label_h #+ app_constants.GRIDBOX_LBL_H def key(self, key): "Assigns an unique key to indexes" if key in self._painted_indexes: return self._painted_indexes[key] else: k = hash(key) self._painted_indexes[key] = str(k) return str(k) def paint(self, painter, option, index): assert isinstance(painter, QPainter) if index.data(Qt.UserRole+1): if app_constants.HIGH_QUALITY_THUMBS: painter.setRenderHint(QPainter.SmoothPixmapTransform) painter.setRenderHint(QPainter.Antialiasing) gallery = index.data(Qt.UserRole+1) title = gallery.title artist = gallery.artist title_color = app_constants.GRID_VIEW_TITLE_COLOR artist_color = app_constants.GRID_VIEW_ARTIST_COLOR label_color = app_constants.GRID_VIEW_LABEL_COLOR # Enable this to see the defining box #painter.drawRect(option.rect) # define font size if 20 > len(title) > 15: title_size = "font-size:{}px;".format(self.font_size) elif 30 > len(title) > 20: title_size = "font-size:{}px;".format(self.font_size-1) elif 40 > len(title) >= 30: title_size = "font-size:{}px;".format(self.font_size-2) elif 50 > len(title) >= 40: title_size = "font-size:{}px;".format(self.font_size-3) elif len(title) >= 50: title_size = "font-size:{}px;".format(self.font_size-4) else: title_size = "font-size:{}px;".format(self.font_size) if 30 > len(artist) > 20: artist_size = "font-size:{}px;".format(self.font_size) elif 40 > len(artist) >= 30: artist_size = "font-size:{}px;".format(self.font_size-1) elif len(artist) >= 40: artist_size = "font-size:{}px;".format(self.font_size-2) else: artist_size = "font-size:{}px;".format(self.font_size) #painter.setPen(QPen(Qt.NoPen)) #option.rect = option.rect.adjusted(11, 10, 0, 0) option.rect.setWidth(self.W) option.rect.setHeight(self.H) rec = option.rect.getRect() x = rec[0] y = rec[1] w = rec[2] h = rec[3] text_area = QTextDocument() text_area.setDefaultFont(option.font) text_area.setHtml(""" <head> <style> #area {{ display:flex; width:{6}px; height:{7}px }} #title {{ position:absolute; color: {4}; font-weight:bold; {0} }} #artist {{ position:absolute; color: {5}; top:20px; right:0; {1} }} </style> </head> <body> <div id="area"> <center> <div id="title">{2} </div> <div id="artist">{3} </div> </div> </center> </body> """.format(title_size, artist_size, title, artist, title_color, artist_color, 130+app_constants.SIZE_FACTOR, 1+app_constants.SIZE_FACTOR)) text_area.setTextWidth(w) #chapter_area = QTextDocument() #chapter_area.setDefaultFont(option.font) #chapter_area.setHtml(""" #<font color="black">{}</font> #""".format("chapter")) #chapter_area.setTextWidth(w) def center_img(width): new_x = x if width < w: diff = w - width offset = diff//2 new_x += offset return new_x def img_too_big(start_x): txt_layout = misc.text_layout("Image is too big!", w, self.title_font, self.title_font_m) clipping = QRectF(x, y+h//4, w, app_constants.GRIDBOX_LBL_H - 10) txt_layout.draw(painter, QPointF(x, y+h//4), clip=clipping) # if we can't find a cached image pix_cache = QPixmapCache.find(self.key(gallery.profile)) if isinstance(pix_cache, QPixmap): self.image = pix_cache img_x = center_img(self.image.width()) if self.image.width() > w or self.image.height() > h: img_too_big(img_x) else: if self.image.height() < self.image.width(): #to keep aspect ratio painter.drawPixmap(QPoint(img_x,y), self.image) else: painter.drawPixmap(QPoint(img_x,y), self.image) else: self.image = QPixmap(gallery.profile) img_x = center_img(self.image.width()) QPixmapCache.insert(self.key(gallery.profile), self.image) if self.image.width() > w or self.image.height() > h: img_too_big(img_x) else: if self.image.height() < self.image.width(): #to keep aspect ratio painter.drawPixmap(QPoint(img_x,y), self.image) else: painter.drawPixmap(QPoint(img_x,y), self.image) # draw ribbon type painter.save() painter.setPen(Qt.NoPen) if app_constants.DISPLAY_GALLERY_RIBBON: type_ribbon_w = type_ribbon_l = w*0.11 rib_top_1 = QPointF(x+w-type_ribbon_l-type_ribbon_w, y) rib_top_2 = QPointF(x+w-type_ribbon_l, y) rib_side_1 = QPointF(x+w, y+type_ribbon_l) rib_side_2 = QPointF(x+w, y+type_ribbon_l+type_ribbon_w) ribbon_polygon = QPolygonF([rib_top_1, rib_top_2, rib_side_1, rib_side_2]) ribbon_path = QPainterPath() ribbon_path.setFillRule(Qt.WindingFill) ribbon_path.addPolygon(ribbon_polygon) ribbon_path.closeSubpath() painter.setBrush(QBrush(QColor(self._ribbon_color(gallery.type)))) painter.drawPath(ribbon_path) # draw if favourited if gallery.fav == 1: star_ribbon_w = star_ribbon_l = w*0.08 rib_top_1 = QPointF(x+star_ribbon_l, y) rib_side_1 = QPointF(x, y+star_ribbon_l) rib_top_2 = QPointF(x+star_ribbon_l+star_ribbon_w, y) rib_side_2 = QPointF(x, y+star_ribbon_l+star_ribbon_w) rib_star_mid_1 = QPointF((rib_top_1.x()+rib_side_1.x())/2, (rib_top_1.y()+rib_side_1.y())/2) rib_star_factor = star_ribbon_l/4 rib_star_p1_1 = rib_star_mid_1 + QPointF(rib_star_factor, -rib_star_factor) rib_star_p1_2 = rib_star_p1_1 + QPointF(-rib_star_factor, -rib_star_factor) rib_star_p1_3 = rib_star_mid_1 + QPointF(-rib_star_factor, rib_star_factor) rib_star_p1_4 = rib_star_p1_3 + QPointF(-rib_star_factor, -rib_star_factor) crown_1 = QPolygonF([rib_star_p1_1, rib_star_p1_2, rib_star_mid_1, rib_star_p1_4, rib_star_p1_3]) painter.setBrush(QBrush(QColor("yellow"))) painter.drawPolygon(crown_1) ribbon_polygon = QPolygonF([rib_top_1, rib_side_1, rib_side_2, rib_top_2]) ribbon_path = QPainterPath() ribbon_path.setFillRule(Qt.WindingFill) ribbon_path.addPolygon(ribbon_polygon) ribbon_path.closeSubpath() painter.drawPath(ribbon_path) #painter.setPen(QColor("#d35400")) #painter.drawPolyline(rib_top_1, rib_star_p1_1, rib_star_p1_2, rib_star_mid_1, rib_star_p1_4, rib_star_p1_3, rib_side_1) #painter.drawLine(rib_top_1, rib_top_2) #painter.drawLine(rib_top_2, rib_side_2) #painter.drawLine(rib_side_1, rib_side_2) painter.restore() if app_constants._REFRESH_EXTERNAL_VIEWER: if app_constants.USE_EXTERNAL_VIEWER: self.external_icon = self.file_icons.get_external_file_icon() else: self.external_icon = self.file_icons.get_default_file_icon() if gallery.state == self.G_DOWNLOAD: painter.save() dl_box = QRect(x, y, w, 20) painter.setBrush(QBrush(QColor(0,0,0,123))) painter.setPen(QColor('white')) painter.drawRect(dl_box) painter.drawText(dl_box, Qt.AlignCenter, 'Downloading...') painter.restore() else: if app_constants.DISPLAY_GALLERY_TYPE: self.type_icon = self.file_icons.get_file_icon(gallery.path) if self.type_icon and not self.type_icon.isNull(): self.type_icon.paint(painter, QRect(x+2, y+app_constants.THUMB_H_SIZE-16, 16, 16)) if app_constants.USE_EXTERNAL_PROG_ICO: if self.external_icon and not self.external_icon.isNull(): self.external_icon.paint(painter, QRect(x+w-30, y+app_constants.THUMB_H_SIZE-28, 28, 28)) def draw_text_label(lbl_h): #draw the label for text painter.save() painter.translate(x, y+app_constants.THUMB_H_SIZE) box_color = QBrush(QColor(label_color))#QColor(0,0,0,123)) painter.setBrush(box_color) rect = QRect(0, 0, w, lbl_h) #x, y, width, height painter.fillRect(rect, box_color) painter.restore() return rect if option.state & QStyle.State_MouseOver or\ option.state & QStyle.State_Selected: title_layout = misc.text_layout(title, w, self.title_font, self.title_font_m) artist_layout = misc.text_layout(artist, w, self.artist_font, self.artist_font_m) t_h = title_layout.boundingRect().height() a_h = artist_layout.boundingRect().height() if app_constants.GALLERY_FONT_ELIDE: lbl_rect = draw_text_label(min(t_h+a_h+3, app_constants.GRIDBOX_LBL_H)) else: lbl_rect = draw_text_label(app_constants.GRIDBOX_LBL_H) clipping = QRectF(x, y+app_constants.THUMB_H_SIZE, w, app_constants.GRIDBOX_LBL_H - 10) painter.setPen(QColor(title_color)) title_layout.draw(painter, QPointF(x, y+app_constants.THUMB_H_SIZE), clip=clipping) painter.setPen(QColor(artist_color)) artist_layout.draw(painter, QPointF(x, y+app_constants.THUMB_H_SIZE+t_h), clip=clipping) #painter.fillRect(option.rect, QColor) else: if app_constants.GALLERY_FONT_ELIDE: lbl_rect = draw_text_label(self.text_label_h) else: lbl_rect = draw_text_label(app_constants.GRIDBOX_LBL_H) # draw text painter.save() alignment = QTextOption(Qt.AlignCenter) alignment.setUseDesignMetrics(True) title_rect = QRectF(0,0,w, self.title_font_m.height()) artist_rect = QRectF(0,self.artist_font_m.height(),w, self.artist_font_m.height()) painter.translate(x, y+app_constants.THUMB_H_SIZE) if app_constants.GALLERY_FONT_ELIDE: painter.setFont(self.title_font) painter.setPen(QColor(title_color)) painter.drawText(title_rect, self.title_font_m.elidedText(title, Qt.ElideRight, w-10), alignment) painter.setPen(QColor(artist_color)) painter.setFont(self.artist_font) alignment.setWrapMode(QTextOption.NoWrap) painter.drawText(artist_rect, self.title_font_m.elidedText(artist, Qt.ElideRight, w-10), alignment) else: text_area.setDefaultFont(QFont(self.font_name)) text_area.drawContents(painter) ##painter.resetTransform() painter.restore() if option.state & QStyle.State_Selected: painter.save() selected_rect = QRectF(x, y, w, lbl_rect.height()+app_constants.THUMB_H_SIZE) painter.setPen(Qt.NoPen) painter.setBrush(QBrush(QColor(164,164,164,120))) painter.drawRoundedRect(selected_rect, 5, 5) #painter.fillRect(selected_rect, QColor(164,164,164,120)) painter.restore() if gallery.dead_link: painter.save() selected_rect = QRectF(x, y, w, lbl_rect.height()+app_constants.THUMB_H_SIZE) painter.setPen(Qt.NoPen) painter.setBrush(QBrush(QColor(255,0,0,120))) p_path = QPainterPath() p_path.setFillRule(Qt.WindingFill) p_path.addRoundedRect(selected_rect, 5,5) p_path.addRect(x,y, 20, 20) p_path.addRect(x+w-20,y, 20, 20) painter.drawPath(p_path.simplified()) painter.setPen(QColor("white")) txt_layout = misc.text_layout("Cannot find gallery source!", w, self.title_font, self.title_font_m) txt_layout.draw(painter, QPointF(x, y+h*0.3)) painter.restore() if app_constants.DEBUG: painter.save() painter.setBrush(QBrush(QColor("red"))) painter.setPen(QColor("white")) txt_l = self.title_font_m.width(str(gallery.id)) painter.drawRect(x, y+40, txt_l*2, self.title_font_m.height()) painter.drawText(x+1, y+51, str(gallery.id)) painter.restore() if option.state & QStyle.State_Selected: painter.setPen(QPen(option.palette.highlightedText().color())) else: super().paint(painter, option, index) def _ribbon_color(self, gallery_type): if gallery_type: gallery_type = gallery_type.lower() if gallery_type == "manga": return app_constants.GRID_VIEW_T_MANGA_COLOR elif gallery_type == "doujinshi": return app_constants.GRID_VIEW_T_DOUJIN_COLOR elif "artist cg" in gallery_type: return app_constants.GRID_VIEW_T_ARTIST_CG_COLOR elif "game cg" in gallery_type: return app_constants.GRID_VIEW_T_GAME_CG_COLOR elif gallery_type == "western": return app_constants.GRID_VIEW_T_WESTERN_COLOR elif "image" in gallery_type: return app_constants.GRID_VIEW_T_IMAGE_COLOR elif gallery_type == "non-h": return app_constants.GRID_VIEW_T_NON_H_COLOR elif gallery_type == "cosplay": return app_constants.GRID_VIEW_T_COSPLAY_COLOR else: return app_constants.GRID_VIEW_T_OTHER_COLOR def sizeHint(self, option, index): return QSize(self.W, self.H)
def paint(self, p, option, index): # QStyledItemDelegate.paint(self, p, option, index) if not index.isValid(): return item = index.internalPointer() self.updateRects(option, index) colors = outlineItemColors(item) style = qApp.style() def _rotate(angle): p.translate(self.mainRect.center()) p.rotate(angle) p.translate(-self.mainRect.center()) # Draw background cg = QPalette.ColorGroup(QPalette.Normal if option.state & QStyle.State_Enabled else QPalette.Disabled) if cg == QPalette.Normal and not option.state & QStyle.State_Active: cg = QPalette.Inactive # Selection if option.state & QStyle.State_Selected: p.save() p.setBrush(option.palette.brush(cg, QPalette.Highlight)) p.setPen(Qt.NoPen) p.drawRoundedRect(option.rect, 12, 12) p.restore() # Stack if item.isFolder() and item.childCount() > 0: p.save() p.setBrush(Qt.white) for i in reversed(range(3)): p.drawRoundedRect(self.itemRect.adjusted(2 * i, 2 * i, -2 * i, 2 * i), 10, 10) p.restore() # Background itemRect = self.itemRect p.save() if settings.viewSettings["Cork"]["Background"] != "Nothing": c = colors[settings.viewSettings["Cork"]["Background"]] col = mixColors(c, QColor(Qt.white), .2) p.setBrush(col) else: p.setBrush(Qt.white) pen = p.pen() pen.setWidth(2) p.setPen(pen) p.drawRoundedRect(itemRect, 10, 10) p.restore() # Title bar topRect = self.topRect p.save() if item.isFolder(): color = QColor(Qt.darkGreen) else: color = QColor(Qt.blue).lighter(175) p.setPen(Qt.NoPen) p.setBrush(color) p.setClipRegion(QRegion(topRect)) p.drawRoundedRect(itemRect, 10, 10) # p.drawRect(topRect) p.restore() # Label color if settings.viewSettings["Cork"]["Corner"] != "Nothing": p.save() color = colors[settings.viewSettings["Cork"]["Corner"]] p.setPen(Qt.NoPen) p.setBrush(color) p.setClipRegion(QRegion(self.labelRect)) p.drawRoundedRect(itemRect, 10, 10) # p.drawRect(topRect) p.restore() p.drawLine(self.labelRect.topLeft(), self.labelRect.bottomLeft()) # One line summary background lineSummary = item.data(Outline.summarySentance.value) fullSummary = item.data(Outline.summaryFull.value) if lineSummary or not fullSummary: m = self.margin r = self.mainLineRect.adjusted(-m, -m, m, m / 2) p.save() p.setPen(Qt.NoPen) p.setBrush(QColor("#EEE")) p.drawRect(r) p.restore() # Border p.save() p.setBrush(Qt.NoBrush) pen = p.pen() pen.setWidth(2) if settings.viewSettings["Cork"]["Border"] != "Nothing": col = colors[settings.viewSettings["Cork"]["Border"]] if col == Qt.transparent: col = Qt.black pen.setColor(col) p.setPen(pen) p.drawRoundedRect(itemRect, 10, 10) p.restore() # Draw the icon iconRect = self.iconRect mode = QIcon.Normal if not option.state & style.State_Enabled: mode = QIcon.Disabled elif option.state & style.State_Selected: mode = QIcon.Selected # index.data(Qt.DecorationRole).paint(p, iconRect, option.decorationAlignment, mode) icon = index.data(Qt.DecorationRole).pixmap(iconRect.size()) if settings.viewSettings["Cork"]["Icon"] != "Nothing": color = colors[settings.viewSettings["Cork"]["Icon"]] colorifyPixmap(icon, color) QIcon(icon).paint(p, iconRect, option.decorationAlignment, mode) # Draw title p.save() text = index.data() titleRect = self.titleRect if text: if settings.viewSettings["Cork"]["Text"] != "Nothing": col = colors[settings.viewSettings["Cork"]["Text"]] if col == Qt.transparent: col = Qt.black p.setPen(col) f = QFont(option.font) # f.setPointSize(f.pointSize() + 1) f.setBold(True) p.setFont(f) fm = QFontMetrics(f) elidedText = fm.elidedText(text, Qt.ElideRight, titleRect.width()) p.drawText(titleRect, Qt.AlignCenter, elidedText) p.restore() # Draw the line bottomRect = self.bottomRect p.save() # p.drawLine(itemRect.x(), iconRect.bottom() + margin, # itemRect.right(), iconRect.bottom() + margin) p.drawLine(bottomRect.topLeft(), bottomRect.topRight()) p.restore() # Lines if True: p.save() p.setPen(QColor("#EEE")) fm = QFontMetrics(option.font) h = fm.lineSpacing() l = self.mainTextRect.topLeft() + QPoint(0, h) while self.mainTextRect.contains(l): p.drawLine(l, QPoint(self.mainTextRect.right(), l.y())) l.setY(l.y() + h) p.restore() # Draw status mainRect = self.mainRect status = item.data(Outline.status.value) if status: it = mainWindow().mdlStatus.item(int(status), 0) if it != None: p.save() p.setClipRegion(QRegion(mainRect)) f = p.font() f.setPointSize(f.pointSize() + 12) f.setBold(True) p.setFont(f) p.setPen(QColor(Qt.red).lighter(175)) _rotate(-35) p.drawText(mainRect, Qt.AlignCenter, it.text()) p.restore() # Draw Summary # One line if lineSummary: p.save() f = QFont(option.font) f.setItalic(True) p.setFont(f) fm = QFontMetrics(f) elidedText = fm.elidedText(lineSummary, Qt.ElideRight, self.mainLineRect.width()) p.drawText(self.mainLineRect, Qt.AlignCenter, elidedText) p.restore() # Full summary if fullSummary: p.setFont(option.font) p.drawText(self.mainTextRect, Qt.TextWordWrap, fullSummary)
def paint(self, painter, option, index): item = index.internalPointer() colors = outlineItemColors(item) style = qApp.style() opt = QStyleOptionViewItem(option) self.initStyleOption(opt, index) iconRect = style.subElementRect(style.SE_ItemViewItemDecoration, opt) textRect = style.subElementRect(style.SE_ItemViewItemText, opt) # Background style.drawPrimitive(style.PE_PanelItemViewItem, opt, painter) if settings.viewSettings["Outline"]["Background"] != "Nothing" and not opt.state & QStyle.State_Selected: col = colors[settings.viewSettings["Outline"]["Background"]] if col != QColor(Qt.transparent): col2 = QColor(Qt.white) if opt.state & QStyle.State_Selected: col2 = opt.palette.brush(QPalette.Normal, QPalette.Highlight).color() col = mixColors(col, col2, .2) painter.save() painter.setBrush(col) painter.setPen(Qt.NoPen) rect = opt.rect if self._view: r2 = self._view.visualRect(index) rect = self._view.viewport().rect() rect.setLeft(r2.left()) rect.setTop(r2.top()) rect.setBottom(r2.bottom()) painter.drawRoundedRect(rect, 5, 5) painter.restore() # Icon mode = QIcon.Normal if not opt.state & QStyle.State_Enabled: mode = QIcon.Disabled elif opt.state & QStyle.State_Selected: mode = QIcon.Selected state = QIcon.On if opt.state & QStyle.State_Open else QIcon.Off icon = opt.icon.pixmap(iconRect.size(), mode=mode, state=state) if opt.icon and settings.viewSettings["Outline"]["Icon"] != "Nothing": color = colors[settings.viewSettings["Outline"]["Icon"]] colorifyPixmap(icon, color) opt.icon = QIcon(icon) opt.icon.paint(painter, iconRect, opt.decorationAlignment, mode, state) # Text if opt.text: painter.save() if settings.viewSettings["Outline"]["Text"] != "Nothing": col = colors[settings.viewSettings["Outline"]["Text"]] if col == Qt.transparent: col = Qt.black painter.setPen(col) f = QFont(opt.font) painter.setFont(f) fm = QFontMetrics(f) elidedText = fm.elidedText(opt.text, Qt.ElideRight, textRect.width()) painter.drawText(textRect, Qt.AlignLeft, elidedText) painter.restore()
def paint(self, painter, option, index): item = index.internalPointer() colors = outlineItemColors(item) style = qApp.style() opt = QStyleOptionViewItem(option) self.initStyleOption(opt, index) iconRect = style.subElementRect(style.SE_ItemViewItemDecoration, opt) textRect = style.subElementRect(style.SE_ItemViewItemText, opt) # Background style.drawPrimitive(style.PE_PanelItemViewItem, opt, painter) if settings.viewSettings["Tree"]["Background"] != "Nothing" and not opt.state & QStyle.State_Selected: col = colors[settings.viewSettings["Tree"]["Background"]] if col != QColor(Qt.transparent): col2 = QColor(Qt.white) if opt.state & QStyle.State_Selected: col2 = opt.palette.brush(QPalette.Normal, QPalette.Highlight).color() col = mixColors(col, col2, .2) painter.save() painter.setBrush(col) painter.setPen(Qt.NoPen) rect = opt.rect if self._view: r2 = self._view.visualRect(index) rect = self._view.viewport().rect() rect.setLeft(r2.left()) rect.setTop(r2.top()) rect.setBottom(r2.bottom()) painter.drawRoundedRect(rect, 5, 5) painter.restore() # Icon mode = QIcon.Normal if not opt.state & QStyle.State_Enabled: mode = QIcon.Disabled elif opt.state & QStyle.State_Selected: mode = QIcon.Selected state = QIcon.On if opt.state & QStyle.State_Open else QIcon.Off icon = opt.icon.pixmap(iconRect.size(), mode=mode, state=state) if opt.icon and settings.viewSettings["Tree"]["Icon"] != "Nothing": color = colors[settings.viewSettings["Tree"]["Icon"]] colorifyPixmap(icon, color) opt.icon = QIcon(icon) opt.icon.paint(painter, iconRect, opt.decorationAlignment, mode, state) # Text if opt.text: painter.save() if settings.viewSettings["Tree"]["Text"] != "Nothing": col = colors[settings.viewSettings["Tree"]["Text"]] if col == Qt.transparent: col = Qt.black painter.setPen(col) f = QFont(opt.font) painter.setFont(f) fm = QFontMetrics(f) elidedText = fm.elidedText(opt.text, Qt.ElideRight, textRect.width()) painter.drawText(textRect, Qt.AlignLeft, elidedText) extraText = "" if item.isFolder() and settings.viewSettings["Tree"]["InfoFolder"] != "Nothing": if settings.viewSettings["Tree"]["InfoFolder"] == "Count": extraText = item.childCount() extraText = " [{}]".format(extraText) elif settings.viewSettings["Tree"]["InfoFolder"] == "WC": extraText = item.data(Outline.wordCount.value) extraText = " ({})".format(extraText) elif settings.viewSettings["Tree"]["InfoFolder"] == "Progress": extraText = int(toFloat(item.data(Outline.goalPercentage.value)) * 100) if extraText: extraText = " ({}%)".format(extraText) elif settings.viewSettings["Tree"]["InfoFolder"] == "Summary": extraText = item.data(Outline.summarySentance.value) if extraText: extraText = " - {}".format(extraText) if item.isText() and settings.viewSettings["Tree"]["InfoText"] != "Nothing": if settings.viewSettings["Tree"]["InfoText"] == "WC": extraText = item.data(Outline.wordCount.value) extraText = " ({})".format(extraText) elif settings.viewSettings["Tree"]["InfoText"] == "Progress": extraText = int(toFloat(item.data(Outline.goalPercentage.value)) * 100) if extraText: extraText = " ({}%)".format(extraText) elif settings.viewSettings["Tree"]["InfoText"] == "Summary": extraText = item.data(Outline.summarySentance.value) if extraText: extraText = " - {}".format(extraText) if extraText: r = QRect(textRect) r.setLeft(r.left() + fm.width(opt.text + " ")) painter.save() f = painter.font() f.setWeight(QFont.Normal) painter.setFont(f) painter.setPen(Qt.darkGray) painter.drawText(r, Qt.AlignLeft | Qt.AlignBottom, extraText) painter.restore() painter.restore()
class CustomDelegate(QStyledItemDelegate): "A custom delegate for the model/view framework" POPUP = pyqtSignal() CONTEXT_ON = False # Gallery states G_NORMAL, G_DOWNLOAD = range(2) def __init__(self, parent=None): super().__init__() QPixmapCache.setCacheLimit(app_constants.THUMBNAIL_CACHE_SIZE[0]* app_constants.THUMBNAIL_CACHE_SIZE[1]) self._painted_indexes = {} #misc.FileIcon.refresh_default_icon() self.file_icons = misc.FileIcon() if app_constants.USE_EXTERNAL_VIEWER: self.external_icon = self.file_icons.get_external_file_icon() else: self.external_icon = self.file_icons.get_default_file_icon() self.font_size = app_constants.GALLERY_FONT[1] self.font_name = app_constants.GALLERY_FONT[0] if not self.font_name: self.font_name = QWidget().font().family() self.title_font = QFont() self.title_font.setBold(True) self.title_font.setFamily(self.font_name) self.artist_font = QFont() self.artist_font.setFamily(self.font_name) if self.font_size is not 0: self.title_font.setPixelSize(self.font_size) self.artist_font.setPixelSize(self.font_size) self.title_font_m = QFontMetrics(self.title_font) self.artist_font_m = QFontMetrics(self.artist_font) t_h = self.title_font_m.height() a_h = self.artist_font_m.height() self.text_label_h = a_h + t_h * 2 self.W = app_constants.THUMB_W_SIZE self.H = app_constants.THUMB_H_SIZE + app_constants.GRIDBOX_LBL_H#self.text_label_h #+ app_constants.GRIDBOX_LBL_H def key(self, key): "Assigns an unique key to indexes" if key in self._painted_indexes: return self._painted_indexes[key] else: k = hash(key) self._painted_indexes[key] = str(k) return str(k) def paint(self, painter, option, index): assert isinstance(painter, QPainter) if index.data(Qt.UserRole+1): if app_constants.HIGH_QUALITY_THUMBS: painter.setRenderHint(QPainter.SmoothPixmapTransform) painter.setRenderHint(QPainter.Antialiasing) gallery = index.data(Qt.UserRole+1) title = gallery.title artist = gallery.artist title_color = app_constants.GRID_VIEW_TITLE_COLOR artist_color = app_constants.GRID_VIEW_ARTIST_COLOR label_color = app_constants.GRID_VIEW_LABEL_COLOR # Enable this to see the defining box #painter.drawRect(option.rect) # define font size if 20 > len(title) > 15: title_size = "font-size:{}px;".format(self.font_size) elif 30 > len(title) > 20: title_size = "font-size:{}px;".format(self.font_size-1) elif 40 > len(title) >= 30: title_size = "font-size:{}px;".format(self.font_size-2) elif 50 > len(title) >= 40: title_size = "font-size:{}px;".format(self.font_size-3) elif len(title) >= 50: title_size = "font-size:{}px;".format(self.font_size-4) else: title_size = "font-size:{}px;".format(self.font_size) if 30 > len(artist) > 20: artist_size = "font-size:{}px;".format(self.font_size) elif 40 > len(artist) >= 30: artist_size = "font-size:{}px;".format(self.font_size-1) elif len(artist) >= 40: artist_size = "font-size:{}px;".format(self.font_size-2) else: artist_size = "font-size:{}px;".format(self.font_size) #painter.setPen(QPen(Qt.NoPen)) #option.rect = option.rect.adjusted(11, 10, 0, 0) option.rect.setWidth(self.W) option.rect.setHeight(self.H) rec = option.rect.getRect() x = rec[0] y = rec[1] w = rec[2] h = rec[3] text_area = QTextDocument() text_area.setDefaultFont(option.font) text_area.setHtml(""" <head> <style> #area {{ display:flex; width:140px; height:10px }} #title {{ position:absolute; color: {4}; font-weight:bold; {0} }} #artist {{ position:absolute; color: {5}; top:20px; right:0; {1} }} </style> </head> <body> <div id="area"> <center> <div id="title">{2} </div> <div id="artist">{3} </div> </div> </center> </body> """.format(title_size, artist_size, title, artist, title_color, artist_color)) text_area.setTextWidth(w) #chapter_area = QTextDocument() #chapter_area.setDefaultFont(option.font) #chapter_area.setHtml(""" #<font color="black">{}</font> #""".format("chapter")) #chapter_area.setTextWidth(w) def center_img(width): new_x = x if width < w: diff = w - width offset = diff//2 new_x += offset return new_x # if we can't find a cached image pix_cache = QPixmapCache.find(self.key(gallery.profile)) if isinstance(pix_cache, QPixmap): self.image = pix_cache img_x = center_img(self.image.width()) if self.image.height() < self.image.width(): #to keep aspect ratio painter.drawPixmap(QPoint(img_x,y), self.image) else: painter.drawPixmap(QPoint(img_x,y), self.image) else: self.image = QPixmap(gallery.profile) img_x = center_img(self.image.width()) QPixmapCache.insert(self.key(gallery.profile), self.image) if self.image.height() < self.image.width(): #to keep aspect ratio painter.drawPixmap(QPoint(img_x,y), self.image) else: painter.drawPixmap(QPoint(img_x,y), self.image) # draw star if it's favorited if gallery.fav == 1: painter.drawPixmap(QPointF(x,y), QPixmap(app_constants.STAR_PATH)) if app_constants._REFRESH_EXTERNAL_VIEWER: if app_constants.USE_EXTERNAL_VIEWER: self.external_icon = self.file_icons.get_external_file_icon() else: self.external_icon = self.file_icons.get_default_file_icon() if gallery.state == self.G_DOWNLOAD: painter.save() dl_box = QRect(x, y, w, 20) painter.setBrush(QBrush(QColor(0,0,0,123))) painter.setPen(QColor('white')) painter.drawRect(dl_box) painter.drawText(dl_box, Qt.AlignCenter, 'Downloading...') painter.restore() else: if app_constants.DISPLAY_GALLERY_TYPE: self.type_icon = self.file_icons.get_file_icon(gallery.path) if self.type_icon and not self.type_icon.isNull(): self.type_icon.paint(painter, QRect(x+2, y+app_constants.THUMB_H_SIZE-16, 16, 16)) if app_constants.USE_EXTERNAL_PROG_ICO: if self.external_icon and not self.external_icon.isNull(): self.external_icon.paint(painter, QRect(x+w-30, y+app_constants.THUMB_H_SIZE-28, 28, 28)) def draw_text_label(lbl_h): #draw the label for text painter.save() painter.translate(x, y+app_constants.THUMB_H_SIZE) box_color = QBrush(QColor(label_color))#QColor(0,0,0,123)) painter.setBrush(box_color) rect = QRect(0, 0, w, lbl_h) #x, y, width, height painter.fillRect(rect, box_color) painter.restore() return rect if option.state & QStyle.State_MouseOver or\ option.state & QStyle.State_Selected: title_layout = self.text_layout(title, w, self.title_font, self.title_font_m) artist_layout = self.text_layout(artist, w, self.artist_font, self.artist_font_m) t_h = title_layout.boundingRect().height() a_h = artist_layout.boundingRect().height() if app_constants.GALLERY_FONT_ELIDE: lbl_rect = draw_text_label(min(t_h+a_h+3, app_constants.GRIDBOX_LBL_H)) else: lbl_rect = draw_text_label(app_constants.GRIDBOX_LBL_H) clipping = QRectF(x, y+app_constants.THUMB_H_SIZE, w, app_constants.GRIDBOX_LBL_H - 10) title_layout.draw(painter, QPointF(x, y+app_constants.THUMB_H_SIZE), clip=clipping) artist_layout.draw(painter, QPointF(x, y+app_constants.THUMB_H_SIZE+t_h), clip=clipping) #painter.fillRect(option.rect, QColor) else: if app_constants.GALLERY_FONT_ELIDE: lbl_rect = draw_text_label(self.text_label_h) else: lbl_rect = draw_text_label(app_constants.GRIDBOX_LBL_H) # draw text painter.save() alignment = QTextOption(Qt.AlignCenter) alignment.setUseDesignMetrics(True) title_rect = QRectF(0,0,w, self.title_font_m.height()) artist_rect = QRectF(0,self.artist_font_m.height(),w, self.artist_font_m.height()) painter.translate(x, y+app_constants.THUMB_H_SIZE) if app_constants.GALLERY_FONT_ELIDE: painter.setFont(self.title_font) painter.setPen(QColor(title_color)) painter.drawText(title_rect, self.title_font_m.elidedText(title, Qt.ElideRight, w-10), alignment) painter.setPen(QColor(artist_color)) painter.setFont(self.artist_font) alignment.setWrapMode(QTextOption.NoWrap) painter.drawText(artist_rect, self.title_font_m.elidedText(artist, Qt.ElideRight, w-10), alignment) else: text_area.setDefaultFont(QFont(self.font_name)) text_area.drawContents(painter) ##painter.resetTransform() painter.restore() if option.state & QStyle.State_Selected: painter.save() selected_rect = QRectF(x, y, w, lbl_rect.height()+app_constants.THUMB_H_SIZE) painter.setPen(Qt.NoPen) painter.setBrush(QBrush(QColor(164,164,164,120))) p_path = QPainterPath() p_path.setFillRule(Qt.WindingFill) p_path.addRoundedRect(selected_rect, 5,5) p_path.addRect(x,y, 20, 20) p_path.addRect(x+w-20,y, 20, 20) painter.drawPath(p_path.simplified()) #painter.fillRect(selected_rect, QColor(164,164,164,120)) painter.restore() #if option.state & QStyle.State_Selected: # painter.setPen(QPen(option.palette.highlightedText().color())) else: super().paint(painter, option, index) def text_layout(self, text, width, font, font_metrics): "Lays out wrapped text" text_option = QTextOption(Qt.AlignCenter) text_option.setUseDesignMetrics(True) text_option.setWrapMode(QTextOption.WordWrap) layout = QTextLayout(text, font) layout.setTextOption(text_option) leading = font_metrics.leading() height = 0 layout.setCacheEnabled(True) layout.beginLayout() while True: line = layout.createLine() if not line.isValid(): break line.setLineWidth(width) height += leading line.setPosition(QPointF(0, height)) height += line.height() layout.endLayout() return layout def sizeHint(self, StyleOptionViewItem, QModelIndex): return QSize(self.W, self.H)