Warning, file /office/calligra/libs/main/KoAutoSaveRecoveryDialog.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) 2012 Boudewijn Rempt <boud@valdyas.org>
0003 
0004    This library is free software; you can redistribute it and/or
0005    modify it under the terms of the GNU Library General Public
0006    License as published by the Free Software Foundation; either
0007    version 2 of the License, or (at your option) any later version.
0008 
0009    This library is distributed in the hope that it will be useful,
0010    but WITHOUT ANY WARRANTY; without even the implied warranty of
0011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0012    Library General Public License for more details.
0013 
0014    You should have received a copy of the GNU Library General Public License
0015    along with this library; see the file COPYING.LIB.  If not, write to
0016    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0017    Boston, MA 02110-1301, USA.
0018 */
0019 
0020 #include "KoAutoSaveRecoveryDialog.h"
0021 
0022 #include <KoStore.h>
0023 
0024 #include <kwidgetitemdelegate.h>
0025 #include <klocalizedstring.h>
0026 
0027 #include <QVBoxLayout>
0028 #include <QHBoxLayout>
0029 #include <QListView>
0030 #include <QAbstractTableModel>
0031 #include <QLabel>
0032 #include <QDir>
0033 #include <QFileInfo>
0034 #include <QDateTime>
0035 #include <QImage>
0036 #include <QPixmap>
0037 #include <QHeaderView>
0038 #include <QStyledItemDelegate>
0039 #include <QPainter>
0040 #include <QCheckBox>
0041 
0042 
0043 struct FileItem {
0044 
0045     FileItem() : checked(true) {}
0046 
0047     QImage thumbnail;
0048     QString name;
0049     QString date;
0050     bool checked;
0051 };
0052 
0053 class FileItemDelegate : public KWidgetItemDelegate
0054 {
0055 public:
0056 
0057     FileItemDelegate(QAbstractItemView *itemView, KoAutoSaveRecoveryDialog *dlg)
0058         : KWidgetItemDelegate(itemView, dlg)
0059         , m_parent(dlg)
0060     {
0061     }
0062 
0063     QList<QWidget*> createItemWidgets(const QModelIndex &index) const override
0064     {
0065         QWidget *page = new QWidget;
0066         QHBoxLayout *layout = new QHBoxLayout(page);
0067 
0068         QCheckBox *checkBox = new QCheckBox;
0069         checkBox->setProperty("fileitem", index.data());
0070 
0071         connect(checkBox, SIGNAL(toggled(bool)), m_parent, SLOT(toggleFileItem(bool)));
0072         QLabel *thumbnail = new QLabel;
0073         QLabel *filename = new QLabel;
0074         QLabel *dateModified = new QLabel;
0075 
0076         layout->addWidget(checkBox);
0077         layout->addWidget(thumbnail);
0078         layout->addWidget(filename);
0079         layout->addWidget(dateModified);
0080 
0081         page->setFixedSize(600, 200);
0082 
0083         return QList<QWidget*>() << page;
0084     }
0085 
0086     void updateItemWidgets(const QList<QWidget*> widgets,
0087                            const QStyleOptionViewItem &option,
0088                            const QPersistentModelIndex &index) const override
0089     {
0090         FileItem *fileItem = (FileItem*)index.data().value<void*>();
0091 
0092         QWidget* page= widgets[0];
0093         QHBoxLayout* layout = qobject_cast<QHBoxLayout*>(page->layout());
0094         QCheckBox *checkBox = qobject_cast<QCheckBox*>(layout->itemAt(0)->widget());
0095         QLabel *thumbnail = qobject_cast<QLabel*>(layout->itemAt(1)->widget());
0096         QLabel *filename = qobject_cast<QLabel*>(layout->itemAt(2)->widget());
0097         QLabel *modified = qobject_cast<QLabel*>(layout->itemAt(3)->widget());
0098 
0099         checkBox->setChecked(fileItem->checked);
0100         thumbnail->setPixmap(QPixmap::fromImage(fileItem->thumbnail));
0101         filename->setText(fileItem->name);
0102         modified->setText(fileItem->date);
0103 
0104         // move the page _up_ otherwise it will draw relative to the actual position
0105         page->setGeometry(option.rect.translated(0, -option.rect.y()));
0106     }
0107 
0108     void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &/*index*/) const override
0109     {
0110         //paint background for selected or hovered item
0111         QStyleOptionViewItem opt = option;
0112         itemView()->style()->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter, 0);
0113     }
0114 
0115     QSize sizeHint(const QStyleOptionViewItem&, const QModelIndex&) const override
0116     {
0117         return QSize(600, 200);
0118     }
0119 
0120 
0121     KoAutoSaveRecoveryDialog *m_parent;
0122 };
0123 
0124 class KoAutoSaveRecoveryDialog::FileItemModel : public QAbstractListModel
0125 {
0126 public:
0127     FileItemModel(QList<FileItem*> fileItems, QObject *parent)
0128         : QAbstractListModel(parent)
0129         , m_fileItems(fileItems){}
0130 
0131     ~FileItemModel() override
0132     {
0133         qDeleteAll(m_fileItems);
0134         m_fileItems.clear();
0135     }
0136 
0137     int rowCount(const QModelIndex &/*parent*/) const override { return m_fileItems.size(); }
0138 
0139     Qt::ItemFlags flags(const QModelIndex& /*index*/) const override
0140     {
0141         Qt::ItemFlags flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable;
0142         return flags;
0143     }
0144 
0145     QVariant data(const QModelIndex& index, int role) const override
0146     {
0147         if (index.isValid() && index.row() < m_fileItems.size()) {
0148 
0149             FileItem *item = m_fileItems.at(index.row());
0150 
0151             switch (role) {
0152             case Qt::DisplayRole:
0153             {
0154                 return QVariant::fromValue<void*>((void*)item);
0155             }
0156             case Qt::SizeHintRole:
0157                 return QSize(600, 200);
0158             }
0159         }
0160         return QVariant();
0161     }
0162 
0163     bool setData(const QModelIndex& index, const QVariant& /*value*/, int role) override
0164     {
0165         if (index.isValid() && index.row() < m_fileItems.size()) {
0166             if (role == Qt::CheckStateRole) {
0167                 m_fileItems.at(index.row())->checked = !m_fileItems.at(index.row())->checked;
0168                 return true;
0169             }
0170         }
0171         return false;
0172     }
0173     QList<FileItem *> m_fileItems;
0174 };
0175 
0176 KoAutoSaveRecoveryDialog::KoAutoSaveRecoveryDialog(const QStringList &filenames, QWidget *parent) :
0177     KoDialog(parent)
0178 {
0179     setCaption(i18nc("@title:window", "Recover Files"));
0180     setMinimumSize(650, 500);
0181     QWidget *page = new QWidget(this);
0182     QVBoxLayout *layout = new QVBoxLayout(page);
0183     if (filenames.size() == 1) {
0184         layout->addWidget(new QLabel(i18n("The following autosave file can be recovered:")));
0185     }
0186     else {
0187         layout->addWidget(new QLabel(i18n("The following autosave files can be recovered:")));
0188     }
0189 
0190     m_listView = new QListView();
0191     m_listView->setAcceptDrops(false);
0192     KWidgetItemDelegate *delegate = new FileItemDelegate(m_listView, this);
0193     m_listView->setItemDelegate(delegate);
0194 
0195     QList<FileItem*> fileItems;
0196     foreach(const QString &filename, filenames) {
0197 
0198         FileItem *file = new FileItem();
0199         file->name = filename;
0200 
0201         QString path = QDir::homePath() + "/" + filename;
0202         // get thumbnail -- all calligra apps save a thumbnail
0203         KoStore* store = KoStore::createStore(path, KoStore::Read);
0204 
0205         if (store && (    store->open(QString("Thumbnails/thumbnail.png"))
0206                           || store->open(QString("preview.png")))) {
0207             // Hooray! No long delay for the user...
0208             QByteArray bytes = store->read(store->size());
0209             store->close();
0210             delete store;
0211             QImage img;
0212             img.loadFromData(bytes);
0213             file->thumbnail = img.scaled(QSize(200,200), Qt::KeepAspectRatio, Qt::SmoothTransformation);
0214         }
0215 
0216         // get the date
0217         QDateTime date = QFileInfo(path).lastModified();
0218         file->date = "(" + date.toString(Qt::LocalDate) + ")";
0219 
0220         fileItems.append(file);
0221     }
0222 
0223     m_model = new FileItemModel(fileItems, m_listView);
0224     m_listView->setModel(m_model);
0225     layout->addWidget(m_listView);
0226     setMainWidget(page);
0227 }
0228 
0229 
0230 QStringList KoAutoSaveRecoveryDialog::recoverableFiles()
0231 {
0232     QStringList files;
0233     foreach(FileItem* fileItem, m_model->m_fileItems) {
0234         if (fileItem->checked) {
0235             files << fileItem->name;
0236         }
0237     }
0238     return files;
0239 }
0240 
0241 void KoAutoSaveRecoveryDialog::toggleFileItem(bool toggle)
0242 {
0243     // I've made better man from a piece of putty and matchstick!
0244     QVariant v = sender()->property("fileitem") ;
0245     if (v.isValid()) {
0246         FileItem *fileItem = (FileItem*)v.value<void*>();
0247         fileItem->checked = toggle;
0248     }
0249 }