KoFilterChainLink.cpp 5.07 KB
Newer Older
Halla Rempt's avatar
Halla Rempt committed
1
/* This file is part of the Calligra libraries
2 3
   Copyright (C) 2001 Werner Trobin <trobin@kde.org>

4 5 6 7
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
8

9 10 11 12
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Library General Public License for more details.
13

14 15 16 17
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB.  If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
18 19
*/
#include "KoFilterChainLink.h"
20 21 22 23
#include <QMetaMethod>
#include <kdebug.h>
#include "KoFilterEntry.h"
#include "KoFilterManager.h"
24 25
#include "KoProgressUpdater.h"
#include "KoUpdater.h"
26 27

namespace
28
{
29
    const char SIGNAL_PREFIX[] = "commSignal";
30
    const int SIGNAL_PREFIX_LEN = 10;
31
    const char SLOT_PREFIX[] = "commSlot";
32
    const int SLOT_PREFIX_LEN = 8;
33

Jos van den Oever's avatar
Jos van den Oever committed
34
    KoUpdater *createUpdater(KoFilterChain *chain)
35 36
    {
        QPointer<KoUpdater> updater = 0;
37 38 39
        Q_ASSERT(chain);
        Q_ASSERT(chain->manager());
        KoProgressUpdater *pu = chain->manager()->progressUpdater();
40 41 42 43
        if (pu) {
            updater = pu->startSubtask(1, "filter");
            updater->setProgress(0);
        }
44

45 46
        return updater;
    }
47 48
}

Halla Rempt's avatar
Halla Rempt committed
49
namespace CalligraFilter {
50

Jos van den Oever's avatar
Jos van den Oever committed
51
    ChainLink::ChainLink(KoFilterChain *chain, KoFilterEntry::Ptr filterEntry,
Halla Rempt's avatar
Halla Rempt committed
52 53 54 55 56 57
                         const QByteArray& from, const QByteArray& to)
        : m_chain(chain)
        , m_filterEntry(filterEntry)
        , m_from(from)
        , m_to(to)
        , m_filter(0)
58
        , m_updater(createUpdater(chain))
59
    {
60 61
    }

Halla Rempt's avatar
Halla Rempt committed
62 63 64
    ChainLink::~ChainLink() {
    }

Jos van den Oever's avatar
Jos van den Oever committed
65
    KoFilter::ConversionStatus ChainLink::invokeFilter(const ChainLink *const parentChainLink)
66 67 68
    {
        if (!m_filterEntry) {
            kError(30500) << "This filter entry is null. Strange stuff going on." << endl;
69
            return KoFilter::FilterEntryNull;
70
        }
71

72
        m_filter = m_filterEntry->createFilter(m_chain);
73

74 75
        if (!m_filter) {
            kError(30500) << "Couldn't create the filter." << endl;
76
            return KoFilter::FilterCreationError;
77
        }
78

79 80 81 82
        if (m_updater) {
            // if there is an updater, use that for progress reporting
            m_filter->setUpdater(m_updater);
        }
83

84
        if (parentChainLink) {
85
            setupCommunication(parentChainLink->m_filter);
86
        }
87

88 89 90
        KoFilter::ConversionStatus status = m_filter->convert(m_from, m_to);
        delete m_filter;
        m_filter = 0;
91 92 93
        if (m_updater) {
            m_updater->setProgress(100);
        }
94 95
        return status;
    }
96

97 98 99 100
    void ChainLink::dump() const
    {
        kDebug(30500) << "   Link:" << m_filterEntry->service()->name();
    }
101

Jos van den Oever's avatar
Jos van den Oever committed
102
    void ChainLink::setupCommunication(const KoFilter *const parentFilter) const
103 104 105
    {
        if (!parentFilter)
            return;
106

Jos van den Oever's avatar
Jos van den Oever committed
107 108
        const QMetaObject *const parent = parentFilter->metaObject();
        const QMetaObject *const child = m_filter->metaObject();
109 110
        if (!parent || !child)
            return;
111

112 113 114 115
        setupConnections(parentFilter, m_filter);
        setupConnections(m_filter, parentFilter);
    }

Jos van den Oever's avatar
Jos van den Oever committed
116
    void ChainLink::setupConnections(const KoFilter *sender, const KoFilter *receiver) const
117
    {
Jos van den Oever's avatar
Jos van den Oever committed
118 119
        const QMetaObject * const parent = sender->metaObject();
        const QMetaObject * const child = receiver->metaObject();
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
        if (!parent || !child)
            return;

        int senderMethodCount = parent->methodCount();
        for (int i = 0; i < senderMethodCount; ++i) {
            QMetaMethod signal = parent->method(i);
            if (signal.methodType() != QMetaMethod::Signal)
                continue;
            // ### untested (QMetaMethod::signature())
            if (strncmp(signal.signature(), SIGNAL_PREFIX, SIGNAL_PREFIX_LEN) == 0) {
                int receiverMethodCount = child->methodCount();
                for (int j = 0; j < receiverMethodCount; ++j) {
                    QMetaMethod slot = child->method(j);
                    if (slot.methodType() != QMetaMethod::Slot)
                        continue;
                    if (strncmp(slot.signature(), SLOT_PREFIX, SLOT_PREFIX_LEN) == 0) {
                        if (strcmp(signal.signature() + SIGNAL_PREFIX_LEN, slot.signature() + SLOT_PREFIX_LEN) == 0) {
                            QByteArray signalString;
                            signalString.setNum(QSIGNAL_CODE);
                            signalString += signal.signature();
                            QByteArray slotString;
                            slotString.setNum(QSLOT_CODE);
                            slotString += slot.signature();
                            QObject::connect(sender, signalString, receiver, slotString);
                        }
145 146 147 148 149 150
                    }
                }
            }
        }
    }

Laurent Montel's avatar
Laurent Montel committed
151
}