Warning, file /office/calligra/libs/main/KoPart.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) 1998, 1999 Torben Weis <weis@kde.org>
0003  * Copyright (C) 2000-2005 David Faure <faure@kde.org>
0004  * Copyright (C) 2007-2008 Thorsten Zachmann <zachmann@kde.org>
0005  * Copyright (C) 2010-2012 Boudewijn Rempt <boud@kogmbh.com>
0006  * Copyright (C) 2011 Inge Wallin <ingwa@kogmbh.com>
0007  *
0008  * This library is free software; you can redistribute it and/or
0009  * modify it under the terms of the GNU Library General Public
0010  * License as published by the Free Software Foundation; either
0011  * version 2 of the License, or (at your option) any later version.
0012  *
0013  * This library is distributed in the hope that it will be useful,
0014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0016  * Library General Public License for more details.
0017  *
0018  * You should have received a copy of the GNU Library General Public License
0019  * along with this library; see the file COPYING.LIB.  If not, write to
0020  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0021  * Boston, MA 02110-1301, USA.
0022  */
0023 
0024 #include "KoPart.h"
0025 
0026 #include "KoApplication.h"
0027 #include "KoMainWindow.h"
0028 #include "KoDocument.h"
0029 #include "KoView.h"
0030 #include "KoOpenPane.h"
0031 #include "KoFilterManager.h"
0032 #include <KoComponentData.h>
0033 
0034 #include <KoCanvasController.h>
0035 #include <KoCanvasControllerWidget.h>
0036 #include <KoResourcePaths.h>
0037 
0038 #include <MainDebug.h>
0039 #include <kxmlguifactory.h>
0040 #include <kdesktopfile.h>
0041 #include <kconfiggroup.h>
0042 #include <ksharedconfig.h>
0043 
0044 #include <QFileInfo>
0045 #include <QGraphicsScene>
0046 #include <QGraphicsProxyWidget>
0047 #include <QMimeDatabase>
0048 
0049 #ifndef QT_NO_DBUS
0050 #include <QDBusConnection>
0051 #include "KoPartAdaptor.h"
0052 #endif
0053 
0054 class Q_DECL_HIDDEN KoPart::Private
0055 {
0056 public:
0057     Private(const KoComponentData &componentData_, KoPart *_parent)
0058         : parent(_parent)
0059         , document(0)
0060         , proxyWidget(0)
0061         , startUpWidget(0)
0062         , componentData(componentData_)
0063     {
0064     }
0065 
0066     ~Private()
0067     {
0068         delete proxyWidget;
0069     }
0070 
0071     KoPart *parent;
0072 
0073     QList<KoView*> views;
0074     QList<KoMainWindow*> mainWindows;
0075     KoDocument *document;
0076     QList<KoDocument*> documents;
0077     QPointer<QGraphicsProxyWidget> proxyWidget;
0078     QPointer<KoOpenPane> startUpWidget;
0079     QString templatesResourcePath;
0080 
0081     KoComponentData componentData;
0082 };
0083 
0084 
0085 KoPart::KoPart(const KoComponentData &componentData, QObject *parent)
0086         : QObject(parent)
0087         , d(new Private(componentData, this))
0088 {
0089 #ifndef QT_NO_DBUS
0090     new KoPartAdaptor(this);
0091     QDBusConnection::sessionBus().registerObject('/' + objectName(), this);
0092 #endif
0093 }
0094 
0095 KoPart::~KoPart()
0096 {
0097     // Tell our views that the document is already destroyed and
0098     // that they shouldn't try to access it.
0099     foreach(KoView *view, views()) {
0100         view->setDocumentDeleted();
0101     }
0102 
0103     while (!d->mainWindows.isEmpty()) {
0104         delete d->mainWindows.takeFirst();
0105     }
0106 
0107     delete d->startUpWidget;
0108     d->startUpWidget = 0;
0109 
0110     delete d;
0111 }
0112 
0113 KoComponentData KoPart::componentData() const
0114 {
0115     return d->componentData;
0116 }
0117 
0118 void KoPart::setDocument(KoDocument *document)
0119 {
0120     Q_ASSERT(document);
0121     d->document = document;
0122 }
0123 
0124 KoDocument *KoPart::document() const
0125 {
0126     return d->document;
0127 }
0128 
0129 KoView *KoPart::createView(KoDocument *document, QWidget *parent)
0130 {
0131     KoView *view = createViewInstance(document, parent);
0132     addView(view, document);
0133     if (!d->documents.contains(document)) {
0134         d->documents.append(document);
0135     }
0136     return view;
0137 }
0138 
0139 void KoPart::addView(KoView *view, KoDocument *document)
0140 {
0141     if (!view)
0142         return;
0143 
0144     if (!d->views.contains(view)) {
0145         d->views.append(view);
0146     }
0147     if (!d->documents.contains(document)) {
0148         d->documents.append(document);
0149     }
0150 
0151     view->updateReadWrite(document->isReadWrite());
0152 
0153     if (d->views.size() == 1) {
0154         KoApplication *app = qobject_cast<KoApplication*>(qApp);
0155         if (0 != app) {
0156             emit app->documentOpened('/'+objectName());
0157         }
0158     }
0159 }
0160 
0161 void KoPart::removeView(KoView *view)
0162 {
0163     d->views.removeAll(view);
0164 
0165     if (d->views.isEmpty()) {
0166         KoApplication *app = qobject_cast<KoApplication*>(qApp);
0167         if (0 != app) {
0168             emit app->documentClosed('/'+objectName());
0169         }
0170     }
0171 }
0172 
0173 QList<KoView*> KoPart::views() const
0174 {
0175     return d->views;
0176 }
0177 
0178 int KoPart::viewCount() const
0179 {
0180     return d->views.count();
0181 }
0182 
0183 QGraphicsItem *KoPart::canvasItem(KoDocument *document, bool create)
0184 {
0185     if (create && !d->proxyWidget) {
0186         return createCanvasItem(document);
0187     }
0188     return d->proxyWidget;
0189 }
0190 
0191 QGraphicsItem *KoPart::createCanvasItem(KoDocument *document)
0192 {
0193     KoView *view = createView(document);
0194     d->proxyWidget = new QGraphicsProxyWidget();
0195     QWidget *canvasController = view->findChild<KoCanvasControllerWidget*>();
0196     d->proxyWidget->setWidget(canvasController);
0197     return d->proxyWidget;
0198 }
0199 
0200 void KoPart::addMainWindow(KoMainWindow *mainWindow)
0201 {
0202     if (d->mainWindows.indexOf(mainWindow) == -1) {
0203         debugMain <<"mainWindow" << (void*)mainWindow <<"added to doc" << this;
0204         d->mainWindows.append(mainWindow);
0205     }
0206 }
0207 
0208 void KoPart::removeMainWindow(KoMainWindow *mainWindow)
0209 {
0210     debugMain <<"mainWindow" << (void*)mainWindow <<"removed from doc" << this;
0211     if (mainWindow) {
0212         d->mainWindows.removeAll(mainWindow);
0213     }
0214 }
0215 
0216 const QList<KoMainWindow*>& KoPart::mainWindows() const
0217 {
0218     return d->mainWindows;
0219 }
0220 
0221 int KoPart::mainwindowCount() const
0222 {
0223     return d->mainWindows.count();
0224 }
0225 
0226 
0227 KoMainWindow *KoPart::currentMainwindow() const
0228 {
0229     QWidget *widget = qApp->activeWindow();
0230     KoMainWindow *mainWindow = qobject_cast<KoMainWindow*>(widget);
0231     while (!mainWindow && widget) {
0232         widget = widget->parentWidget();
0233         mainWindow = qobject_cast<KoMainWindow*>(widget);
0234     }
0235 
0236     if (!mainWindow && mainWindows().size() > 0) {
0237         mainWindow = mainWindows().first();
0238     }
0239     return mainWindow;
0240 
0241 }
0242 
0243 void KoPart::openExistingFile(const QUrl &url)
0244 {
0245     QApplication::setOverrideCursor(Qt::BusyCursor);
0246     d->document->openUrl(url);
0247     d->document->setModified(false);
0248     QApplication::restoreOverrideCursor();
0249 }
0250 
0251 void KoPart::openTemplate(const QUrl &url)
0252 {
0253     QApplication::setOverrideCursor(Qt::BusyCursor);
0254     bool ok = d->document->loadNativeFormat(url.toLocalFile());
0255     d->document->setModified(false);
0256     d->document->undoStack()->clear();
0257 
0258     if (ok) {
0259         QString mimeType = QMimeDatabase().mimeTypeForUrl(url).name();
0260         // in case this is a open document template remove the -template from the end
0261         mimeType.remove( QRegExp( "-template$" ) );
0262         d->document->setMimeTypeAfterLoading(mimeType);
0263         deleteOpenPane();
0264         d->document->resetURL();
0265         d->document->setEmpty();
0266     } else {
0267         d->document->showLoadingErrorDialog();
0268         d->document->initEmpty();
0269     }
0270     QApplication::restoreOverrideCursor();
0271 }
0272 
0273 void KoPart::addRecentURLToAllMainWindows(const QUrl &url)
0274 {
0275     // Add to recent actions list in our mainWindows
0276     foreach(KoMainWindow *mainWindow, d->mainWindows) {
0277         mainWindow->addRecentURL(url);
0278     }
0279 
0280 }
0281 
0282 void KoPart::showStartUpWidget(KoMainWindow *mainWindow, bool alwaysShow)
0283 {
0284 #ifndef NDEBUG
0285     if (d->templatesResourcePath.isEmpty())
0286         debugMain << "showStartUpWidget called, but setTemplatesResourcePath() never called. This will not show a lot";
0287 #endif
0288     if (!alwaysShow) {
0289         KConfigGroup cfgGrp(componentData().config(), "TemplateChooserDialog");
0290         QString fullTemplateName = cfgGrp.readPathEntry("AlwaysUseTemplate", QString());
0291         if (!fullTemplateName.isEmpty()) {
0292             QFileInfo fi(fullTemplateName);
0293             if (!fi.exists()) {
0294                 const QString templatesResourcePath = this->templatesResourcePath();
0295                 QString desktopfile = KoResourcePaths::findResource("data", templatesResourcePath + "*/" + fullTemplateName);
0296                 if (desktopfile.isEmpty()) {
0297                     desktopfile = KoResourcePaths::findResource("data", templatesResourcePath + fullTemplateName);
0298                 }
0299                 if (desktopfile.isEmpty()) {
0300                     fullTemplateName.clear();
0301                 } else {
0302                     QUrl templateURL;
0303                     KDesktopFile f(desktopfile);
0304                     templateURL.setPath(QFileInfo(desktopfile).absolutePath() + '/' + f.readUrl());
0305                     fullTemplateName = templateURL.toLocalFile();
0306                 }
0307             }
0308             if (!fullTemplateName.isEmpty()) {
0309                 openTemplate(QUrl::fromUserInput(fullTemplateName));
0310                 mainWindows().first()->setRootDocument(d->document, this);
0311                 return;
0312             }
0313         }
0314     }
0315 
0316     mainWindow->factory()->container("mainToolBar", mainWindow)->hide();
0317 
0318     if (d->startUpWidget) {
0319         d->startUpWidget->show();
0320     } else {
0321         d->startUpWidget = createOpenPane(mainWindow, d->templatesResourcePath);
0322         mainWindow->setCentralWidget(d->startUpWidget);
0323     }
0324 
0325     mainWindow->setPartToOpen(this);
0326 }
0327 
0328 void KoPart::deleteOpenPane(bool closing)
0329 {
0330     if (d->startUpWidget) {
0331         d->startUpWidget->hide();
0332         d->startUpWidget->deleteLater();
0333 
0334         if(!closing) {
0335             mainWindows().first()->setRootDocument(d->document, this);
0336             KoPart::mainWindows().first()->factory()->container("mainToolBar",
0337                                                                   mainWindows().first())->show();
0338         }
0339     }
0340 }
0341 
0342 QList<KoPart::CustomDocumentWidgetItem> KoPart::createCustomDocumentWidgets(QWidget * /*parent*/)
0343 {
0344     return QList<CustomDocumentWidgetItem>();
0345 }
0346 
0347 void KoPart::setTemplatesResourcePath(const QString &templatesResourcePath)
0348 {
0349     Q_ASSERT(!templatesResourcePath.isEmpty());
0350     Q_ASSERT(templatesResourcePath.endsWith(QLatin1Char('/')));
0351 
0352     d->templatesResourcePath = templatesResourcePath;
0353 }
0354 
0355 QString KoPart::templatesResourcePath() const
0356 {
0357     return d->templatesResourcePath;
0358 }
0359 
0360 
0361 void KoPart::startCustomDocument()
0362 {
0363     deleteOpenPane();
0364 }
0365 
0366 KoOpenPane *KoPart::createOpenPane(QWidget *parent, const QString& templatesResourcePath)
0367 {
0368     const QStringList mimeFilter = koApp->mimeFilter(KoFilterManager::Import);
0369 
0370     KoOpenPane *openPane = new KoOpenPane(parent, mimeFilter, templatesResourcePath);
0371     QList<CustomDocumentWidgetItem> widgetList = createCustomDocumentWidgets(openPane);
0372     foreach(const CustomDocumentWidgetItem & item, widgetList) {
0373         openPane->addCustomDocumentWidget(item.widget, item.title, item.icon);
0374         connect(item.widget, SIGNAL(documentSelected()), this, SLOT(startCustomDocument()));
0375     }
0376     openPane->show();
0377 
0378     connect(openPane, SIGNAL(openExistingFile(QUrl)), this, SLOT(openExistingFile(QUrl)));
0379     connect(openPane, SIGNAL(openTemplate(QUrl)), this, SLOT(openTemplate(QUrl)));
0380 
0381     return openPane;
0382 }