File indexing completed on 2024-05-12 16:28:28

0001 /* This file is part of the KDE project
0002    Copyright (C) 2010 KO GmbH <jos.van.den.oever@kogmbh.com>
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 #include "oothread.h"
0020 #include <QDir>
0021 #include <QUrl>
0022 #include <QDebug>
0023 #include <QDateTime>
0024 #include <cstdio>
0025 
0026 #define UNX
0027 #define LINUX
0028 #define CPPU_ENV gcc3
0029 #define OSL_DEBUG_LEVEL 0
0030 #include <cppuhelper/bootstrap.hxx>
0031 #include <osl/process.h>
0032 #include <osl/file.hxx>
0033 #include <com/sun/star/bridge/XUnoUrlResolver.hpp>
0034 #include <com/sun/star/frame/XComponentLoader.hpp>
0035 #include <com/sun/star/frame/XDesktop.hpp>
0036 #include <com/sun/star/frame/XStorable.hpp>
0037 #include <com/sun/star/lang/XMultiComponentFactory.hpp>
0038 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
0039 #include <com/sun/star/lang/DisposedException.hpp>
0040 #include <com/sun/star/util/XModifiable.hpp>
0041 #include <com/sun/star/util/XCloseable.hpp>
0042  
0043 using namespace com::sun::star::bridge;
0044 using namespace com::sun::star::container;
0045 using namespace com::sun::star::frame;
0046 using namespace com::sun::star::lang;
0047 using namespace com::sun::star::beans;
0048 using namespace com::sun::star::uno;
0049 using namespace com::sun::star::util;
0050 using namespace cppu;
0051 using namespace rtl;
0052 
0053 class OoThread::OOConnection {
0054 public:
0055     Reference<XComponentContext> rComponentContext;
0056     Reference<XMultiComponentFactory> xServiceManager;
0057     Reference<XComponentLoader> xComponentLoader;
0058     OOConnection() {
0059         try {
0060             rComponentContext = Reference<XComponentContext>(bootstrap());
0061             xServiceManager = Reference<XMultiComponentFactory>(
0062                 rComponentContext->getServiceManager());
0063             OUString d(
0064                     RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.Desktop"));
0065             xComponentLoader = Reference<XComponentLoader>(
0066                 xServiceManager->createInstanceWithContext(d,
0067                      rComponentContext), UNO_QUERY_THROW);
0068         } catch(Exception &e) {
0069             OString o = OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US);
0070             qDebug() << "Error in OOConnection(): " << o;
0071         } catch(...) {
0072             qDebug() << "Unknown error in OOConnection().";
0073         }
0074     }
0075     ~OOConnection() {
0076         try {
0077             if (xComponentLoader.get()) {
0078                 Reference<XDesktop>::query(xComponentLoader)->terminate();
0079             }
0080         } catch(Exception &e) {
0081             OString o = OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US);
0082             qDebug() << "Error in ~OOConnection(): " << o;
0083         } catch(...) {
0084             qDebug() << "Unknown error in ~OOConnection().";
0085         }
0086     }
0087 };
0088  
0089 OoThread::OoThread(QObject* o) :QThread(o), oo(0) {
0090     qsrand(QDateTime::currentDateTime().toTime_t());
0091     running = true;
0092     start();
0093 }
0094 OoThread::~OoThread() {
0095     stop();
0096     wait();
0097 }
0098 void OoThread::run() {
0099     oo = new OOConnection();
0100     running = oo->xComponentLoader.get() != 0;
0101     while (running) {
0102         mutex.lock();
0103         currentToOdp = currentToPng = Conversion();
0104         if (!(nextToOdp || nextToPng)) {
0105             moreWork.wait(&mutex);
0106         }
0107         Conversion toOdp;
0108         Conversion toPng;
0109         if (nextToOdp) {
0110             toOdp = currentToOdp = nextToOdp;
0111             nextToOdp = Conversion();
0112         } else if (nextToPng) {
0113             toPng = currentToPng = nextToPng;
0114             nextToPng = Conversion();
0115         }
0116         mutex.unlock();
0117 
0118         if (toOdp) {
0119             convertToOdp(toOdp);
0120             emit toOdpDone(toOdp.to);
0121         } else if (toPng) {
0122             convertToPng(toPng);
0123             emit toPngDone(toPng.to);
0124         }
0125     }
0126     delete oo;
0127 }
0128 void OoThread::stop() {
0129     running = false;
0130     moreWork.wakeAll();
0131 }
0132 namespace {
0133     QString tmpname() {
0134         return QString::number(qrand());
0135     }
0136 }
0137 QString
0138 OoThread::toOdp(const QString& path) {
0139     QDir dir(QDir::temp().filePath("slidecompare-" + QDir::home().dirName()));
0140     dir.mkpath(dir.absolutePath());
0141     Conversion c;
0142     c.from = path;
0143     do {
0144         c.to = dir.absoluteFilePath(tmpname()+".odp");
0145     } while(dir.exists(c.to));
0146     mutex.lock();
0147     nextToOdp = c;
0148     moreWork.wakeAll();
0149     mutex.unlock();
0150     return c.to;
0151 }
0152 QString
0153 OoThread::toPng(const QString& path, int pngwidth) {
0154     QDir dir(QDir::temp().filePath("slidecompare-" + QDir::home().dirName()));
0155     dir.mkpath(dir.absolutePath());
0156     Conversion c;
0157     c.from = path;
0158     c.width = pngwidth;
0159     do {
0160         c.to = dir.absoluteFilePath(tmpname() + '/');
0161     } while(dir.exists(c.to));
0162     dir.mkdir(c.to);
0163     mutex.lock();
0164     nextToPng = c;
0165     moreWork.wakeAll();
0166     mutex.unlock();
0167     return c.to;
0168 }
0169 bool
0170 OoThread::waitingOrBusy(const QString& path) {
0171     bool b;
0172     mutex.lock();
0173     b = nextToOdp.to == path || nextToPng.to == path
0174         || currentToOdp.to == path || currentToPng.to == path;
0175     mutex.unlock();
0176     return b;
0177 }
0178 void
0179 OoThread::convertToOdp(const Conversion& c) {
0180     QByteArray fromUrl(QUrl::fromLocalFile(c.from).toEncoded());
0181     QByteArray toUrl(QUrl::fromLocalFile(c.to).toEncoded());
0182 
0183     qDebug() << "converting from '" << fromUrl << "' to '" << toUrl;
0184 
0185     Sequence<PropertyValue> props(1);
0186     props[0].Name = OUString::createFromAscii("Hidden");
0187     props[0].Value = Any(true);
0188     try {
0189         Reference<XComponent> xComponent
0190                 = oo->xComponentLoader->loadComponentFromURL(
0191                     OUString::createFromAscii(fromUrl.constData()),
0192                     OUString::createFromAscii("_default"),
0193                     0, props);
0194 
0195         Sequence<PropertyValue> htmlProps(2);
0196         htmlProps[0].Name = OUString::createFromAscii("Overwrite");
0197         htmlProps[0].Value = Any(true);
0198         htmlProps[1].Name = OUString::createFromAscii("FilterName");
0199         htmlProps[1].Value <<= OUString::createFromAscii("impress8");
0200 
0201         Reference<XStorable> store(xComponent, UNO_QUERY);
0202 
0203         if (store.is()) {
0204             OUString dest_url = OUString::createFromAscii(toUrl.constData());
0205             store->storeToURL(dest_url, htmlProps);
0206         }
0207         Reference<XModifiable>::query(xComponent)->setModified(false);
0208         Reference<XCloseable>::query(xComponent)->close(true);
0209         Reference<XComponent>::query(xComponent)->dispose();
0210     } catch(Exception &e) {
0211         OString o = OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US);
0212         qDebug() << "Error in toOdp: " << o;
0213     } catch(...) {
0214         qDebug() << "Unknown error in convertToPng().";
0215     }
0216 }
0217 void
0218 OoThread::convertToPng(const Conversion& c) {
0219     QByteArray fromUrl(QUrl::fromLocalFile(
0220             QFileInfo(c.from).absoluteFilePath()).toEncoded());
0221     QByteArray toUrl(QUrl::fromLocalFile(
0222             QFileInfo(c.to).absoluteFilePath()+"/index.html").toEncoded());
0223 
0224     qDebug() << "converting from '" << fromUrl << "' to '" << toUrl << " "
0225             << c.width;
0226 
0227     Sequence<PropertyValue> props(1);
0228     props[0].Name = OUString::createFromAscii("Hidden");
0229     props[0].Value = Any(true);
0230     try {
0231         Reference<XComponent> xComponent
0232                 = oo->xComponentLoader->loadComponentFromURL(
0233                     OUString::createFromAscii(fromUrl.constData()),
0234                     OUString::createFromAscii("_default"),
0235                     0, props);
0236 
0237         Sequence<PropertyValue> pngProps(3);
0238         pngProps[0].Name = OUString::createFromAscii("Format");
0239         pngProps[0].Value = Any((sal_uInt32)2); // png
0240         pngProps[1].Name = OUString::createFromAscii("Width");
0241         pngProps[1].Value = Any((sal_uInt32)c.width);
0242         pngProps[2].Name = OUString::createFromAscii("PublishMode");
0243         pngProps[2].Value = Any((sal_uInt32)0); // html
0244 
0245         Sequence<PropertyValue> htmlProps(3);
0246         htmlProps[0].Name = OUString::createFromAscii("Overwrite");
0247         htmlProps[0].Value = Any(true);
0248         htmlProps[1].Name = OUString::createFromAscii("FilterName");
0249         htmlProps[1].Value <<= OUString::createFromAscii("impress_html_Export");
0250         htmlProps[2].Name = OUString::createFromAscii("FilterData");
0251         htmlProps[2].Value <<= pngProps;
0252 
0253         Reference<XStorable> store(xComponent, UNO_QUERY);
0254         if (store.is()) {
0255             OUString dest_url = OUString::createFromAscii(toUrl.constData());
0256             store->storeToURL(dest_url, htmlProps);
0257         }
0258         Reference<XModifiable>::query(xComponent)->setModified(false);
0259         Reference<XCloseable>::query(xComponent)->close(true);
0260         Reference<XComponent>::query(xComponent)->dispose();
0261     } catch(Exception &e) {
0262         OString o = OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US);
0263         qDebug() << "Error in toPng: " << o;
0264     } catch(...) {
0265         qDebug() << "Unknown error in convertToPng().";
0266     }
0267 }