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 }