Warning, file /office/calligra/libs/main/KoRecentDocumentsPane.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /* This file is part of the KDE project
0002    Copyright (C) 2005-2006 Peter Simonsson <psn@linux.se>
0003    Copyright 2012 Friedrich W. H. Kossebau <kossebau@kde.org>
0004 
0005    This library is free software; you can redistribute it and/or
0006    modify it under the terms of the GNU Library General Public
0007    License as published by the Free Software Foundation; either
0008    version 2 of the License, or (at your option) any later version.
0009 
0010    This library is distributed in the hope that it will be useful,
0011    but WITHOUT ANY WARRANTY; without even the implied warranty of
0012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0013    Library General Public License for more details.
0014 
0015    You should have received a copy of the GNU Library General Public License
0016    along with this library; see the file COPYING.LIB.  If not, write to
0017    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0018    Boston, MA 02110-1301, USA.
0019 */
0020 
0021 #include "KoRecentDocumentsPane.h"
0022 
0023 #include <QFile>
0024 #include <QStandardItemModel>
0025 #include <QUrl>
0026 
0027 #include <KSharedConfig>
0028 #include <KConfigGroup>
0029 #include <kfileitem.h>
0030 #include <kio/previewjob.h>
0031 
0032 #include <KoIcon.h>
0033 
0034 
0035 static const int MAX_RECENTFILES_ENTRIES = 10;
0036 
0037 
0038 enum KoRecentDocumentRoles {
0039     PreviewRole = Qt::UserRole
0040 };
0041 
0042 class KoFileListItem : public QStandardItem
0043 {
0044 public:
0045     KoFileListItem(const QIcon &icon, const QString &text, const KFileItem& item)
0046             : QStandardItem(icon, text)
0047             , m_fileItem(item){
0048     }
0049 
0050     ~KoFileListItem() override {
0051     }
0052 
0053     const KFileItem &fileItem() const {
0054         return m_fileItem;
0055     }
0056 
0057 private:
0058     KFileItem m_fileItem;
0059 };
0060 
0061 
0062 class KoRecentDocumentsPanePrivate
0063 {
0064 public:
0065     KoRecentDocumentsPanePrivate()
0066     {
0067     }
0068 
0069     ~KoRecentDocumentsPanePrivate()
0070     {
0071         foreach(KJob* job, m_previewJobs)
0072             job->kill();
0073     }
0074 
0075     QList<KJob*> m_previewJobs;
0076 };
0077 
0078 
0079 KoRecentDocumentsPane::KoRecentDocumentsPane(QWidget* parent, const QString& header)
0080         : KoDetailsPane(parent, header)
0081         , d(new KoRecentDocumentsPanePrivate)
0082 {
0083     setFocusProxy(m_documentList);
0084     m_openButton->setText(i18n("Open This Document"));
0085     m_openButton->setIcon(koIcon("document-open"));
0086 
0087     m_alwaysUseCheckBox->hide();
0088 
0089     model()->setSortRole(0); // Disable sorting
0090 
0091     // load list of recent files from config
0092     KConfigGroup config(KSharedConfig::openConfig(), "RecentFiles");
0093 
0094     QString fileKey;
0095     QString fileValue;
0096     QUrl url;
0097     QString nameValue;
0098     KFileItemList fileList;
0099     QStandardItem* rootItem = model()->invisibleRootItem();
0100 
0101     for (int i = 1; i <= MAX_RECENTFILES_ENTRIES; ++i) {
0102         fileValue = config.readPathEntry(QString("File%1").arg(i), QString());
0103 
0104         // ignore empty entries
0105         if (fileValue.isEmpty()) {
0106             continue;
0107         }
0108 
0109         url = QUrl::fromUserInput(fileValue);
0110 
0111         // ignore entries for files known to no longer exist
0112         if (url.isLocalFile() && !QFile::exists(url.toLocalFile())) {
0113             continue;
0114         }
0115         // ignore duplicated entries
0116         if (!fileList.findByUrl(url).isNull()) {
0117             continue;
0118         }
0119 
0120         nameValue = config.readPathEntry(QString("Name%1").arg(i), QString());
0121         // handle name entries with empty strings
0122         if (nameValue.isEmpty()) {
0123             nameValue = url.fileName();
0124         }
0125 
0126         KFileItem fileItem(url);
0127         fileList.prepend(fileItem);
0128         const QIcon icon = QIcon::fromTheme(fileItem.iconName());
0129         KoFileListItem* item = new KoFileListItem(icon, nameValue, fileItem);
0130         item->setEditable(false);
0131         rootItem->insertRow(0, item);
0132     }
0133 
0134 
0135     //Select the first file
0136     QModelIndex firstIndex = model()->indexFromItem(model()->item(0));
0137     m_documentList->selectionModel()->select(firstIndex, QItemSelectionModel::Select);
0138     m_documentList->selectionModel()->setCurrentIndex(firstIndex, QItemSelectionModel::Select);
0139 
0140     QStringList availablePlugins = KIO::PreviewJob::availablePlugins();
0141     KIO::PreviewJob *previewJob = KIO::filePreview(fileList, QSize(IconExtent, IconExtent), &availablePlugins);
0142 
0143     d->m_previewJobs.append(previewJob);
0144     connect(previewJob, SIGNAL(result(KJob*)), SLOT(previewResult(KJob*)));
0145     connect(previewJob, SIGNAL(gotPreview(KFileItem,QPixmap)),
0146             SLOT(updateIcon(KFileItem,QPixmap)));
0147 }
0148 
0149 KoRecentDocumentsPane::~KoRecentDocumentsPane()
0150 {
0151     delete d;
0152 }
0153 
0154 void KoRecentDocumentsPane::selectionChanged(const QModelIndex& index)
0155 {
0156     if (index.isValid()) {
0157         KoFileListItem* item = static_cast<KoFileListItem*>(model()->itemFromIndex(index));
0158         const KFileItem fileItem = item->fileItem();
0159 
0160         m_openButton->setEnabled(true);
0161         m_titleLabel->setText(item->data(Qt::DisplayRole).toString());
0162 
0163         QPixmap preview = item->data(PreviewRole).value<QPixmap>();
0164         if (preview.isNull()) {
0165             // need to fetch preview
0166             const KFileItemList fileList = KFileItemList() << fileItem;
0167             QStringList availablePlugins = KIO::PreviewJob::availablePlugins();
0168             KIO::PreviewJob *previewJob = KIO::filePreview(fileList, QSize(PreviewExtent, PreviewExtent), &availablePlugins);
0169 
0170             d->m_previewJobs.append(previewJob);
0171             connect(previewJob, SIGNAL(result(KJob*)), SLOT(previewResult(KJob*)));
0172             connect(previewJob, SIGNAL(gotPreview(KFileItem,QPixmap)),
0173                     SLOT(updatePreview(KFileItem,QPixmap)));
0174 
0175             // for now set preview to icon
0176             preview = item->icon().pixmap(PreviewExtent);
0177             if (preview.width() < PreviewExtent && preview.height() < PreviewExtent) {
0178                 preview = preview.scaled(PreviewExtent, PreviewExtent, Qt::KeepAspectRatio, Qt::SmoothTransformation);
0179             }
0180         }
0181         m_previewLabel->setPixmap(preview);
0182 
0183         if (!fileItem.isNull()) {
0184             // TODO: think about not displaying Modified/Accessed if not available
0185             QString details = QString("<center>%1<br>").arg(fileItem.url().toDisplayString(QUrl::PreferLocalFile)) +
0186                 "<table border=\"0\">" +
0187                 i18nc("File modification date and time. %1 is date time",
0188                       "<tr><td><b>Modified:</b></td><td>%1</td></tr>",
0189                       QString(fileItem.timeString(KFileItem::ModificationTime))) +
0190                 i18nc("File access date and time. %1 is date time",
0191                       "<tr><td><b>Accessed:</b></td><td>%1</td></tr>",
0192                       QString(fileItem.timeString(KFileItem::AccessTime))) +
0193                 "</table></center>";
0194             m_detailsLabel->setHtml(details);
0195         } else {
0196             m_detailsLabel->clear();
0197         }
0198     } else {
0199         m_openButton->setEnabled(false);
0200         m_titleLabel->clear();
0201         m_previewLabel->setPixmap(QPixmap());
0202         m_detailsLabel->clear();
0203     }
0204 }
0205 
0206 void KoRecentDocumentsPane::openFile()
0207 {
0208     KoDetailsPane::openFile();
0209 }
0210 
0211 void KoRecentDocumentsPane::openFile(const QModelIndex& index)
0212 {
0213     if (!index.isValid()) return;
0214 
0215     KConfigGroup cfgGrp(KSharedConfig::openConfig(), "TemplateChooserDialog");
0216     cfgGrp.writeEntry("LastReturnType", "File");
0217 
0218     KoFileListItem* item = static_cast<KoFileListItem*>(model()->itemFromIndex(index));
0219     KFileItem fileItem = item->fileItem();
0220 
0221     if (!fileItem.isNull()) {
0222         emit openUrl(fileItem.url());
0223     }
0224 }
0225 
0226 void KoRecentDocumentsPane::previewResult(KJob* job)
0227 {
0228     d->m_previewJobs.removeOne(job);
0229 }
0230 
0231 void KoRecentDocumentsPane::updatePreview(const KFileItem& fileItem, const QPixmap& preview)
0232 {
0233     if (preview.isNull()) {
0234         return;
0235     }
0236 
0237     QStandardItem* rootItem = model()->invisibleRootItem();
0238 
0239     for (int i = 0; i < rootItem->rowCount(); ++i) {
0240         KoFileListItem* item = static_cast<KoFileListItem*>(rootItem->child(i));
0241         if (item->fileItem().url() == fileItem.url()) {
0242             item->setData(preview, PreviewRole);
0243 
0244             if (m_documentList->selectionModel()->currentIndex() == item->index()) {
0245                 m_previewLabel->setPixmap(preview);
0246             }
0247 
0248             break;
0249         }
0250     }
0251 }
0252 
0253 void KoRecentDocumentsPane::updateIcon(const KFileItem& fileItem, const QPixmap& pixmap)
0254 {
0255     if (pixmap.isNull()) {
0256         return;
0257     }
0258 
0259     QStandardItem *rootItem = model()->invisibleRootItem();
0260 
0261     for (int i = 0; i < rootItem->rowCount(); ++i) {
0262         KoFileListItem *item = static_cast<KoFileListItem*>(rootItem->child(i));
0263         if (item->fileItem().url() == fileItem.url()) {
0264             // ensure squareness
0265             QImage icon = pixmap.toImage();
0266             icon = icon.convertToFormat(QImage::Format_ARGB32);
0267             icon = icon.copy((icon.width() - IconExtent) / 2, (icon.height() - IconExtent) / 2, IconExtent, IconExtent);
0268 
0269             item->setIcon(QIcon(QPixmap::fromImage(icon)));
0270 
0271             break;
0272         }
0273     }
0274 }