summaryrefslogtreecommitdiffstats
path: root/src/profileengine/lib/profileengine.h
blob: 34e14a93dfc13886ca9b8d3dda1be3f2b95b120f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
/***************************************************************************
 *   Copyright (C) 2004 by Alexander Dymo <adymo@kdevelop.org>             *
 *                                                                         *
 *   This program 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.                       *
 *                                                                         *
 *   This program 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 General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU Library General Public     *
 *   License along with this program; if not, write to the                 *
 *   Free Software Foundation, Inc.,                                       *
 *   51 Franklin Street, Fifth Floor, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#ifndef PROFILEENGINE_H
#define PROFILEENGINE_H

#include <qmap.h>

#include <ktrader.h>

#include "profile.h"

/**
Profile listing operation.
Used to get a plain list of profiles
and store it in the QMap<QString, Profile*>.
*/
class ProfileListing{
public:
    void operator() (Profile *profile)
    {
        profiles[profile->name()] = profile;
    }

    QMap<QString, Profile*> profiles;
};

/**Profile resource listing operation.
Used to get a list of urls to the profile resources.

Resource urls can be filtered by an @p filter parameter
passed to the constructor. Filter can have values
as described in @ref QDir::setNameFilter function documentation.*/
class ProfileListingEx {
public:
    ProfileListingEx(const QString &filter): m_filter(filter) {}
    void operator() (Profile *profile)
    {
        resourceList += profile->resources(m_filter);
    }
    
    KURL::List resourceList;
    QString m_filter;
};

/**
Profile engine.

- Uses KDevelop profiles to form lists of plugin offers;
- Provides means of managing profiles;
- Provides means to access the resources provided by a profile.

KDevelop profiles form a tree with a root profile named "KDevelop".
For example, such profiles tree can look as:
@code
KDevelop
- IDE
  - CompiledLanguageIDE
    - AdaIDE
    - CandCppIDE
      - CIDE
      - CppIDE
        - KDECppIDE
    - FortranIDE
    ...
  - DatabaseIDE
  - ScriptingLanguageIDE
  ..
- KDevAssistant
@endcode
To manage a tree of profiles, use @ref ProfileEngine::walkProfiles methods.
*/
class ProfileEngine {
public:
    ProfileEngine();
    ~ProfileEngine();

    /**Type of the plugin offer. Engine will usually find profiles and return offers
    of selected type.
    @sa KDevPlugin class documentation for more information of plugin types.*/
    enum OfferType { 
        Global    /**<Global plugins.*/,
        Project   /**<Project plugins.*/,
        Core      /**<Core plugins.*/
    };
    
    /**@return The list of plugin offers for given profile and type.*/
    KTrader::OfferList offers(const QString &profileName, OfferType offerType);
    /**@return The list of all plugin offers for given type.*/
    KTrader::OfferList allOffers(OfferType offerType);
    
    /**@return The list of URLs to the resources (files) with given @p extension.
    @param profileName A name of a profile to find resources in.
    @param nameFilter Name filter for files. @see QDir::setNameFilter documentation
    for name filters syntax.*/
    KURL::List resources(const QString &profileName, const QString &nameFilter);
    
    /**@return The list of URLs to the resources (files) with given @p extension.
    This list is obtained by a recursive search that process given profile
    and all it's subprofiles.
    @param profileName A name of a profile to find resources in.
    @param nameFilter Name filter for files. @see QDir::setNameFilter documentation
    for name filters syntax.*/
    KURL::List resourcesRecursive(const QString &profileName, const QString &nameFilter);
    
    /**Adds a resource for the profile. Resource will be copied to the user profile directory
    (like $HOME/.kde/share/apps/kdevelop/profiles/...).
    @param profileName A name of the profile.
    @param url The url to a file to copy as a profile resource.*/
    void addResource(const QString &profileName, const KURL &url);
    
    /**Gets the difference between @p profile1 and @p profile2.
    Difference is calculated as two lists of plugins to be unloaded and loaded
    in order to switch from @p profile1 to @p profile2.
    @param offerType A type of plugin offers to list.
    @param profile1 A name of the first profile.
    @param profile2 A name of the second profile.
    @param unload Will be filled with a list of plugins to unload.
    @param load Will be filled with a list of plugins to load.
    @note Resulting lists are not cleared. Pass only clean lists in the
    common case.*/
    void diffProfiles(OfferType offerType, const QString &profile1, const QString &profile2, 
        QStringList &unload, KTrader::OfferList &load);

