1 /****************************************************************************************
2  * Copyright (c) 2007 Maximilian Kossick <maximilian.kossick@googlemail.com>            *
3  * Copyright (c) 2007 Nikolaj Hald Nielsen <nhn@kde.org>                                *
4  *                                                                                      *
5  * This program is free software; you can redistribute it and/or modify it under        *
6  * the terms of the GNU General Public License as published by the Free Software        *
7  * Foundation; either version 2 of the License, or (at your option) any later           *
8  * version.                                                                             *
9  *                                                                                      *
10  * This program is distributed in the hope that it will be useful, but WITHOUT ANY      *
11  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A      *
12  * PARTICULAR PURPOSE. See the GNU General Public License for more details.             *
13  *                                                                                      *
14  * You should have received a copy of the GNU General Public License along with         *
15  * this program.  If not, see <http://www.gnu.org/licenses/>.                           *
16  ****************************************************************************************/
17 
18 #define DEBUG_PREFIX "ServicePluginManager"
19 
20 #include "ServicePluginManager.h"
21 
22 #include "browsers/servicebrowser/ServiceBrowser.h"
23 #include "core/support/Debug.h"
24 #include "services/ServiceBase.h"
25 
26 #include <KService>
27 
28 #include <QSet>
29 #include <QCoreApplication>
30 
31 ServicePluginManager *ServicePluginManager::s_instance = nullptr;
32 
33 ServicePluginManager *
instance()34 ServicePluginManager::instance()
35 {
36     if( !s_instance ) {
37         s_instance = new ServicePluginManager();
38     }
39 
40     return s_instance;
41 }
42 
43 
44 void
destroy()45 ServicePluginManager::destroy()
46 {
47     if( s_instance ) {
48         delete s_instance;
49         s_instance = nullptr;
50     }
51 }
52 
53 
ServicePluginManager()54 ServicePluginManager::ServicePluginManager()
55     : QObject()
56 {
57     DEBUG_BLOCK
58     // ensure this object is created in a main thread
59     Q_ASSERT( thread() == QCoreApplication::instance()->thread() );
60 
61     setObjectName( QStringLiteral("ServicePluginManager") );
62 }
63 
64 
~ServicePluginManager()65 ServicePluginManager::~ServicePluginManager()
66 {
67 }
68 
69 
70 void
setFactories(const QList<QSharedPointer<Plugins::PluginFactory>> & factories)71 ServicePluginManager::setFactories( const QList<QSharedPointer<Plugins::PluginFactory> > &factories )
72 {
73     QSet<QSharedPointer<Plugins::PluginFactory> > newFactories = factories.toSet();
74     QSet<QSharedPointer<Plugins::PluginFactory> > oldFactories = m_factories.toSet();
75 
76     // remove old factories
77     for( const auto &pFactory : oldFactories - newFactories )
78     {
79         auto factory = qobject_cast<ServiceFactory*>( pFactory );
80         if( !factory )
81             continue;
82 
83         foreach( ServiceBase * service, factory->activeServices() )
84             ServiceBrowser::instance()->removeCategory( service );
85         factory->clearActiveServices();
86     }
87 
88     // create new factories
89     for( const auto &pFactory : newFactories - oldFactories )
90     {
91         auto factory = qobject_cast<ServiceFactory*>( pFactory );
92         if( !factory )
93             continue;
94 
95         connect( factory.data(), &ServiceFactory::newService, this, &ServicePluginManager::slotNewService );
96         connect( factory.data(), &ServiceFactory::removeService, this, &ServicePluginManager::slotRemoveService );
97     }
98 
99     m_factories = factories;
100 }
101 
102 void
slotNewService(ServiceBase * newService)103 ServicePluginManager::slotNewService( ServiceBase *newService )
104 {
105     DEBUG_BLOCK
106     debug() << "new service:" << newService->name();
107     ServiceBrowser::instance()->addCategory( newService );
108 }
109 
110 void
slotRemoveService(ServiceBase * removedService)111 ServicePluginManager::slotRemoveService( ServiceBase *removedService )
112 {
113     DEBUG_BLOCK
114     debug() << "removed service:" << removedService->name();
115     ServiceBrowser::instance()->removeCategory( removedService );
116 }
117 
118 QStringList
loadedServices() const119 ServicePluginManager::loadedServices() const
120 {
121     QStringList names;
122     for( const auto &pFactory : m_factories )
123     {
124         auto factory = qobject_cast<ServiceFactory*>( pFactory );
125         if( !factory )
126             continue;
127 
128         foreach( ServiceBase *service, factory->activeServices() )
129             names << service->name();
130     }
131     return names;
132 }
133 
134 QStringList
loadedServiceNames() const135 ServicePluginManager::loadedServiceNames() const
136 {
137     return ServiceBrowser::instance()->categories().keys();
138 }
139 
140 QString
serviceDescription(const QString & serviceName)141 ServicePluginManager::serviceDescription( const QString & serviceName )
142 {
143     //get named service
144     if ( !ServiceBrowser::instance()->categories().contains( serviceName ) )
145     {
146         return i18n( "No service named %1 is currently loaded", serviceName );
147     }
148 
149     ServiceBase * service = dynamic_cast<ServiceBase *>( ServiceBrowser::instance()->categories().value( serviceName ) );
150 
151     if ( service == 0 )
152         return QString();
153 
154     return service->shortDescription();
155 }
156 
157 QString
serviceMessages(const QString & serviceName)158 ServicePluginManager::serviceMessages( const QString & serviceName )
159 {
160     //get named service
161     if ( !ServiceBrowser::instance()->categories().contains( serviceName ) )
162     {
163         return i18n( "No service named %1 is currently loaded", serviceName );
164     }
165 
166     ServiceBase * service = dynamic_cast<ServiceBase *>( ServiceBrowser::instance()->categories().value( serviceName ) );
167 
168     if ( service == 0 )
169         return QString();
170 
171     return service->messages();
172 }
173 
174 QString
sendMessage(const QString & serviceName,const QString & message)175 ServicePluginManager::sendMessage( const QString & serviceName, const QString & message )
176 {
177     //get named service
178     if ( !ServiceBrowser::instance()->categories().contains( serviceName ) )
179     {
180         return i18n( "No service named %1 is currently loaded", serviceName );
181     }
182 
183     ServiceBase * service = dynamic_cast<ServiceBase *>( ServiceBrowser::instance()->categories().value( serviceName ) );
184 
185     if ( service == 0 )
186         return QString();
187 
188     return service->sendMessage( message );
189 }
190 
191