source: calamares/trunk/fuentes/src/libcalamares/utils/PluginFactory.cpp @ 7538

Last change on this file since 7538 was 7538, checked in by kbut, 13 months ago

sync with github

File size: 4.4 KB
Line 
1/* === This file is part of Calamares - <https://github.com/calamares> ===
2 *
3 *   Copyright 2015, Teo Mrnjavac <teo@kde.org>
4 *   Copyright 2017, Adriaan de Groot <groot@kde.org>
5 *
6 *   Based on KPluginFactory from KCoreAddons, KDE project
7 *   Copyright 2007, Matthias Kretz <kretz@kde.org>
8 *   Copyright 2007, Bernhard Loos <nhuh.put@web.de>
9 *
10 *   Calamares is free software: you can redistribute it and/or modify
11 *   it under the terms of the GNU General Public License as published by
12 *   the Free Software Foundation, either version 3 of the License, or
13 *   (at your option) any later version.
14 *
15 *   Calamares is distributed in the hope that it will be useful,
16 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
17 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 *   GNU General Public License for more details.
19 *
20 *   You should have received a copy of the GNU General Public License
21 *   along with Calamares. If not, see <http://www.gnu.org/licenses/>.
22 */
23
24#include "PluginFactory.h"
25#include "PluginFactory_p.h"
26
27#include <QObjectCleanupHandler>
28#include <QDebug>
29
30Q_GLOBAL_STATIC( QObjectCleanupHandler, factorycleanup )
31
32namespace Calamares
33{
34
35PluginFactory::PluginFactory()
36    : pd_ptr( new PluginFactoryPrivate )
37{
38    pd_ptr->q_ptr = this;
39
40    factorycleanup()->add( this );
41}
42
43PluginFactory::PluginFactory( PluginFactoryPrivate& d )
44    : pd_ptr( &d )
45{
46    factorycleanup()->add( this );
47}
48
49PluginFactory::~PluginFactory()
50{
51    delete pd_ptr;
52}
53
54void PluginFactory::doRegisterPlugin( const QString& keyword, const QMetaObject* metaObject, CreateInstanceFunction instanceFunction )
55{
56    Q_ASSERT( metaObject );
57
58    // we allow different interfaces to be registered without keyword
59    if ( !keyword.isEmpty() )
60    {
61        if ( pd_ptr->createInstanceHash.contains( keyword ) )
62            qWarning() << "A plugin with the keyword" << keyword << "was already registered. A keyword must be unique!";
63        pd_ptr->createInstanceHash.insert( keyword, PluginFactoryPrivate::Plugin( metaObject, instanceFunction ) );
64    }
65    else
66    {
67        const QList<PluginFactoryPrivate::Plugin> clashes( pd_ptr->createInstanceHash.values( keyword ) );
68        const QMetaObject* superClass = metaObject->superClass();
69        if ( superClass )
70        {
71            for ( const PluginFactoryPrivate::Plugin& plugin : clashes )
72            {
73                for ( const QMetaObject* otherSuper = plugin.first->superClass(); otherSuper;
74                        otherSuper = otherSuper->superClass() )
75                {
76                    if ( superClass == otherSuper )
77                        qWarning() << "Two plugins with the same interface(" << superClass->className() << ") were registered. Use keywords to identify the plugins.";
78                }
79            }
80        }
81        for ( const PluginFactoryPrivate::Plugin& plugin : clashes )
82        {
83            superClass = plugin.first->superClass();
84            if ( superClass )
85            {
86                for ( const QMetaObject* otherSuper = metaObject->superClass(); otherSuper;
87                        otherSuper = otherSuper->superClass() )
88                {
89                    if ( superClass == otherSuper )
90                        qWarning() << "Two plugins with the same interface(" << superClass->className() << ") were registered. Use keywords to identify the plugins.";
91                }
92            }
93        }
94        pd_ptr->createInstanceHash.insertMulti( keyword, PluginFactoryPrivate::Plugin( metaObject, instanceFunction ) );
95    }
96}
97
98QObject* PluginFactory::create( const char* iface, QWidget* parentWidget, QObject* parent, const QString& keyword )
99{
100    QObject* obj = nullptr;
101
102    const QList<PluginFactoryPrivate::Plugin> candidates( pd_ptr->createInstanceHash.values( keyword ) );
103    // for !keyword.isEmpty() candidates.count() is 0 or 1
104
105    for ( const PluginFactoryPrivate::Plugin& plugin : candidates )
106    {
107        for ( const QMetaObject* current = plugin.first; current; current = current->superClass() )
108        {
109            if ( 0 == qstrcmp( iface, current->className() ) )
110            {
111                if ( obj )
112                    qWarning() << "ambiguous interface requested from a DSO containing more than one plugin";
113                obj = plugin.second( parentWidget, parent );
114                break;
115            }
116        }
117    }
118
119    if ( obj )
120        emit objectCreated( obj );
121    return obj;
122}
123
124}
Note: See TracBrowser for help on using the repository browser.