Warning, file /office/calligra/libs/widgets/KoDocumentInfoDlg.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) 2000 Simon Hausmann <hausmann@kde.org>
0003                  2006 Martin Pfeiffer <hubipete@gmx.net>
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 "KoDocumentInfoDlg.h"
0022 
0023 #include "ui_koDocumentInfoAboutWidget.h"
0024 #include "ui_koDocumentInfoAuthorWidget.h"
0025 
0026 #include "KoDocumentInfo.h"
0027 #include "KoDocumentBase.h"
0028 #include "KoGlobal.h"
0029 #include <KoEncryptionChecker.h>
0030 #include "KoPageWidgetItem.h"
0031 #include <KoDocumentRdfBase.h>
0032 #include <KoIcon.h>
0033 
0034 #include <klocalizedstring.h>
0035 #include <kiconloader.h>
0036 
0037 #include <kmessagebox.h>
0038 #include <kmainwindow.h>
0039 #include <KoDialog.h>
0040 
0041 #include <QUrl>
0042 #include <QLineEdit>
0043 #include <QDateTime>
0044 #include <QMimeDatabase>
0045 #include <QMimeType>
0046 
0047 
0048 // see KoIcon.h
0049 #define koSmallIcon(name) (SmallIcon(QStringLiteral(name)))
0050 
0051 
0052 class KoPageWidgetItemAdapter : public KPageWidgetItem
0053 {
0054 Q_OBJECT
0055 public:
0056     KoPageWidgetItemAdapter(KoPageWidgetItem *item)
0057       : KPageWidgetItem(item->widget(), item->name())
0058       , m_item(item)
0059     {
0060         setHeader(item->name());
0061         setIcon(QIcon::fromTheme(item->iconName()));
0062     }
0063     ~KoPageWidgetItemAdapter() override { delete m_item; }
0064 
0065     bool shouldDialogCloseBeVetoed() { return m_item->shouldDialogCloseBeVetoed(); }
0066     void apply() { m_item->apply(); }
0067 
0068 private:
0069     KoPageWidgetItem * const m_item;
0070 };
0071 
0072 
0073 class KoDocumentInfoDlg::KoDocumentInfoDlgPrivate
0074 {
0075 public:
0076     KoDocumentInfoDlgPrivate() :
0077         toggleEncryption(false),
0078         applyToggleEncryption(false),
0079         documentSaved(false) {}
0080     ~KoDocumentInfoDlgPrivate() = default;
0081 
0082     KoDocumentInfo* info;
0083     QList<KPageWidgetItem*> pages;
0084     Ui::KoDocumentInfoAboutWidget* aboutUi;
0085     Ui::KoDocumentInfoAuthorWidget* authorUi;
0086 
0087     bool toggleEncryption;
0088     bool applyToggleEncryption;
0089     bool documentSaved;
0090 };
0091 
0092 
0093 KoDocumentInfoDlg::KoDocumentInfoDlg(QWidget* parent, KoDocumentInfo* docInfo)
0094     : KPageDialog(parent)
0095     , d(new KoDocumentInfoDlgPrivate)
0096 {
0097     d->info = docInfo;
0098 
0099     setWindowTitle(i18n("Document Information"));
0100 //    setInitialSize(QSize(500, 500));
0101     setFaceType(KPageDialog::List);
0102     setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
0103     button(QDialogButtonBox::Ok)->setDefault(true);
0104 
0105     d->aboutUi = new Ui::KoDocumentInfoAboutWidget();
0106     QWidget *infodlg = new QWidget();
0107     d->aboutUi->setupUi(infodlg);
0108     if (!KoEncryptionChecker::isEncryptionSupported()) {
0109         d->aboutUi->lblEncryptedDesc->setVisible(false);
0110         d->aboutUi->lblEncrypted->setVisible(false);
0111         d->aboutUi->pbEncrypt->setVisible(false);
0112         d->aboutUi->lblEncryptedPic->setVisible(false);
0113     }
0114     d->aboutUi->cbLanguage->addItems(KoGlobal::listOfLanguages());
0115     d->aboutUi->cbLanguage->setCurrentIndex(-1);
0116 
0117     KPageWidgetItem *page = new KPageWidgetItem(infodlg, i18n("General"));
0118     page->setHeader(i18n("General"));
0119 
0120     // Ugly hack, the mimetype should be a parameter, instead
0121     KoDocumentBase* doc = dynamic_cast< KoDocumentBase* >(d->info->parent());
0122     if (doc) {
0123         QMimeDatabase db;
0124         QMimeType mime = db.mimeTypeForName(doc->mimeType());
0125         if (mime.isValid()) {
0126             page->setIcon(QIcon::fromTheme(mime.iconName()));
0127         }
0128     } else {
0129         // hide all entries not used in pages for KoDocumentInfoPropsPage
0130         d->aboutUi->filePathInfoLabel->setVisible(false);
0131         d->aboutUi->filePathLabel->setVisible(false);
0132         d->aboutUi->filePathSeparatorLine->setVisible(false);
0133         d->aboutUi->lblTypeDesc->setVisible(false);
0134         d->aboutUi->lblType->setVisible(false);
0135     }
0136     addPage(page);
0137     d->pages.append(page);
0138 
0139     initAboutTab();
0140 
0141     d->authorUi = new Ui::KoDocumentInfoAuthorWidget();
0142     QWidget *authordlg = new QWidget();
0143     d->authorUi->setupUi(authordlg);
0144     page = new KPageWidgetItem(authordlg, i18n("Author"));
0145     page->setHeader(i18n("Last saved by"));
0146     page->setIcon(koIcon("user-identity"));
0147     addPage(page);
0148     d->pages.append(page);
0149 
0150     initAuthorTab();
0151 }
0152 
0153 KoDocumentInfoDlg::~KoDocumentInfoDlg()
0154 {
0155     delete d->authorUi;
0156     delete d->aboutUi;
0157     delete d;
0158 }
0159 
0160 void KoDocumentInfoDlg::accept()
0161 {
0162     // check if any pages veto the close
0163     foreach(KPageWidgetItem* item, d->pages) {
0164         KoPageWidgetItemAdapter *page = dynamic_cast<KoPageWidgetItemAdapter*>(item);
0165         if (page) {
0166             if (page->shouldDialogCloseBeVetoed()) {
0167                 return;
0168             }
0169         }
0170     }
0171 
0172     // all fine, go and apply
0173     saveAboutData();
0174     foreach(KPageWidgetItem* item, d->pages) {
0175         KoPageWidgetItemAdapter *page = dynamic_cast<KoPageWidgetItemAdapter*>(item);
0176         if (page) {
0177             page->apply();
0178         }
0179     }
0180 
0181     KPageDialog::accept();
0182 }
0183 
0184 bool KoDocumentInfoDlg::isDocumentSaved()
0185 {
0186     return d->documentSaved;
0187 }
0188 
0189 void KoDocumentInfoDlg::initAboutTab()
0190 {
0191     KoDocumentBase* doc = dynamic_cast< KoDocumentBase* >(d->info->parent());
0192 
0193     if (doc) {
0194         d->aboutUi->filePathLabel->setText(doc->localFilePath());
0195     }
0196 
0197     d->aboutUi->leTitle->setText(d->info->aboutInfo("title"));
0198     d->aboutUi->leSubject->setText(d->info->aboutInfo("subject"));
0199     QString language = KoGlobal::languageFromTag(d->info->aboutInfo("language"));
0200     d->aboutUi->cbLanguage->setCurrentIndex(d->aboutUi->cbLanguage->findText(language));
0201 
0202     d->aboutUi->leKeywords->setToolTip(i18n("Use ';' (Example: Office;KDE;Calligra)"));
0203     if (!d->info->aboutInfo("keyword").isEmpty())
0204         d->aboutUi->leKeywords->setText(d->info->aboutInfo("keyword"));
0205 
0206     d->aboutUi->meComments->setPlainText(d->info->aboutInfo("description"));
0207     if (doc && !doc->mimeType().isEmpty()) {
0208         QMimeDatabase db;
0209         QMimeType docmime = db.mimeTypeForName(doc->mimeType());
0210         if (docmime.isValid())
0211             d->aboutUi->lblType->setText(docmime.comment());
0212     }
0213     if (!d->info->aboutInfo("creation-date").isEmpty()) {
0214         QDateTime t = QDateTime::fromString(d->info->aboutInfo("creation-date"),
0215                                             Qt::ISODate);
0216         QString s = QLocale().toString(t);
0217         d->aboutUi->lblCreated->setText(s + ", " +
0218                                         d->info->aboutInfo("initial-creator"));
0219     }
0220 
0221     if (!d->info->aboutInfo("date").isEmpty()) {
0222         QDateTime t = QDateTime::fromString(d->info->aboutInfo("date"), Qt::ISODate);
0223         QString s = QLocale().toString(t);
0224         d->aboutUi->lblModified->setText(s + ", " + d->info->authorInfo("creator"));
0225     }
0226 
0227     d->aboutUi->lblRevision->setText(d->info->aboutInfo("editing-cycles"));
0228 
0229     if (doc && (doc->supportedSpecialFormats() & KoDocumentBase::SaveEncrypted)) {
0230         if (doc->specialOutputFlag() == KoDocumentBase::SaveEncrypted) {
0231             if (d->toggleEncryption) {
0232                 d->aboutUi->lblEncrypted->setText(i18n("This document will be decrypted"));
0233                 d->aboutUi->lblEncryptedPic->setPixmap(koSmallIcon("object-unlocked"));
0234                 d->aboutUi->pbEncrypt->setText(i18n("Do not decrypt"));
0235             } else {
0236                 d->aboutUi->lblEncrypted->setText(i18n("This document is encrypted"));
0237                 d->aboutUi->lblEncryptedPic->setPixmap(koSmallIcon("object-locked"));
0238                 d->aboutUi->pbEncrypt->setText(i18n("D&ecrypt"));
0239             }
0240         } else {
0241             if (d->toggleEncryption) {
0242                 d->aboutUi->lblEncrypted->setText(i18n("This document will be encrypted."));
0243                 d->aboutUi->lblEncryptedPic->setPixmap(koSmallIcon("object-locked"));
0244                 d->aboutUi->pbEncrypt->setText(i18n("Do not encrypt"));
0245             } else {
0246                 d->aboutUi->lblEncrypted->setText(i18n("This document is not encrypted"));
0247                 d->aboutUi->lblEncryptedPic->setPixmap(koSmallIcon("object-unlocked"));
0248                 d->aboutUi->pbEncrypt->setText(i18n("&Encrypt"));
0249             }
0250         }
0251     } else {
0252         d->aboutUi->lblEncrypted->setText(i18n("This document does not support encryption"));
0253         d->aboutUi->pbEncrypt->setEnabled( false );
0254     }
0255     connect(d->aboutUi->pbReset, SIGNAL(clicked()),
0256             this, SLOT(slotResetMetaData()));
0257     connect(d->aboutUi->pbEncrypt, SIGNAL(clicked()),
0258             this, SLOT(slotToggleEncryption()));
0259 }
0260 
0261 void KoDocumentInfoDlg::initAuthorTab()
0262 {
0263     d->authorUi->fullName->setText(d->info->authorInfo("creator"));
0264     d->authorUi->initials->setText(d->info->authorInfo("initial"));
0265     d->authorUi->title->setText(d->info->authorInfo("author-title"));
0266     d->authorUi->company->setText(d->info->authorInfo("company"));
0267     d->authorUi->email->setText(d->info->authorInfo("email"));
0268     d->authorUi->phoneWork->setText(d->info->authorInfo("telephone-work"));
0269     d->authorUi->phoneHome->setText(d->info->authorInfo("telephone"));
0270     d->authorUi->fax->setText(d->info->authorInfo("fax"));
0271     d->authorUi->country->setText(d->info->authorInfo("country"));
0272     d->authorUi->postal->setText(d->info->authorInfo("postal-code"));
0273     d->authorUi->city->setText(d->info->authorInfo("city"));
0274     d->authorUi->street->setText(d->info->authorInfo("street"));
0275     d->authorUi->position->setText(d->info->authorInfo("position"));
0276 }
0277 
0278 void KoDocumentInfoDlg::saveAboutData()
0279 {
0280     d->info->setAboutInfo("keyword", d->aboutUi->leKeywords->text());
0281     d->info->setAboutInfo("title", d->aboutUi->leTitle->text());
0282     d->info->setAboutInfo("subject", d->aboutUi->leSubject->text());
0283     d->info->setAboutInfo("description", d->aboutUi->meComments->toPlainText());
0284     d->info->setAboutInfo("language", KoGlobal::tagOfLanguage(d->aboutUi->cbLanguage->currentText()));
0285     d->applyToggleEncryption = d->toggleEncryption;
0286 }
0287 
0288 void KoDocumentInfoDlg::hideEvent( QHideEvent *event )
0289 {
0290     Q_UNUSED(event);
0291 
0292     // Saving encryption implies saving the document, this is done after closing the dialog
0293     // TODO: shouldn't this be skipped if cancel is pressed?
0294     saveEncryption();
0295 }
0296 
0297 void KoDocumentInfoDlg::slotResetMetaData()
0298 {
0299     d->info->resetMetaData();
0300 
0301     if (!d->info->aboutInfo("creation-date").isEmpty()) {
0302         QDateTime t = QDateTime::fromString(d->info->aboutInfo("creation-date"),
0303                                             Qt::ISODate);
0304         QString s = QLocale().toString(t);
0305         d->aboutUi->lblCreated->setText(s + ", " +
0306                                         d->info->aboutInfo("initial-creator"));
0307     }
0308 
0309     if (!d->info->aboutInfo("date").isEmpty()) {
0310         QDateTime t = QDateTime::fromString(d->info->aboutInfo("date"), Qt::ISODate);
0311         QString s = QLocale().toString(t);
0312         d->aboutUi->lblModified->setText(s + ", " + d->info->authorInfo("creator"));
0313     }
0314 
0315     d->aboutUi->lblRevision->setText(d->info->aboutInfo("editing-cycles"));
0316 }
0317 
0318 void KoDocumentInfoDlg::slotToggleEncryption()
0319 {
0320     KoDocumentBase* doc = dynamic_cast< KoDocumentBase* >(d->info->parent());
0321     if (!doc)
0322         return;
0323 
0324     d->toggleEncryption = !d->toggleEncryption;
0325 
0326     if (doc->specialOutputFlag() == KoDocumentBase::SaveEncrypted) {
0327         if (d->toggleEncryption) {
0328             d->aboutUi->lblEncrypted->setText(i18n("This document will be decrypted"));
0329             d->aboutUi->lblEncryptedPic->setPixmap(koSmallIcon("object-unlocked"));
0330             d->aboutUi->pbEncrypt->setText(i18n("Do not decrypt"));
0331         } else {
0332             d->aboutUi->lblEncrypted->setText(i18n("This document is encrypted"));
0333             d->aboutUi->lblEncryptedPic->setPixmap(koSmallIcon("object-locked"));
0334             d->aboutUi->pbEncrypt->setText(i18n("D&ecrypt"));
0335         }
0336     } else {
0337         if (d->toggleEncryption) {
0338             d->aboutUi->lblEncrypted->setText(i18n("This document will be encrypted."));
0339             d->aboutUi->lblEncryptedPic->setPixmap(koSmallIcon("object-locked"));
0340             d->aboutUi->pbEncrypt->setText(i18n("Do not encrypt"));
0341         } else {
0342             d->aboutUi->lblEncrypted->setText(i18n("This document is not encrypted"));
0343             d->aboutUi->lblEncryptedPic->setPixmap(koSmallIcon("object-unlocked"));
0344             d->aboutUi->pbEncrypt->setText(i18n("&Encrypt"));
0345         }
0346     }
0347 }
0348 
0349 void KoDocumentInfoDlg::saveEncryption()
0350 {
0351     if (!d->applyToggleEncryption)
0352         return;
0353 
0354     KoDocumentBase* doc = dynamic_cast< KoDocumentBase* >(d->info->parent());
0355     if (!doc)
0356         return;
0357 
0358     KMainWindow* mainWindow = dynamic_cast< KMainWindow* >(parent());
0359 
0360     if (doc->specialOutputFlag() == KoDocumentBase::SaveEncrypted) {
0361         // Decrypt
0362         if (KMessageBox::warningContinueCancel(
0363                     this,
0364                     i18n("<qt>Decrypting the document will remove the password protection from it."
0365                          "<p>Do you still want to decrypt the file?</qt>"),
0366                     i18n("Confirm Decrypt"),
0367                     KGuiItem(i18n("Decrypt")),
0368                     KStandardGuiItem::cancel(),
0369                     "DecryptConfirmation"
0370                     ) != KMessageBox::Continue) {
0371             return;
0372         }
0373         bool modified = doc->isModified();
0374         doc->setOutputMimeType(doc->outputMimeType(), doc->specialOutputFlag() & ~KoDocumentBase::SaveEncrypted);
0375         if (!mainWindow) {
0376             KMessageBox::information(
0377                         this,
0378                         i18n("<qt>Your document could not be saved automatically."
0379                              "<p>To complete the decryption, please save the document.</qt>"),
0380                         i18n("Save Document"),
0381                         "DecryptSaveMessage");
0382             return;
0383         }
0384         if (modified && KMessageBox::questionYesNo(
0385                     this,
0386                     i18n("<qt>The document has been changed since it was opened. To complete the decryption the document needs to be saved."
0387                          "<p>Do you want to save the document now?</qt>"),
0388                     i18n("Save Document"),
0389                     KStandardGuiItem::save(),
0390                     KStandardGuiItem::dontSave(),
0391                     "DecryptSaveConfirmation"
0392                     ) != KMessageBox::Yes) {
0393             return;
0394         }
0395     } else {
0396         // Encrypt
0397         bool modified = doc->isModified();
0398         if (!doc->url().isEmpty() && !(doc->mimeType().startsWith("application/vnd.oasis.opendocument.") && doc->specialOutputFlag() == 0)) {
0399             QMimeDatabase db;
0400             QMimeType mime = db.mimeTypeForName(doc->mimeType());
0401             QString comment = mime.isValid() ? mime.comment() : i18n("%1 (unknown file type)", QString::fromLatin1(doc->mimeType()));
0402             if (KMessageBox::warningContinueCancel(
0403                         this,
0404                         i18n("<qt>The document is currently saved as %1. The document needs to be changed to <b>OASIS OpenDocument</b> to be encrypted."
0405                              "<p>Do you want to change the file to OASIS OpenDocument?</qt>", QString("<b>%1</b>").arg(comment)),
0406                         i18n("Change Filetype"),
0407                         KGuiItem(i18n("Change")),
0408                         KStandardGuiItem::cancel(),
0409                         "EncryptChangeFiletypeConfirmation"
0410                         ) != KMessageBox::Continue) {
0411                 return;
0412             }
0413             doc->resetURL();
0414         }
0415         doc->setMimeType(doc->nativeOasisMimeType());
0416         doc->setOutputMimeType(doc->nativeOasisMimeType(), KoDocumentBase::SaveEncrypted);
0417         if (!mainWindow) {
0418             KMessageBox::information(
0419                         this,
0420                         i18n("<qt>Your document could not be saved automatically."
0421                              "<p>To complete the encryption, please save the document.</qt>"),
0422                         i18n("Save Document"),
0423                         "EncryptSaveMessage");
0424             return;
0425         }
0426         if (modified && KMessageBox::questionYesNo(
0427                     this,
0428                     i18n("<qt>The document has been changed since it was opened. To complete the encryption the document needs to be saved."
0429                          "<p>Do you want to save the document now?</qt>"),
0430                     i18n("Save Document"),
0431                     KStandardGuiItem::save(),
0432                     KStandardGuiItem::dontSave(),
0433                     "EncryptSaveConfirmation"
0434                     ) != KMessageBox::Yes) {
0435             return;
0436         }
0437     }
0438     // Why do the dirty work ourselves?
0439     emit saveRequested();
0440     d->toggleEncryption = false;
0441     d->applyToggleEncryption = false;
0442     // Detects when the user cancelled saving
0443     d->documentSaved = !doc->url().isEmpty();
0444 }
0445 
0446 QList<KPageWidgetItem*> KoDocumentInfoDlg::pages() const
0447 {
0448     return d->pages;
0449 }
0450 
0451 void KoDocumentInfoDlg::setReadOnly(bool ro)
0452 {
0453     d->aboutUi->meComments->setReadOnly(ro);
0454 
0455     Q_FOREACH(KPageWidgetItem* page, d->pages) {
0456         Q_FOREACH(QLineEdit* le, page->widget()->findChildren<QLineEdit *>()) {
0457             le->setReadOnly(ro);
0458         }
0459         Q_FOREACH(QPushButton* le, page->widget()->findChildren<QPushButton *>()) {
0460             le->setDisabled(ro);
0461         }
0462     }
0463 }
0464 
0465 void KoDocumentInfoDlg::addPageItem(KoPageWidgetItem *item)
0466 {
0467     KPageWidgetItem * page = new KoPageWidgetItemAdapter(item);
0468 
0469     addPage(page);
0470     d->pages.append(page);
0471 }
0472 #include "KoDocumentInfoDlg.moc"