Warning, file /office/calligra/libs/odf/KoEmbeddedDocumentLoader.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  *
0003  * This library is free software; you can redistribute it and/or
0004  * modify it under the terms of the GNU Library General Public
0005  * License as published by the Free Software Foundation; either
0006  * version 2 of the License, or (at your option) any later version.
0007  *
0008  * This library is distributed in the hope that it will be useful,
0009  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0010  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0011  * Library General Public License for more details.
0012  *
0013  * You should have received a copy of the GNU Library General Public License
0014  * along with this library; see the file COPYING.LIB.  If not, write to
0015  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0016  * Boston, MA 02110-1301, USA.
0017  */
0018 
0019 #include "KoEmbeddedDocumentLoader.h"
0020 
0021 #include "KoDocumentBase.h"
0022 #include "KoOdfLoadingContext.h"
0023 #include "OdfDebug.h"
0024 
0025 #include <QList>
0026 #include <QUrl>
0027 #include <QString>
0028 
0029 #include <KoStore.h>
0030 #include <KoXmlReader.h>
0031 #include <KoXmlNS.h>
0032 
0033 
0034 #define INTERNAL_PROTOCOL "intern"
0035 #define STORE_PROTOCOL "tar"
0036 
0037 
0038 class Q_DECL_HIDDEN KoEmbeddedDocumentLoader::Private
0039 {
0040 public:
0041     Private() {}
0042 
0043     KoDocumentBase *doc;
0044 };
0045 
0046 KoEmbeddedDocumentLoader::KoEmbeddedDocumentLoader(KoDocumentBase *doc)
0047     : d(new Private())
0048 {
0049     d->doc = doc;
0050 }
0051 
0052 KoEmbeddedDocumentLoader::~KoEmbeddedDocumentLoader()
0053 {
0054     delete d;
0055 }
0056 
0057 bool isInternalUrl(const QString &url)
0058 {
0059     return url.startsWith(STORE_PROTOCOL) || url.startsWith(INTERNAL_PROTOCOL) || QUrl::fromUserInput(url).isRelative();
0060 }
0061 
0062 bool KoEmbeddedDocumentLoader::loadEmbeddedDocument(const KoXmlElement &element, KoOdfLoadingContext &context)
0063 {
0064     if (!element.hasAttributeNS(KoXmlNS::xlink, "href")) {
0065         errorOdf << "Object element has no valid xlink:href attribute";
0066         return false;
0067     }
0068     QString url = element.attributeNS(KoXmlNS::xlink, "href");
0069     // It can happen that the url is empty e.g. when it is a
0070     // presentation:placeholder.
0071     if (url.isEmpty()) {
0072         return true;
0073     }
0074     QString tmpURL;
0075     if (url[0] == '#') {
0076         url.remove(0, 1);
0077     }
0078     if (QUrl::fromUserInput(url).isRelative()) {
0079         if (url.startsWith("./")) {
0080             tmpURL = QString(INTERNAL_PROTOCOL) + ":/" + url.mid(2);
0081         } else {
0082             tmpURL = QString(INTERNAL_PROTOCOL) + ":/" + url;
0083         }
0084     } else {
0085         tmpURL = url;
0086     }
0087     KoStore *store = context.store();
0088     QString path = tmpURL;
0089     if (tmpURL.startsWith(INTERNAL_PROTOCOL)) {
0090         path = store->currentPath();
0091         if (!path.isEmpty() && !path.endsWith('/')) {
0092             path += '/';
0093         }
0094         QString relPath = QUrl::fromUserInput(tmpURL).path();
0095         path += relPath.mid(1); // remove leading '/'
0096     }
0097     if (!path.endsWith('/')) {
0098         path += '/';
0099     }
0100     const QString mimeType = context.mimeTypeForPath(path);
0101     //debugOdf << "path for manifest file=" << path << "mimeType=" << mimeType;
0102     if (mimeType.isEmpty()) {
0103         //debugOdf << "Manifest doesn't have media-type for" << path;
0104         return false;
0105     }
0106     bool res = true;
0107     if (isInternalUrl(tmpURL)) {
0108         store->pushDirectory();
0109         Q_ASSERT(tmpURL.startsWith(INTERNAL_PROTOCOL));
0110         QString relPath = QUrl::fromUserInput(tmpURL).path().mid(1);
0111         store->enterDirectory(relPath);
0112         res = d->doc->loadOasisFromStore(store);
0113         store->popDirectory();
0114         d->doc->setStoreInternal(true);
0115     } else {
0116         //TODO
0117         //         // Reference to an external document.
0118         //         dpc->setStoreInternal(false);
0119         //         QUrl url = QUrl::fromUserInput(tmpURL);
0120         //         if (!url.isLocalFile()) {
0121         //             //QApplication::restoreOverrideCursor();
0122         //
0123         //             // For security reasons we need to ask confirmation if the
0124         //             // url is remote.
0125         //             int result = KMessageBox::warningYesNoCancel(
0126         //                 0, i18n("This document contains an external link to a remote document\n%1", tmpURL),
0127         //                                                          i18n("Confirmation Required"), KGuiItem(i18n("Download")), KGuiItem(i18n("Skip")));
0128         //
0129         //             if (result == KMessageBox::Cancel) {
0130         //                 //d->m_parent->setErrorMessage("USER_CANCELED");
0131         //                 return false;
0132         //             }
0133         //             if (result == KMessageBox::Yes) {
0134         //                 res = openUrl(url);
0135         //             }
0136         //             // and if == No, res will still be false so we'll use a kounavail below
0137         //         } else {
0138         //             res = openUrl(url);
0139         //         }
0140     }
0141     return res;
0142 }