File indexing completed on 2024-06-02 05:43:53
0001 /* 0002 SPDX-FileCopyrightText: 2009 Craig Drummond <craig@kde.org> 0003 SPDX-License-Identifier: GPL-2.0-or-later 0004 */ 0005 0006 #include "PreviewList.h" 0007 #include "Fc.h" 0008 #include "FcEngine.h" 0009 #include "FontList.h" 0010 #include <QApplication> 0011 #include <QContextMenuEvent> 0012 #include <QHeaderView> 0013 #include <QPainter> 0014 #include <QPixmapCache> 0015 #include <QStyledItemDelegate> 0016 #include <QTextStream> 0017 #include <private/qtx11extras_p.h> 0018 0019 namespace KFI 0020 { 0021 static CFcEngine *theFcEngine = nullptr; 0022 0023 CPreviewList::CPreviewList(QObject *parent) 0024 : QAbstractItemModel(parent) 0025 { 0026 } 0027 0028 QVariant CPreviewList::data(const QModelIndex &index, int role) const 0029 { 0030 if (!index.isValid()) { 0031 return QVariant(); 0032 } 0033 0034 CPreviewListItem *item = static_cast<CPreviewListItem *>(index.internalPointer()); 0035 0036 if (item) { 0037 switch (role) { 0038 case Qt::DisplayRole: 0039 return FC::createName(item->name(), item->style()); 0040 default: 0041 break; 0042 } 0043 } 0044 return QVariant(); 0045 } 0046 0047 Qt::ItemFlags CPreviewList::flags(const QModelIndex &) const 0048 { 0049 return Qt::ItemIsEnabled; 0050 } 0051 0052 QModelIndex CPreviewList::index(int row, int column, const QModelIndex &parent) const 0053 { 0054 if (!parent.isValid()) { 0055 CPreviewListItem *item = m_items.value(row); 0056 0057 if (item) { 0058 return createIndex(row, column, item); 0059 } 0060 } 0061 0062 return QModelIndex(); 0063 } 0064 0065 QModelIndex CPreviewList::parent(const QModelIndex &) const 0066 { 0067 return QModelIndex(); 0068 } 0069 0070 void CPreviewList::clear() 0071 { 0072 Q_EMIT layoutAboutToBeChanged(); 0073 qDeleteAll(m_items); 0074 m_items.clear(); 0075 Q_EMIT layoutChanged(); 0076 } 0077 0078 void CPreviewList::showFonts(const QModelIndexList &fonts) 0079 { 0080 clear(); 0081 Q_EMIT layoutAboutToBeChanged(); 0082 QModelIndex index; 0083 foreach (index, fonts) { 0084 CFontModelItem *mi = static_cast<CFontModelItem *>(index.internalPointer()); 0085 CFontItem *font = mi->parent() ? static_cast<CFontItem *>(mi) : (static_cast<CFamilyItem *>(mi))->regularFont(); 0086 0087 if (font) { 0088 m_items.append(new CPreviewListItem(font->family(), font->styleInfo(), font->isEnabled() ? QString() : font->fileName(), font->index())); 0089 } 0090 } 0091 0092 Q_EMIT layoutChanged(); 0093 } 0094 0095 class CPreviewListViewDelegate : public QStyledItemDelegate 0096 { 0097 public: 0098 CPreviewListViewDelegate(QObject *p, int previewSize) 0099 : QStyledItemDelegate(p) 0100 , m_previewSize(previewSize) 0101 { 0102 } 0103 ~CPreviewListViewDelegate() override 0104 { 0105 } 0106 0107 void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &idx) const override 0108 { 0109 CPreviewListItem *item = static_cast<CPreviewListItem *>(idx.internalPointer()); 0110 QStyleOptionViewItem opt(option); 0111 0112 opt.rect.adjust(1, constBorder - 3, 0, -(1 + m_previewSize)); 0113 0114 QStyledItemDelegate::paint(painter, opt, idx); 0115 0116 opt.rect.adjust(constBorder, option.rect.height() - (1 + m_previewSize), -constBorder, 0); 0117 painter->save(); 0118 painter->setPen(QApplication::palette().color(QPalette::Text)); 0119 QRect lineRect(opt.rect.adjusted(-1, 3, 0, 2)); 0120 painter->drawLine(lineRect.bottomLeft(), lineRect.bottomRight()); 0121 painter->setClipRect(option.rect.adjusted(constBorder, 0, -constBorder, 0)); 0122 painter->drawPixmap(opt.rect.topLeft(), getPixmap(item)); 0123 painter->restore(); 0124 } 0125 0126 QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &idx) const override 0127 { 0128 QSize sz(QStyledItemDelegate::sizeHint(option, idx)); 0129 // int pWidth(getPixmap(static_cast<CPreviewListItem *>(idx.internalPointer())).width()); 0130 int pWidth(1536); 0131 0132 return QSize((constBorder * 2) + pWidth, sz.height() + 1 + constBorder + m_previewSize); 0133 } 0134 0135 QPixmap getPixmap(CPreviewListItem *item) const 0136 { 0137 QString key; 0138 QPixmap pix; 0139 QColor text(QApplication::palette().color(QPalette::Text)); 0140 0141 QTextStream(&key) << "kfi-" << item->name() << "-" << item->style() << "-" << text.rgba(); 0142 0143 if (!QPixmapCache::find(key, &pix)) { 0144 QColor bgnd(Qt::black); 0145 0146 bgnd.setAlpha(0); 0147 // TODO: Ideally, for this preview we want the fonts to be of a set point size 0148 pix = QPixmap::fromImage( 0149 theFcEngine->drawPreview(item->file().isEmpty() ? item->name() : item->file(), item->style(), item->index(), text, bgnd, m_previewSize)); 0150 QPixmapCache::insert(key, pix); 0151 } 0152 0153 return pix; 0154 } 0155 0156 int m_previewSize; 0157 static const int constBorder = 4; 0158 }; 0159 0160 CPreviewListView::CPreviewListView(CFcEngine *eng, QWidget *parent) 0161 : QTreeView(parent) 0162 { 0163 theFcEngine = eng; 0164 0165 QFont font; 0166 int pixelSize((int)(((font.pointSizeF() * QX11Info::appDpiY()) / 72.0) + 0.5)); 0167 0168 m_model = new CPreviewList(this); 0169 setModel(m_model); 0170 setItemDelegate(new CPreviewListViewDelegate(this, (pixelSize + 12) * 3)); 0171 setSelectionMode(NoSelection); 0172 setVerticalScrollMode(ScrollPerPixel); 0173 setSortingEnabled(false); 0174 setAlternatingRowColors(false); 0175 setAcceptDrops(false); 0176 setDragEnabled(false); 0177 header()->setVisible(false); 0178 setRootIsDecorated(false); 0179 resizeColumnToContents(0); 0180 } 0181 0182 void CPreviewListView::refreshPreviews() 0183 { 0184 QPixmapCache::clear(); 0185 repaint(); 0186 resizeColumnToContents(0); 0187 } 0188 0189 void CPreviewListView::showFonts(const QModelIndexList &fonts) 0190 { 0191 m_model->showFonts(fonts); 0192 resizeColumnToContents(0); 0193 } 0194 0195 void CPreviewListView::contextMenuEvent(QContextMenuEvent *ev) 0196 { 0197 Q_EMIT showMenu(ev->pos()); 0198 } 0199 0200 }