File indexing completed on 2024-04-28 04:21:03
0001 // SPDX-FileCopyrightText: 2012-2020 The KPhotoAlbum Development Team 0002 // SPDX-FileCopyrightText: 2021 Johannes Zarl-Zierl <johannes@zarl-zierl.at> 0003 // 0004 // SPDX-License-Identifier: GPL-2.0-or-later 0005 0006 #include "Grid.h" 0007 0008 #include <kpaexif/Info.h> 0009 0010 #include <kpabase/SettingsData.h> 0011 0012 #include <QColor> 0013 #include <QGridLayout> 0014 #include <QLabel> 0015 #include <QPainter> 0016 #include <QPalette> 0017 #include <QResizeEvent> 0018 #include <QScrollBar> 0019 #include <QTimer> 0020 0021 Exif::Grid::Grid(QWidget *parent) 0022 : QScrollArea(parent) 0023 { 0024 setFocusPolicy(Qt::WheelFocus); 0025 setWidgetResizable(true); 0026 setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); 0027 viewport()->installEventFilter(this); 0028 setMinimumSize(800, 400); 0029 } 0030 0031 class Background : public QWidget 0032 { 0033 protected: 0034 void paintEvent(QPaintEvent *event) override 0035 { 0036 QPainter painter(this); 0037 painter.fillRect(event->rect(), QColor(palette().window().color())); 0038 } 0039 }; 0040 0041 void Exif::Grid::setupUI(const QString &charset) 0042 { 0043 delete this->widget(); 0044 m_labels.clear(); 0045 Background *widget = new Background; 0046 0047 QGridLayout *layout = new QGridLayout(widget); 0048 layout->setSpacing(0); 0049 int row = 0; 0050 0051 const QMap<QString, QStringList> map = Exif::Info::instance()->infoForDialog(m_fileName, charset); 0052 const StringSet groups = exifGroups(map); 0053 0054 for (const QString &group : groups) { 0055 layout->addWidget(headerLabel(group), row++, 0, 1, 4); 0056 0057 // Items of group 0058 const QMap<QString, QStringList> items = itemsForGroup(group, map); 0059 QStringList sorted = items.keys(); 0060 sorted.sort(); 0061 int elements = sorted.size(); 0062 int perCol = (elements + 1) / 2; 0063 int count = 0; 0064 for (const QString &key : sorted) { 0065 const int subrow = (count % perCol); 0066 const QPalette::ColorRole role = (subrow & 1) ? QPalette::Base : QPalette::AlternateBase; 0067 QPair<QLabel *, QLabel *> pair = infoLabelPair(exifNameNoGroup(key), items[key].join(QLatin1String(", ")), role); 0068 0069 int col = (count / perCol) * 2; 0070 layout->addWidget(pair.first, row + subrow, col); 0071 layout->addWidget(pair.second, row + subrow, col + 1); 0072 count++; 0073 } 0074 row += perCol; 0075 } 0076 0077 setWidget(widget); 0078 widget->show(); 0079 QTimer::singleShot(0, this, SLOT(updateWidgetSize())); 0080 } 0081 0082 QLabel *Exif::Grid::headerLabel(const QString &title) 0083 { 0084 QLabel *label = new QLabel(title); 0085 0086 label->setBackgroundRole(QPalette::Dark); 0087 label->setForegroundRole(QPalette::BrightText); 0088 label->setAutoFillBackground(true); 0089 label->setAlignment(Qt::AlignCenter); 0090 0091 return label; 0092 } 0093 0094 QPair<QLabel *, QLabel *> Exif::Grid::infoLabelPair(const QString &title, const QString &value, const QPalette::ColorRole backgroundRole) 0095 { 0096 QLabel *keyLabel = new QLabel(title); 0097 QLabel *valueLabel = new QLabel(value); 0098 0099 keyLabel->setBackgroundRole(backgroundRole); 0100 valueLabel->setBackgroundRole(backgroundRole); 0101 keyLabel->setAutoFillBackground(true); 0102 valueLabel->setAutoFillBackground(true); 0103 m_labels.append(qMakePair(keyLabel, valueLabel)); 0104 return qMakePair(keyLabel, valueLabel); 0105 } 0106 0107 void Exif::Grid::updateWidgetSize() 0108 { 0109 widget()->setFixedSize(viewport()->width(), widget()->height()); 0110 } 0111 0112 StringSet Exif::Grid::exifGroups(const QMap<QString, QStringList> &exifInfo) 0113 { 0114 StringSet result; 0115 for (QMap<QString, QStringList>::ConstIterator it = exifInfo.begin(); it != exifInfo.end(); ++it) { 0116 result.insert(groupName(it.key())); 0117 } 0118 return result; 0119 } 0120 0121 QMap<QString, QStringList> Exif::Grid::itemsForGroup(const QString &group, const QMap<QString, QStringList> &exifInfo) 0122 { 0123 QMap<QString, QStringList> result; 0124 for (QMap<QString, QStringList>::ConstIterator it = exifInfo.begin(); it != exifInfo.end(); ++it) { 0125 if (groupName(it.key()) == group) 0126 result.insert(it.key(), it.value()); 0127 } 0128 return result; 0129 } 0130 0131 QString Exif::Grid::groupName(const QString &exifName) 0132 { 0133 QStringList list = exifName.split(QString::fromLatin1(".")); 0134 list.pop_back(); 0135 return list.join(QString::fromLatin1(".")); 0136 } 0137 0138 QString Exif::Grid::exifNameNoGroup(const QString &fullName) 0139 { 0140 return fullName.split(QString::fromLatin1(".")).last(); 0141 } 0142 0143 void Exif::Grid::scroll(int dy) 0144 { 0145 verticalScrollBar()->setValue(verticalScrollBar()->value() + dy); 0146 } 0147 0148 void Exif::Grid::updateSearchString(const QString &search) 0149 { 0150 for (QPair<QLabel *, QLabel *> tuple : m_labels) { 0151 const bool matches = tuple.first->text().contains(search, Qt::CaseInsensitive) && search.length() != 0; 0152 const auto fgRole = matches ? QPalette::HighlightedText : QPalette::Text; 0153 const auto bgRole = matches ? QPalette::Highlight : QPalette::Base; 0154 tuple.first->setForegroundRole(fgRole); 0155 tuple.first->setBackgroundRole(bgRole); 0156 tuple.second->setForegroundRole(fgRole); 0157 tuple.second->setBackgroundRole(bgRole); 0158 QFont fnt = tuple.first->font(); 0159 fnt.setBold(matches); 0160 tuple.first->setFont(fnt); 0161 tuple.second->setFont(fnt); 0162 } 0163 } 0164 0165 void Exif::Grid::keyPressEvent(QKeyEvent *e) 0166 { 0167 switch (e->key()) { 0168 case Qt::Key_Down: 0169 scroll(20); 0170 return; 0171 case Qt::Key_Up: 0172 scroll(-20); 0173 return; 0174 case Qt::Key_PageDown: 0175 scroll(viewport()->height() - 20); 0176 return; 0177 case Qt::Key_PageUp: 0178 scroll(-(viewport()->height() - 20)); 0179 return; 0180 case Qt::Key_Escape: 0181 QScrollArea::keyPressEvent(e); // Propagate to close dialog. 0182 return; 0183 } 0184 } 0185 0186 bool Exif::Grid::eventFilter(QObject *object, QEvent *event) 0187 { 0188 if (object == viewport() && event->type() == QEvent::Resize) { 0189 QResizeEvent *re = static_cast<QResizeEvent *>(event); 0190 widget()->setFixedSize(re->size().width(), widget()->height()); 0191 } 0192 return false; 0193 } 0194 0195 void Exif::Grid::setFileName(const DB::FileName &fileName) 0196 { 0197 m_fileName = fileName; 0198 setupUI(Settings::SettingsData::instance()->iptcCharset()); 0199 } 0200 // vi:expandtab:tabstop=4 shiftwidth=4: 0201 0202 #include "moc_Grid.cpp"