File indexing completed on 2024-05-05 17:04:25

0001 /* This file is part of the KDE project
0002  * Copyright (C) 2012 Arjen Hiemstra <ahiemstra@heimr.nl>
0003  *
0004  *  This program is free software; you can redistribute it and/or modify
0005  *  it under the terms of the GNU General Public License as published by
0006  *  the Free Software Foundation; either version 2 of the License, or
0007  *  (at your option) any later version.
0008  *
0009  *  This program 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
0012  *  GNU General Public License for more details.
0013  *
0014  *  You should have received a copy of the GNU General Public License
0015  *  along with this program; if not, write to the Free Software
0016  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
0017  */
0018 
0019 #include "DocumentManager.h"
0020 #include "Settings.h"
0021 #include "RecentFileManager.h"
0022 #include "ProgressProxy.h"
0023 
0024 #include <KWPart.h>
0025 #include <KoDocument.h>
0026 #include <KoDocumentEntry.h>
0027 
0028 #include <libs/pigment/KoColor.h>
0029 #include <KoColorSpaceRegistry.h>
0030 
0031 #include <stage/part/KPrDocument.h>
0032 #include <part/KWDocument.h>
0033 
0034 #include <QMimeType>
0035 
0036 class DocumentManager::Private
0037 {
0038 public:
0039     Private()
0040         : proxy(0)
0041         , document(0)
0042         , part(0)
0043         , settingsManager(0)
0044         , recentFileManager(0)
0045         , importingDocument(false)
0046         , temporaryFile(false)
0047     { }
0048 
0049     ProgressProxy* proxy;
0050     QPointer<KoDocument> document;
0051     QPointer<KoPart> part;
0052     Settings* settingsManager;
0053     RecentFileManager* recentFileManager;
0054 
0055     QString saveAsFilename;
0056     QString openDocumentFilename;
0057     bool importingDocument;
0058     QVariantMap newDocOptions;
0059     bool temporaryFile;
0060 };
0061 
0062 DocumentManager *DocumentManager::sm_instance = 0;
0063 
0064 KoDocument* DocumentManager::document() const
0065 {
0066     return d->document;
0067 }
0068 
0069 QObject* DocumentManager::doc() const
0070 {
0071     return d->document;
0072 }
0073 
0074 KoPart* DocumentManager::part(const QString& type)
0075 {
0076     Q_UNUSED(type)
0077     if (!d->part)
0078         d->part = new KWPart(this);
0079     return d->part;
0080 }
0081 
0082 ProgressProxy* DocumentManager::progressProxy() const
0083 {
0084     return d->proxy;
0085 }
0086 
0087 Settings* DocumentManager::settingsManager() const
0088 {
0089     return d->settingsManager;
0090 }
0091 
0092 void DocumentManager::setSettingsManager(Settings* newManager)
0093 {
0094     d->settingsManager = newManager;
0095 }
0096 
0097 void DocumentManager::setDocAndPart(KoDocument* document, KoPart* part)
0098 {
0099     d->document = document;
0100     d->part = part;
0101     d->temporaryFile = false;
0102     emit documentChanged();
0103     connect(document, SIGNAL(destroyed()), SIGNAL(aboutToDeleteDocument()));
0104 }
0105 
0106 RecentFileManager* DocumentManager::recentFileManager() const
0107 {
0108     return d->recentFileManager;
0109 }
0110 
0111 bool DocumentManager::isTemporaryFile() const
0112 {
0113     if(d->document->url().isEmpty()) {
0114         return true;
0115     }
0116     return d->temporaryFile;
0117 }
0118 
0119 void DocumentManager::newDocument(int width, int height, float resolution)
0120 {
0121     Q_UNUSED(width)
0122     Q_UNUSED(height)
0123     Q_UNUSED(resolution)
0124     closeDocument();
0125 
0126     QTimer::singleShot(300, this, SLOT(delayedNewDocument()));
0127 }
0128 
0129 void DocumentManager::newDocument(const QVariantMap& options)
0130 {
0131     closeDocument();
0132 
0133     d->newDocOptions = options;
0134     QTimer::singleShot(300, this, SLOT(delayedNewDocument()));
0135 }
0136 
0137 void DocumentManager::delayedNewDocument()
0138 {
0139     QString filetype;
0140     if(d->newDocOptions.value("type", WORDS_MIME_TYPE).toString() == WORDS_MIME_TYPE) {
0141         filetype = "odt";
0142         d->document = new KWDocument(part(WORDS_MIME_TYPE));
0143     }
0144     else {
0145         filetype = "odp";
0146         d->document = new KPrDocument(part(STAGE_MIME_TYPE));
0147     }
0148     d->document->setProgressProxy(d->proxy);
0149     d->document->setSaveInBatchMode(true);
0150     part()->setDocument(d->document);
0151     connect(d->document, SIGNAL(destroyed()), SIGNAL(aboutToDeleteDocument()));
0152 
0153     if(d->newDocOptions.isEmpty())
0154     {
0155         //d->document->newImage("Untitled", d->newDocWidth, d->newDocHeight, KoColorSpaceRegistry::instance()->rgb8());
0156         //d->document->image()->setResolution(d->newDocResolution, d->newDocResolution);
0157         //d->document->setUrl(QUrl("Untitled.kra"));
0158     }
0159     else
0160     {
0161         QString name = d->newDocOptions.value("name", "Untitled").toString();
0162         //int width = d->newDocOptions.value("width").toInt();
0163         //int height = d->newDocOptions.value("height").toInt();
0164         // internal resolution is pixels per point, not ppi
0165         //float res = d->newDocOptions.value("resolution", 72.0f).toFloat() / 72.0f;
0166 
0167         QString colorModelId = d->newDocOptions.value("colorModelId").toString();
0168         QString colorDepthId = d->newDocOptions.value("colorDepthId").toString();
0169         QString colorProfileId = d->newDocOptions.value("colorProfileId").toString();
0170 
0171         const KoColorSpace* profile;
0172         if(colorModelId.isEmpty() || colorDepthId.isEmpty() || colorProfileId.isEmpty())
0173         {
0174             profile = KoColorSpaceRegistry::instance()->rgb8();
0175         }
0176         else
0177         {
0178             profile = KoColorSpaceRegistry::instance()->colorSpace(colorModelId, colorDepthId, colorProfileId);
0179         }
0180 
0181         QColor background = d->newDocOptions.value("backgroundColor", QColor("white")).value<QColor>();
0182         background.setAlphaF(d->newDocOptions.value("backgroundOpacity", 1.0f).toFloat());
0183         KoColor bg(background, profile);
0184 
0185         d->document->setUrl(QUrl(QString("Untitled.").append(filetype)));
0186     }
0187 
0188     d->temporaryFile = true;
0189 
0190     emit documentChanged();
0191 }
0192 
0193 void DocumentManager::openDocument(const QString& document, bool import)
0194 {
0195     closeDocument();
0196     d->openDocumentFilename = document;
0197     d->importingDocument = import;
0198     QTimer::singleShot(0, this, SLOT(delayedOpenDocument()));
0199 }
0200 
0201 void DocumentManager::delayedOpenDocument()
0202 {
0203     d->document = 0;
0204     QMimeDatabase db;
0205     QMimeType mimeType = db.mimeTypeForUrl(QUrl::fromLocalFile(d->openDocumentFilename));
0206     KoDocumentEntry documentEntry = KoDocumentEntry::queryByMimeType(mimeType.name());
0207     d->part = documentEntry.createKoPart();
0208     if (d->part) {
0209         d->document = d->part->document();
0210         d->document->setProgressProxy(d->proxy);
0211         d->document->setSaveInBatchMode(true);
0212 
0213         d->document->setModified(false);
0214         if (d->importingDocument)
0215             d->document->importDocument(QUrl::fromLocalFile(d->openDocumentFilename));
0216         else
0217             d->document->openUrl(QUrl::fromLocalFile(d->openDocumentFilename));
0218         d->recentFileManager->addRecent(d->openDocumentFilename);
0219 
0220         d->temporaryFile = false;
0221     }
0222 
0223     emit documentChanged();
0224 }
0225 
0226 void DocumentManager::closeDocument()
0227 {
0228     if (d->document) {
0229         d->document->closeUrl(false);
0230         d->document->deleteLater();
0231         d->document.clear();
0232     }
0233 }
0234 
0235 bool DocumentManager::save()
0236 {
0237     if (d->document->save())
0238     {
0239         d->recentFileManager->addRecent(d->document->url().toLocalFile());
0240         d->settingsManager->setCurrentFile(d->document->url().toLocalFile());
0241         emit documentSaved();
0242         return true;
0243     }
0244     return false;
0245 }
0246 
0247 void DocumentManager::saveAs(const QString &filename, const QString &mimetype)
0248 {
0249     d->document->setOutputMimeType(mimetype.toAscii());
0250     d->saveAsFilename = filename;
0251     // Yes. This is a massive hack. Basically, we need to wait a little while, to ensure
0252     // the save call happens late enough for a variety of UI things to happen first.
0253     // A second seems like a long time, but well, we do have file system interaction here,
0254     // so for now, we can get away with it.
0255     QTimer::singleShot(0, this, SLOT(delayedSaveAs()));
0256 }
0257 
0258 void DocumentManager::delayedSaveAs()
0259 {
0260     d->document->saveAs(QUrl::fromLocalFile(d->saveAsFilename));
0261     d->settingsManager->setCurrentFile(d->saveAsFilename);
0262     d->recentFileManager->addRecent(d->saveAsFilename);
0263     emit documentSaved();
0264 }
0265 
0266 void DocumentManager::reload()
0267 {
0268     QUrl url = d->document->url();
0269     closeDocument();
0270     d->openDocumentFilename = url.toLocalFile();
0271     QTimer::singleShot(0, this, SLOT(delayedOpenDocument()));
0272 }
0273 
0274 void DocumentManager::setTemporaryFile(bool temp)
0275 {
0276     d->temporaryFile = temp;
0277     emit documentSaved();
0278 }
0279 
0280 DocumentManager* DocumentManager::instance()
0281 {
0282     if (!sm_instance) {
0283         sm_instance = new DocumentManager(QCoreApplication::instance());
0284     }
0285 
0286     return sm_instance;
0287 }
0288 
0289 DocumentManager::DocumentManager(QObject* parent)
0290     : QObject(parent), d(new Private)
0291 {
0292     d->proxy = new ProgressProxy(this);
0293     d->recentFileManager = new RecentFileManager(this);
0294 }
0295 
0296 DocumentManager::~DocumentManager()
0297 {
0298     delete d;
0299 }
0300