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"