    /**@return The root profile. Root profile is always named "KDevelop" and it
    defines an empty list of plugins. Applications built on KDevelop platform
    will define nested profiles.*/
    Profile *rootProfile() const { return m_rootProfile; }
    /**Finds a profile with given name.
    @return The profile found or 0 if it does not exist.*/
    Profile *findProfile(const QString &profileName);
    
    /**Walks profiles tree and applies operation @p op to each profile found 
    in the tree below @p root (@p root profile itself is not processed).
    
    Operation is a class that have operator(Profile *).
    Example of operation class which is used to build a plain list of profiles:
    @code
    class ProfileListing{
    public:
        void operator() (Profile *profile)
        {
            profiles[profile->name()] = profile;
        }
    
        QMap<QString, Profile*> profiles;
    };
    @endcode
    Use case for such operation - building a list of all profiles:
    @code
    ProfileEngine engine;
    ProfileListing listing;
    engine.walkProfiles<ProfileListing>(listing, engine.rootProfile());
    @endcode
    
    @note @ref ProfileListing and @ref ProfileListingEx operations are already defined in 
    profileengine.h header file.
    
    @param op An operation to apply.
    @param root A profile to start walking from. Complete subtree of the @p root is traversed.
    */
    template<class Operation>
    void walkProfiles(Operation &op, Profile *root)
    {
        QValueList<Profile*> children = root->children();
        for (QValueList<Profile*>::iterator it = children.begin(); it != children.end(); ++it)
        {
            op(*it);
            walkProfiles<Operation>(op, *it);
        }
    }
    /**Walks profiles tree and applies operation @p op to each profile 
    found in the tree below @p root (@p root profile itself is not processed)
    but the operation in this case returns a result of type defined by
    "Result" template parameter.
    
    When iterating the tree, the result of operation applied to the parent profile 
    is passed as @p result parameter to the recursive call for child profiles.
    
    For example, this function can be used to build another hierarcy of profiles
    or other objects connected to profiles.
    Example of operation class which is used to build a listview with items
    where each item represents a profile:
    @code
    class ProfileListBuilding {
    public:
        ProfileItem * operator() (ProfileItem *parent, Profile *profile)
        {
            parent->setOpen(true);
            return new ProfileItem(parent, profile);
        }
    };
    
    class ProfileItem: public KListViewItem {
    public:
        ProfileItem(KListView *parent, Profile *profile)
            :KListViewItem(parent), m_profile(profile)
        {
            setText(0, profile->genericName());
            setText(1, profile->description());
        }
        
        ProfileItem(KListViewItem *parent, Profile *profile)
            : KListViewItem(parent), m_profile(profile)
        {
            setText(0, profile->genericName());
            setText(1, profile->description());
        }
        
        Profile *profile() const { return m_profile; }
        
    private:
        Profile *m_profile;
    };

    @endcode
    Use case for such operation - building a listview:
    @code
    ProfileEngine engine;
    ProfileItem *item = new ProfileItem(profilesList, engine.rootProfile());
    ProfileListBuilding op;
    engine.walkProfiles<ProfileListBuilding, ProfileItem>(op, item, engine.rootProfile());
    @endcode
    
    @param op An operation to apply.
    @param result A result of the operation as it would have been applied to the @p root.
    @param root A profile to start walking from. Complete subtree of the @p root is traversed.
    */
    template<class Operation, class Result>
    void walkProfiles(Operation &op, Result *result, Profile *root)
    {
        QValueList<Profile*> children = root->children();
        for (QValueList<Profile*>::iterator it = children.begin(); it != children.end(); ++it)
        {
            Result *newResult = op(result, *it);
            walkProfiles<Operation>(op, newResult, *it);
        }
    }

protected:
    void processDir(const QString &dir, const QString &currPath, QMap<QString, Profile*> &passedPaths, Profile *root);

    KURL::List resources(Profile *profile, const QString &nameFilter);
    
    /**Gets a complete listing of available profiles and looks for a profile.
    @param listing Profiles listing will be saved here.
    @param profile Will be a pointer to a profile with the name @p profileName or 0
    if no profile with that name is found.
    @param profileName The name of a profile to find.*/
    void getProfileWithListing(ProfileListing &listing, Profile **profile, 
        const QString &profileName);
    
private:
    Profile *m_rootProfile;
};

#endif