modernize: Replace most remaining old-style connects by PMF ones
[quassel.git] / src / common / basichandler.cpp
1 /***************************************************************************
2  *   Copyright (C) 2005-2018 by the Quassel Project                        *
3  *   devel@quassel-irc.org                                                 *
4  *                                                                         *
5  *   This program is free software; you can redistribute it and/or modify  *
6  *   it under the terms of the GNU General Public License as published by  *
7  *   the Free Software Foundation; either version 2 of the License, or     *
8  *   (at your option) version 3.                                           *
9  *                                                                         *
10  *   This program is distributed in the hope that it will be useful,       *
11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
13  *   GNU General Public License for more details.                          *
14  *                                                                         *
15  *   You should have received a copy of the GNU General Public License     *
16  *   along with this program; if not, write to the                         *
17  *   Free Software Foundation, Inc.,                                       *
18  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.         *
19  ***************************************************************************/
20
21 #include "basichandler.h"
22
23 #include <QDebug>
24 #include <QMetaMethod>
25 #include <utility>
26
27 BasicHandler::BasicHandler(QObject *parent)
28     : QObject(parent),
29     _methodPrefix("handle")
30 {
31 }
32
33
34 BasicHandler::BasicHandler(QString methodPrefix, QObject *parent)
35     : QObject(parent),
36     _methodPrefix(std::move(methodPrefix))
37 {
38 }
39
40
41 QStringList BasicHandler::providesHandlers()
42 {
43     return handlerHash().keys();
44 }
45
46
47 const QHash<QString, int> &BasicHandler::handlerHash()
48 {
49     if (!_initDone) {
50         for (int i = metaObject()->methodOffset(); i < metaObject()->methodCount(); i++) {
51             QString methodSignature = metaObject()->method(i).methodSignature();
52             if (methodSignature.startsWith("defaultHandler")) {
53                 _defaultHandler = i;
54                 continue;
55             }
56
57             if (!methodSignature.startsWith(_methodPrefix))
58                 continue;
59
60             methodSignature = methodSignature.section('(', 0, 0); // chop the attribute list
61             methodSignature = methodSignature.mid(_methodPrefix.length()); // strip "handle" or whatever the prefix is
62             _handlerHash[methodSignature] = i;
63         }
64         _initDone = true;
65     }
66     return _handlerHash;
67 }
68
69
70 void BasicHandler::handle(const QString &member, QGenericArgument val0,
71     QGenericArgument val1, QGenericArgument val2,
72     QGenericArgument val3, QGenericArgument val4,
73     QGenericArgument val5, QGenericArgument val6,
74     QGenericArgument val7, QGenericArgument val8)
75 {
76     // Now we try to find a handler for this message. BTW, I do love the Trolltech guys ;-)
77     // and now we even have a fast lookup! Thanks thiago!
78
79     QString handler = member.toLower();
80     handler[0] = handler[0].toUpper();
81
82     if (!handlerHash().contains(handler)) {
83         if (_defaultHandler == -1) {
84             qWarning() << QString("No such Handler: %1::%2%3").arg(metaObject()->className(), _methodPrefix, handler);
85             return;
86         }
87         else {
88             void *param[] = { nullptr, Q_ARG(QString, member).data(), val0.data(), val1.data(), val2.data(), val3.data(), val4.data(),
89                               val5.data(), val6.data(), val7.data(), val8.data(), val8.data() };
90             qt_metacall(QMetaObject::InvokeMetaMethod, _defaultHandler, param);
91             return;
92         }
93     }
94
95     void *param[] = { nullptr, val0.data(), val1.data(), val2.data(), val3.data(), val4.data(),
96                       val5.data(), val6.data(), val7.data(), val8.data(), val8.data(), nullptr };
97     qt_metacall(QMetaObject::InvokeMetaMethod, handlerHash()[handler], param);
98 }