1 /* This file is part of the Calligra libraries 2 Copyright (C) 2001 Werner Trobin <trobin@kde.org> 3 4 This library is free software; you can redistribute it and/or 5 modify it under the terms of the GNU Library General Public 6 License as published by the Free Software Foundation; either 7 version 2 of the License, or (at your option) any later version. 8 9 This library is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 Library General Public License for more details. 13 14 You should have received a copy of the GNU Library General Public License 15 along with this library; see the file COPYING.LIB. If not, write to 16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 Boston, MA 02110-1301, USA. 18 */ 19 // clazy:excludeall=qstring-arg 20 #include "KoFilterChainLink.h" 21 #include <QMetaMethod> 22 #include <QPluginLoader> 23 #include <MainDebug.h> 24 #include "KoFilterEntry.h" 25 #include "KoFilterManager.h" 26 #include "KoProgressUpdater.h" 27 #include "KoUpdater.h" 28 29 namespace 30 { 31 const char SIGNAL_PREFIX[] = "commSignal"; 32 const int SIGNAL_PREFIX_LEN = 10; 33 const char SLOT_PREFIX[] = "commSlot"; 34 const int SLOT_PREFIX_LEN = 8; 35 createUpdater(KoFilterChain * chain)36 KoUpdater *createUpdater(KoFilterChain *chain) 37 { 38 QPointer<KoUpdater> updater = 0; 39 Q_ASSERT(chain); 40 Q_ASSERT(chain->manager()); 41 KoProgressUpdater *pu = chain->manager()->progressUpdater(); 42 if (pu) { 43 updater = pu->startSubtask(1, "filter"); 44 updater->setProgress(0); 45 } 46 47 return updater; 48 } 49 } 50 51 namespace CalligraFilter { 52 ChainLink(KoFilterChain * chain,KoFilterEntry::Ptr filterEntry,const QByteArray & from,const QByteArray & to)53 ChainLink::ChainLink(KoFilterChain *chain, KoFilterEntry::Ptr filterEntry, 54 const QByteArray& from, const QByteArray& to) 55 : m_chain(chain) 56 , m_filterEntry(filterEntry) 57 , m_from(from) 58 , m_to(to) 59 , m_filter(0) 60 , m_updater(createUpdater(chain)) 61 { 62 } 63 ~ChainLink()64 ChainLink::~ChainLink() { 65 } 66 invokeFilter(const ChainLink * const parentChainLink)67 KoFilter::ConversionStatus ChainLink::invokeFilter(const ChainLink *const parentChainLink) 68 { 69 if (!m_filterEntry) { 70 errorFilter << "This filter entry is null. Strange stuff going on." << endl; 71 return KoFilter::FilterEntryNull; 72 } 73 74 m_filter = m_filterEntry->createFilter(m_chain); 75 76 if (!m_filter) { 77 errorFilter << "Couldn't create the filter." << endl; 78 return KoFilter::FilterCreationError; 79 } 80 81 if (m_updater) { 82 // if there is an updater, use that for progress reporting 83 m_filter->setUpdater(m_updater); 84 } 85 86 if (parentChainLink) { 87 setupCommunication(parentChainLink->m_filter); 88 } 89 90 KoFilter::ConversionStatus status = m_filter->convert(m_from, m_to); 91 delete m_filter; 92 m_filter = 0; 93 if (m_updater) { 94 m_updater->setProgress(100); 95 } 96 return status; 97 } 98 dump() const99 void ChainLink::dump() const 100 { 101 debugFilter << " Link:" << m_filterEntry->fileName(); 102 } 103 setupCommunication(const KoFilter * const parentFilter) const104 void ChainLink::setupCommunication(const KoFilter *const parentFilter) const 105 { 106 if (!parentFilter) 107 return; 108 109 const QMetaObject *const parent = parentFilter->metaObject(); 110 const QMetaObject *const child = m_filter->metaObject(); 111 if (!parent || !child) 112 return; 113 114 setupConnections(parentFilter, m_filter); 115 setupConnections(m_filter, parentFilter); 116 } 117 setupConnections(const KoFilter * sender,const KoFilter * receiver) const118 void ChainLink::setupConnections(const KoFilter *sender, const KoFilter *receiver) const 119 { 120 const QMetaObject * const parent = sender->metaObject(); 121 const QMetaObject * const child = receiver->metaObject(); 122 if (!parent || !child) 123 return; 124 125 int senderMethodCount = parent->methodCount(); 126 for (int i = 0; i < senderMethodCount; ++i) { 127 QMetaMethod metaMethodSignal = parent->method(i); 128 if (metaMethodSignal.methodType() != QMetaMethod::Signal) 129 continue; 130 // ### untested (QMetaMethod::signature()) 131 if (strncmp(metaMethodSignal.methodSignature(), SIGNAL_PREFIX, SIGNAL_PREFIX_LEN) == 0) { 132 int receiverMethodCount = child->methodCount(); 133 for (int j = 0; j < receiverMethodCount; ++j) { 134 QMetaMethod metaMethodSlot = child->method(j); 135 if (metaMethodSlot.methodType() != QMetaMethod::Slot) 136 continue; 137 if (strncmp(metaMethodSlot.methodSignature().constData(), SLOT_PREFIX, SLOT_PREFIX_LEN) == 0) { 138 if (strcmp(metaMethodSignal.methodSignature().constData() + SIGNAL_PREFIX_LEN, metaMethodSlot.methodSignature().constData() + SLOT_PREFIX_LEN) == 0) { 139 QByteArray signalString; 140 signalString.setNum(QSIGNAL_CODE); 141 signalString += metaMethodSignal.methodSignature(); 142 QByteArray slotString; 143 slotString.setNum(QSLOT_CODE); 144 slotString += metaMethodSlot.methodSignature(); 145 QObject::connect(sender, signalString, receiver, slotString); 146 } 147 } 148 } 149 } 150 } 151 } 152 153 } 154