File indexing completed on 2024-05-12 05:12:46

0001 /*
0002     This file is part of Akonadi.
0003 
0004     SPDX-FileCopyrightText: 2009 Till Adam <adam@kde.org>
0005 
0006     SPDX-License-Identifier: GPL-2.0-or-later
0007 */
0008 
0009 #include "jobtrackerwidget.h"
0010 #include <QCheckBox>
0011 
0012 #include "jobtrackerfilterproxymodel.h"
0013 #include "jobtrackermodel.h"
0014 #include "jobtrackersearchwidget.h"
0015 
0016 #include <KLocalizedString>
0017 
0018 #include <Akonadi/ControlGui>
0019 
0020 #include <QApplication>
0021 #include <QClipboard>
0022 #include <QFile>
0023 #include <QFileDialog>
0024 #include <QHeaderView>
0025 #include <QMenu>
0026 #include <QPushButton>
0027 #include <QTreeView>
0028 #include <QVBoxLayout>
0029 
0030 class JobTrackerWidgetPrivate
0031 {
0032 public:
0033     JobTrackerModel *model = nullptr;
0034     QTreeView *tv = nullptr;
0035     JobTrackerFilterProxyModel *filterProxyModel = nullptr;
0036     JobTrackerSearchWidget *searchLineEditWidget = nullptr;
0037 };
0038 
0039 JobTrackerWidget::JobTrackerWidget(const char *name, QWidget *parent, const QString &checkboxText)
0040     : QWidget(parent)
0041     , d(new JobTrackerWidgetPrivate)
0042 {
0043     d->model = new JobTrackerModel(name, this);
0044 
0045     auto layout = new QVBoxLayout(this);
0046 
0047     auto enableCB = new QCheckBox(this);
0048     enableCB->setText(checkboxText);
0049     connect(enableCB, &QAbstractButton::toggled, d->model, &JobTrackerModel::setEnabled);
0050     layout->addWidget(enableCB);
0051 
0052     d->searchLineEditWidget = new JobTrackerSearchWidget(this);
0053     layout->addWidget(d->searchLineEditWidget);
0054     connect(d->searchLineEditWidget, &JobTrackerSearchWidget::searchTextChanged, this, &JobTrackerWidget::textFilterChanged);
0055     connect(d->searchLineEditWidget, &JobTrackerSearchWidget::columnChanged, this, &JobTrackerWidget::searchColumnChanged);
0056     connect(d->searchLineEditWidget, &JobTrackerSearchWidget::selectOnlyErrorChanged, this, &JobTrackerWidget::selectOnlyErrorChanged);
0057     d->filterProxyModel = new JobTrackerFilterProxyModel(this);
0058     d->filterProxyModel->setSourceModel(d->model);
0059 
0060     d->tv = new QTreeView(this);
0061     d->tv->setModel(d->filterProxyModel);
0062     d->tv->expandAll();
0063     d->tv->setAlternatingRowColors(true);
0064     d->tv->setContextMenuPolicy(Qt::CustomContextMenu);
0065     // too slow with many jobs:
0066     // tv->header()->setResizeMode( QHeaderView::ResizeToContents );
0067     connect(d->model, &JobTrackerModel::modelReset, d->tv, &QTreeView::expandAll);
0068     connect(d->tv, &QTreeView::customContextMenuRequested, this, &JobTrackerWidget::contextMenu);
0069     layout->addWidget(d->tv);
0070     d->model->setEnabled(false); // since it can be slow, default to off
0071 
0072     auto layout2 = new QHBoxLayout;
0073     auto button = new QPushButton(i18n("Save to file..."), this);
0074     connect(button, &QAbstractButton::clicked, this, &JobTrackerWidget::slotSaveToFile);
0075     layout2->addWidget(button);
0076     layout2->addStretch(1);
0077     layout->addLayout(layout2);
0078 
0079     Akonadi::ControlGui::widgetNeedsAkonadi(this);
0080 }
0081 
0082 JobTrackerWidget::~JobTrackerWidget() = default;
0083 
0084 void JobTrackerWidget::selectOnlyErrorChanged(bool state)
0085 {
0086     d->filterProxyModel->setShowOnlyFailed(state);
0087     d->tv->expandAll();
0088 }
0089 
0090 void JobTrackerWidget::searchColumnChanged(int index)
0091 {
0092     d->filterProxyModel->setSearchColumn(index);
0093     d->tv->expandAll();
0094 }
0095 
0096 void JobTrackerWidget::textFilterChanged(const QString &str)
0097 {
0098     d->filterProxyModel->setFilterFixedString(str);
0099     d->tv->expandAll();
0100 }
0101 
0102 void JobTrackerWidget::contextMenu(const QPoint & /*pos*/)
0103 {
0104     QMenu menu;
0105     menu.addAction(i18n("Clear View"), d->model, &JobTrackerModel::resetTracker);
0106     menu.addSeparator();
0107     menu.addAction(i18n("Copy Info"), this, &JobTrackerWidget::copyJobInfo);
0108     menu.addSeparator();
0109     menu.addAction(i18n("Collapse All"), this, &JobTrackerWidget::collapseAll);
0110     menu.addAction(i18n("Expand All"), this, &JobTrackerWidget::expandAll);
0111 
0112     menu.exec(QCursor::pos());
0113 }
0114 
0115 void JobTrackerWidget::expandAll()
0116 {
0117     d->tv->expandAll();
0118 }
0119 
0120 void JobTrackerWidget::collapseAll()
0121 {
0122     d->tv->collapseAll();
0123 }
0124 
0125 void JobTrackerWidget::copyJobInfo()
0126 {
0127     QModelIndex index = d->tv->currentIndex();
0128     if (index.isValid()) {
0129         const QModelIndex newIndex = d->model->index(index.row(), 6, index.parent());
0130         QClipboard *cb = QApplication::clipboard();
0131         cb->setText(newIndex.data().toString(), QClipboard::Clipboard);
0132     }
0133 }
0134 
0135 void JobTrackerWidget::slotSaveToFile()
0136 {
0137     const QString fileName = QFileDialog::getSaveFileName(this, QString(), QString(), QString());
0138     if (fileName.isEmpty()) {
0139         return;
0140     }
0141 
0142     QFile file(fileName);
0143     if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
0144         return;
0145     }
0146 
0147     file.write("Job ID\t\tCreated\t\tWait Time\tJob Duration\tJob Type\t\tState\tInfo\n");
0148 
0149     writeRows(QModelIndex(), file, 0);
0150 
0151     file.close();
0152 }
0153 
0154 void JobTrackerWidget::writeRows(const QModelIndex &parent, QFile &file, int indentLevel)
0155 {
0156     for (int row = 0; row < d->model->rowCount(parent); ++row) {
0157         QByteArray data;
0158         for (int tabs = 0; tabs < indentLevel; ++tabs) {
0159             data += '\t';
0160         }
0161         const int columnCount = d->model->columnCount(parent);
0162         for (int column = 0; column < columnCount; ++column) {
0163             const QModelIndex index = d->model->index(row, column, parent);
0164             data += index.data().toByteArray();
0165             if (column < columnCount - 1) {
0166                 data += '\t';
0167             }
0168         }
0169         data += '\n';
0170         file.write(data);
0171 
0172         const QModelIndex index = d->model->index(row, 0, parent);
0173         writeRows(index, file, indentLevel + 1);
0174     }
0175 }
0176 
0177 #include "moc_jobtrackerwidget.cpp"