File indexing completed on 2025-01-05 03:56:39
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 2009-05-26 0007 * Description : History view. 0008 * 0009 * SPDX-FileCopyrightText: 2009-2024 by Gilles Caulier <caulier dot gilles at gmail dot com> 0010 * 0011 * SPDX-License-Identifier: GPL-2.0-or-later 0012 * 0013 * ============================================================ */ 0014 0015 #include "dhistoryview.h" 0016 0017 // Qt includes 0018 0019 #include <QHeaderView> 0020 #include <QPixmap> 0021 #include <QStringList> 0022 #include <QMouseEvent> 0023 #include <QMimeData> 0024 #include <QClipboard> 0025 #include <QTime> 0026 #include <QApplication> 0027 #include <QMenu> 0028 #include <QAction> 0029 #include <QIcon> 0030 0031 // KDE includes 0032 0033 #include <klocalizedstring.h> 0034 0035 namespace Digikam 0036 { 0037 0038 class Q_DECL_HIDDEN DHistoryViewItem : public QTreeWidgetItem 0039 { 0040 public: 0041 0042 DHistoryViewItem(QTreeWidget* const parent, const QString& msg, DHistoryView::EntryType type, const QVariant& metadata) 0043 : QTreeWidgetItem(parent, QStringList()), 0044 m_metadata (metadata) 0045 { 0046 switch (type) 0047 { 0048 case DHistoryView::StartingEntry: 0049 { 0050 setIcon(0, QIcon::fromTheme(QLatin1String("system-run"))); 0051 break; 0052 } 0053 0054 case DHistoryView::SuccessEntry: 0055 { 0056 setIcon(0, QIcon::fromTheme(QLatin1String("dialog-ok-apply"))); 0057 break; 0058 } 0059 0060 case DHistoryView::WarningEntry: 0061 { 0062 setIcon(0, QIcon::fromTheme(QLatin1String("dialog-warning"))); 0063 setForeground(2, QBrush(QColor(Qt::darkYellow))); 0064 break; 0065 } 0066 0067 case DHistoryView::ErrorEntry: 0068 { 0069 setIcon(0, QIcon::fromTheme(QLatin1String("dialog-error"))); 0070 setForeground(2, QBrush(QColor(Qt::red))); 0071 break; 0072 } 0073 0074 case DHistoryView::ProgressEntry: 0075 { 0076 setIcon(0, QIcon::fromTheme(QLatin1String("dialog-information"))); 0077 break; 0078 } 0079 0080 case DHistoryView::CancelEntry: 0081 { 0082 setIcon(0, QIcon::fromTheme(QLatin1String("dialog-cancel"))); 0083 setForeground(2, QBrush(QColor(Qt::darkBlue))); 0084 break; 0085 } 0086 0087 default: 0088 { 0089 setIcon(0, QIcon::fromTheme(QLatin1String("dialog-information"))); 0090 break; 0091 } 0092 } 0093 0094 setText(1, QTime::currentTime().toString(Qt::ISODate)); 0095 setText(2, msg); 0096 } 0097 0098 QVariant metadata() const 0099 { 0100 return m_metadata; 0101 } 0102 0103 private: 0104 0105 QVariant m_metadata; 0106 0107 private: 0108 0109 Q_DISABLE_COPY(DHistoryViewItem) 0110 }; 0111 0112 // --------------------------------------------------------------------------- 0113 0114 DHistoryView::DHistoryView(QWidget* const parent) 0115 : QTreeWidget(parent) 0116 { 0117 qRegisterMetaType<EntryType>("DHistoryView::EntryType"); 0118 0119 setContextMenuPolicy(Qt::CustomContextMenu); 0120 setIconSize(QSize(22, 22)); 0121 setSelectionMode(QAbstractItemView::SingleSelection); 0122 setSortingEnabled(false); 0123 setAllColumnsShowFocus(true); 0124 setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); 0125 setColumnCount(3); 0126 setHeaderHidden(true); 0127 setRootIsDecorated(false); 0128 setUniformRowHeights(true); 0129 setDragEnabled(true); 0130 viewport()->setMouseTracking(true); 0131 header()->setSectionResizeMode(0, QHeaderView::ResizeToContents); // Icon 0132 header()->setSectionResizeMode(1, QHeaderView::ResizeToContents); // Time 0133 header()->setSectionResizeMode(2, QHeaderView::Stretch); // Message 0134 0135 connect(this, SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)), 0136 this, SLOT(slotItemDoubleClicked(QTreeWidgetItem*))); 0137 0138 connect(this, SIGNAL(customContextMenuRequested(QPoint)), 0139 this, SLOT(slotContextMenu())); 0140 } 0141 0142 DHistoryView::~DHistoryView() 0143 { 0144 } 0145 0146 void DHistoryView::slotContextMenu() 0147 { 0148 QMenu popmenu(this); 0149 QAction* const action = new QAction(QIcon::fromTheme(QLatin1String("edit-copy")), i18n("Copy to Clipboard"), this); 0150 0151 connect(action, SIGNAL(triggered(bool)), 0152 this, SLOT(slotCopy2ClipBoard())); 0153 0154 popmenu.addAction(action); 0155 popmenu.exec(QCursor::pos()); 0156 } 0157 0158 void DHistoryView::slotCopy2ClipBoard() 0159 { 0160 QString textInfo; 0161 0162 QTreeWidgetItemIterator it(this); 0163 0164 while (*it) 0165 { 0166 textInfo.append((*it)->text(1)); 0167 textInfo.append(QLatin1String(" :: ")); 0168 textInfo.append((*it)->text(2)); 0169 textInfo.append(QLatin1Char('\n')); 0170 ++it; 0171 } 0172 0173 QMimeData* const mimeData = new QMimeData(); 0174 mimeData->setText(textInfo); 0175 QApplication::clipboard()->setMimeData(mimeData, QClipboard::Clipboard); 0176 } 0177 0178 void DHistoryView::addEntry(const QString& msg, EntryType type, const QVariant& metadata) 0179 { 0180 DHistoryViewItem* const item = new DHistoryViewItem(this, msg, type, metadata); 0181 0182 // Dispatch events to Qt loop in case of bombarding of messages. See bug #338629 0183 0184 qApp->processEvents(); 0185 0186 if (item) 0187 { 0188 setCurrentItem(item); 0189 } 0190 } 0191 0192 void DHistoryView::slotItemDoubleClicked(QTreeWidgetItem* item) 0193 { 0194 DHistoryViewItem* const lvi = dynamic_cast<DHistoryViewItem*>(item); 0195 0196 if (lvi) 0197 { 0198 if (!lvi->metadata().isNull()) 0199 { 0200 Q_EMIT signalEntryClicked(lvi->metadata()); 0201 } 0202 } 0203 } 0204 0205 void DHistoryView::mouseMoveEvent(QMouseEvent* e) 0206 { 0207 DHistoryViewItem* const lvi = dynamic_cast<DHistoryViewItem*>(itemAt(e->pos())); 0208 0209 if (lvi) 0210 { 0211 if (!lvi->metadata().isNull()) 0212 { 0213 setCursor(Qt::PointingHandCursor); 0214 } 0215 else 0216 { 0217 unsetCursor(); 0218 } 0219 } 0220 else 0221 { 0222 unsetCursor(); 0223 } 0224 0225 QTreeWidget::mouseMoveEvent(e); 0226 } 0227 0228 } // namespace Digikam 0229 0230 #include "moc_dhistoryview.cpp"