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"