Warning, file /office/calligra/libs/main/KoFilterChainLink.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 Calligra libraries
0002    Copyright (C) 2001 Werner Trobin <trobin@kde.org>
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 "KoFilterChainLink.h"
0020 #include <QMetaMethod>
0021 #include <QPluginLoader>
0022 #include <MainDebug.h>
0023 #include "KoFilterEntry.h"
0024 #include "KoFilterManager.h"
0025 #include "KoProgressUpdater.h"
0026 #include "KoUpdater.h"
0027 
0028 namespace
0029 {
0030     const char SIGNAL_PREFIX[] = "commSignal";
0031     const int SIGNAL_PREFIX_LEN = 10;
0032     const char SLOT_PREFIX[] = "commSlot";
0033     const int SLOT_PREFIX_LEN = 8;
0034 
0035     KoUpdater *createUpdater(KoFilterChain *chain)
0036     {
0037         QPointer<KoUpdater> updater = 0;
0038         Q_ASSERT(chain);
0039         Q_ASSERT(chain->manager());
0040         KoProgressUpdater *pu = chain->manager()->progressUpdater();
0041         if (pu) {
0042             updater = pu->startSubtask(1, "filter");
0043             updater->setProgress(0);
0044         }
0045 
0046         return updater;
0047     }
0048 }
0049 
0050 namespace CalligraFilter {
0051 
0052     ChainLink::ChainLink(KoFilterChain *chain, KoFilterEntry::Ptr filterEntry,
0053                          const QByteArray& from, const QByteArray& to)
0054         : m_chain(chain)
0055         , m_filterEntry(filterEntry)
0056         , m_from(from)
0057         , m_to(to)
0058         , m_filter(0)
0059         , m_updater(createUpdater(chain))
0060     {
0061     }
0062 
0063     ChainLink::~ChainLink() {
0064     }
0065 
0066     KoFilter::ConversionStatus ChainLink::invokeFilter(const ChainLink *const parentChainLink)
0067     {
0068         if (!m_filterEntry) {
0069             errorFilter << "This filter entry is null. Strange stuff going on." << endl;
0070             return KoFilter::FilterEntryNull;
0071         }
0072 
0073         m_filter = m_filterEntry->createFilter(m_chain);
0074 
0075         if (!m_filter) {
0076             errorFilter << "Couldn't create the filter." << endl;
0077             return KoFilter::FilterCreationError;
0078         }
0079 
0080         if (m_updater) {
0081             // if there is an updater, use that for progress reporting
0082             m_filter->setUpdater(m_updater);
0083         }
0084 
0085         if (parentChainLink) {
0086             setupCommunication(parentChainLink->m_filter);
0087         }
0088 
0089         KoFilter::ConversionStatus status = m_filter->convert(m_from, m_to);
0090         delete m_filter;
0091         m_filter = 0;
0092         if (m_updater) {
0093             m_updater->setProgress(100);
0094         }
0095         return status;
0096     }
0097 
0098     void ChainLink::dump() const
0099     {
0100         debugFilter << "   Link:" << m_filterEntry->fileName();
0101     }
0102 
0103     void ChainLink::setupCommunication(const KoFilter *const parentFilter) const
0104     {
0105         if (!parentFilter)
0106             return;
0107 
0108         const QMetaObject *const parent = parentFilter->metaObject();
0109         const QMetaObject *const child = m_filter->metaObject();
0110         if (!parent || !child)
0111             return;
0112 
0113         setupConnections(parentFilter, m_filter);
0114         setupConnections(m_filter, parentFilter);
0115     }
0116 
0117     void ChainLink::setupConnections(const KoFilter *sender, const KoFilter *receiver) const
0118     {
0119         const QMetaObject * const parent = sender->metaObject();
0120         const QMetaObject * const child = receiver->metaObject();
0121         if (!parent || !child)
0122             return;
0123 
0124         int senderMethodCount = parent->methodCount();
0125         for (int i = 0; i < senderMethodCount; ++i) {
0126             QMetaMethod metaMethodSignal = parent->method(i);
0127             if (metaMethodSignal.methodType() != QMetaMethod::Signal)
0128                 continue;
0129             // ### untested (QMetaMethod::signature())
0130             if (strncmp(metaMethodSignal.methodSignature(), SIGNAL_PREFIX, SIGNAL_PREFIX_LEN) == 0) {
0131                 int receiverMethodCount = child->methodCount();
0132                 for (int j = 0; j < receiverMethodCount; ++j) {
0133                     QMetaMethod metaMethodSlot = child->method(j);
0134                     if (metaMethodSlot.methodType() != QMetaMethod::Slot)
0135                         continue;
0136                     if (strncmp(metaMethodSlot.methodSignature().constData(), SLOT_PREFIX, SLOT_PREFIX_LEN) == 0) {
0137                         if (strcmp(metaMethodSignal.methodSignature().constData() + SIGNAL_PREFIX_LEN, metaMethodSlot.methodSignature().constData() + SLOT_PREFIX_LEN) == 0) {
0138                             QByteArray signalString;
0139                             signalString.setNum(QSIGNAL_CODE);
0140                             signalString += metaMethodSignal.methodSignature();
0141                             QByteArray slotString;
0142                             slotString.setNum(QSLOT_CODE);
0143                             slotString += metaMethodSlot.methodSignature();
0144                             QObject::connect(sender, signalString, receiver, slotString);
0145                         }
0146                     }
0147                 }
0148             }
0149         }
0150     }
0151 
0152 }