1/*
2 * Copyright 2007 Aaron Seigo <aseigo@kde.org>
3 * Copyright 2007 Matt Broadstone <mbroadst@gmail.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU Library General Public License as
7 * published by the Free Software Foundation; either version 2, or
8 * (at your option) any later version.
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 Library General Public
16 * License 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#ifndef PLASMA_CORONA_H
22#define PLASMA_CORONA_H
23
24#include <QtGui/QGraphicsScene>
25
26#include <plasma/applet.h>
27#include <plasma/containment.h>
28#include <plasma/plasma.h>
29#include <plasma/plasma_export.h>
30
31class QGraphicsGridLayout;
32class QAction;
33
34class KAction;
35
36namespace Plasma
37{
38
39class CoronaPrivate;
40class ContainmentActionsPluginsConfig;
41class AbstractDialogManager;
42
43/**
44 * @class Corona plasma/corona.h <Plasma/Corona>
45 *
46 * @short A QGraphicsScene for Plasma::Applets
47 */
48class PLASMA_EXPORT Corona : public QGraphicsScene
49{
50 Q_OBJECT
51
52//typedef QHash<QString, QList<Plasma::Applet*> > layouts;
53
54public:
55 explicit Corona(QObject * parent = 0);
56 ~Corona();
57
58 /**
59 * Sets the mimetype of Drag/Drop items. Default is
60 * text/x-plasmoidservicename
61 */
62 void setAppletMimeType(const QString &mimetype);
63
64 /**
65 * The current mime type of Drag/Drop items.
66 */
67 QString appletMimeType();
68
69 /**
70 * @return the default containment plugin type
71 * @since 4.7
72 */
73 QString defaultContainmentPlugin() const;
74
75 /**
76 * @return all containments on this Corona
77 */
78 QList<Containment*> containments() const;
79
80 /**
81 * Clear the Corona from all applets.
82 */
83 void clearContainments();
84
85 /**
86 * Returns the config file used to store the configuration for this Corona
87 */
88 KSharedConfig::Ptr config() const;
89
90 /**
91 * Adds a Containment to the Corona
92 *
93 * @param name the plugin name for the containment, as given by
94 * KPluginInfo::pluginName(). If an empty string is passed in, the default
95 * containment plugin will be used (usually DesktopContainment). If the
96 * string literal "null" is passed in, then no plugin will be loaded and
97 * a simple Containment object will be created instead.
98 * @param args argument list to pass to the containment
99 *
100 * @return a pointer to the containment on success, or 0 on failure. Failure can be
101 * caused by too restrictive of an Immutability type, as containments cannot be added
102 * when widgets are locked, or if the requested containment plugin can not be located
103 * or successfully loaded.
104 */
105 Containment *addContainment(const QString &name, const QVariantList &args = QVariantList());
106
107 /**
108 * Loads a containment with delayed initialization, primarily useful
109 * for implementations of loadDefaultLayout. The caller is responsible
110 * for all initializating, saving and notification of a new containment.
111 *
112 * @param name the plugin name for the containment, as given by
113 * KPluginInfo::pluginName(). If an empty string is passed in, the defalt
114 * containment plugin will be used (usually DesktopContainment). If the
115 * string literal "null" is passed in, then no plugin will be loaded and
116 * a simple Containment object will be created instead.
117 * @param args argument list to pass to the containment
118 *
119 * @return a pointer to the containment on success, or 0 on failure. Failure can
120 * be caused by the Immutability type being too restrictive, as containments can't be added
121 * when widgets are locked, or if the requested containment plugin can not be located
122 * or successfully loaded.
123 * @see addContainment
124 **/
125 Containment *addContainmentDelayed(const QString &name,
126 const QVariantList &args = QVariantList());
127
128 /**
129 * Returns the Containment, if any, for a given physical screen and desktop
130 *
131 * @param screen number of the physical screen to locate
132 * @param desktop the virtual desktop) to locate; if < 0 then it will
133 * simply return the first Containment associated with screen
134 */
135 Containment *containmentForScreen(int screen, int desktop = -1) const;
136
137 /**
138 * Returns the Containment for a given physical screen and desktop, creating one
139 * if none exists
140 *
141 * @param screen number of the physical screen to locate
142 * @param desktop the virtual desktop) to locate; if < 0 then it will
143 * simply return the first Containment associated with screen
144 * @param defaultPluginIfNonExistent the plugin to load by default; "null" is an empty
145 * Containment and "default" creates the default plugin
146 * @param defaultArgs optional arguments to pass in when creating a Containment if needed
147 * @since 4.6
148 */
149 Containment *containmentForScreen(int screen, int desktop,
150 const QString &defaultPluginIfNonExistent,
151 const QVariantList &defaultArgs = QVariantList());
152 /**
153 * Adds a widget in the topleft quadrant in the scene. Widgets in the topleft quadrant are
154 * normally never shown unless you specifically aim a view at it, which makes it ideal for
155 * toplevel views etc.
156 * @param widget the widget to add.
157 */
158 void addOffscreenWidget(QGraphicsWidget *widget);
159
160 /**
161 * Removes a widget from the topleft quadrant in the scene.
162 * @param widget the widget to remove.
163 */
164 void removeOffscreenWidget(QGraphicsWidget *widget);
165
166 /**
167 * @return the list of all offscreen widgets
168 * @since 4.3
169 */
170 QList <QGraphicsWidget *> offscreenWidgets() const;
171
172 /**
173 * Returns the number of screens available to plasma.
174 * Subclasses should override this method as the default
175 * implementation returns a meaningless value.
176 */
177 virtual int numScreens() const;
178
179 /**
180 * Returns the geometry of a given screen.
181 * Valid screen ids are 0 to numScreen()-1, or -1 for the full desktop geometry.
182 * Subclasses should override this method as the default
183 * implementation returns a meaningless value.
184 */
185 virtual QRect screenGeometry(int id) const;
186
187 /**
188 * Returns the available region for a given screen.
189 * The available region excludes panels and similar windows.
190 * Valid screen ids are 0 to numScreens()-1.
191 * By default this method returns a rectangular region
192 * equal to screenGeometry(id); subclasses that need another
193 * behavior should override this method.
194 */
195 virtual QRegion availableScreenRegion(int id) const;
196
197 /**
198 * Recommended position for a popup window like a menu or a tooltip
199 * given its size
200 * @param item the item that the popup should appear adjacent to (an applet, say)
201 * @param size size of the popup
202 * @returns reccomended position
203 */
204 QPoint popupPosition(const QGraphicsItem *item, const QSize &size);
205
206 /**
207 * @since 4.4
208 * Recommended position for a popup window like a menu or a tooltip
209 * given its size
210 * @param item the item that the popup should appear adjacent to (an applet, say)
211 * @param size size of the popup
212 * @param alignment alignment of the popup, valid flags are Qt::AlignLeft, Qt::AlignRight and Qt::AlignCenter
213 * @returns reccomended position
214 */
215 QPoint popupPosition(const QGraphicsItem *item, const QSize &size, Qt::AlignmentFlag alignment);
216
217 /**
218 * This method is useful in order to retrieve the list of available
219 * screen edges for panel type containments.
220 * @param screen the id of the screen to look for free edges.
221 * @returns a list of free edges not filled with panel type containments.
222 */
223 QList<Plasma::Location> freeEdges(int screen) const;
224
225 /**
226 * Returns the QAction with the given name from our collection
227 */
228 QAction *action(QString name) const;
229
230 /**
231 * Adds the action to our collection under the given name
232 */
233 void addAction(QString name, QAction *action);
234
235 /**
236 * Returns all the actions in our collection
237 */
238 QList<QAction*> actions() const;
239
240 /**
241 * convenience function - enables or disables an action by name
242 *
243 * @param name the name of the action in our collection
244 * @param enable true to enable, false to disable
245 */
246 void enableAction(const QString &name, bool enable);
247
248 /**
249 * @since 4.3
250 * Updates keyboard shortcuts for all the corona's actions.
251 * If you've added actions to the corona you'll need to
252 * call this for them to be configurable.
253 */
254 void updateShortcuts();
255
256 /**
257 * @since 4.3
258 * Adds a set of actions to the shortcut config dialog.
259 * don't use this on actions in the corona's own actioncollection,
260 * those are handled automatically. this is for stuff outside of that.
261 */
262 void addShortcuts(KActionCollection *newShortcuts);
263
264 /**
265 * @since 4.3
266 * Creates an action in our collection under the given name
267 * @return the new action
268 * FIXME I'm wrapping so much of kactioncollection API now, maybe I should just expose the
269 * collection itself :P
270 */
271 KAction* addAction(QString name);
272
273 /**
274 * @since 4.4
275 * Sets the default containmentactions plugins for the given containment type
276 */
277 void setContainmentActionsDefaults(Containment::Type containmentType, const ContainmentActionsPluginsConfig &config);
278
279 /**
280 * @since 4.4
281 * Returns the default containmentactions plugins for the given containment type
282 */
283 ContainmentActionsPluginsConfig containmentActionsDefaults(Containment::Type containmentType);
284
285 /**
286 * @param the AbstractDialogManager implementaion
287 *
288 * @since 4.5
289 */
290 void setDialogManager(AbstractDialogManager *manager);
291
292 /**
293 * @return the AbstractDialogManager that will show dialogs used by applets, like configuration dialogs
294 *
295 * @since 4.5
296 */
297 AbstractDialogManager *dialogManager();
298
299 /**
300 * Imports an applet layout from a config file. The results will be added to the
301 * current set of Containments.
302 * @deprecated Use the 4.6 version that takes a KConfigGroup
303 *
304 * @param config the name of the config file to load from,
305 * or the default config file if QString()
306 * @return the list of containments that were loaded
307 * @since 4.5
308 */
309#ifndef KDE_NO_DEPRECATED
310 KDE_DEPRECATED QList<Plasma::Containment *> importLayout(const KConfigBase &config);
311#endif
312
313 /**
314 * Returns the name of the preferred plugin to be used as containment toolboxes.
315 * CustomContainments and CustomPanelContainments can still override it as their liking. It's also not guaranteed that the plugin will actually exist.
316 *
317 * @param type the containment type of which we want to know the associated toolbox plugin
318 * @since 4.6
319 */
320 QString preferredToolBoxPlugin(const Containment::Type type) const;
321
322 /**
323 * Imports an applet layout from a config file. The results will be added to the
324 * current set of Containments.
325 *
326 * @param config the name of the config file to load from,
327 * or the default config file if QString()
328 * @return the list of containments that were loaded
329 * @since 4.6
330 */
331 QList<Plasma::Containment *> importLayout(const KConfigGroup &config);
332
333 /**
334 * Exports a set of containments to a config file.
335 *
336 * @param config the config group to save to
337 * @param containments the list of containments to save
338 * @since 4.6
339 */
340 void exportLayout(KConfigGroup &config, QList<Containment*> containments);
341
342public Q_SLOTS:
343 /**
344 * Initializes the layout from a config file. This will first clear any existing
345 * Containments, load a layout from the requested configuration file, request the
346 * default layout if needed and update immutability.
347 *
348 * @param config the name of the config file to load from,
349 * or the default config file if QString()
350 */
351 void initializeLayout(const QString &config = QString());
352
353 /**
354 * Load applet layout from a config file. The results will be added to the
355 * current set of Containments.
356 *
357 * @param config the name of the config file to load from,
358 * or the default config file if QString()
359 */
360 void loadLayout(const QString &config = QString());
361
362 /**
363 * Save applets layout to file
364 * @param config the file to save to, or the default config file if QString()
365 */
366 void saveLayout(const QString &config = QString()) const;
367
368 /**
369 * @return The type of immutability of this Corona
370 */
371 ImmutabilityType immutability() const;
372
373 /**
374 * Sets the immutability type for this Corona (not immutable,
375 * user immutable or system immutable)
376 * @param immutable the new immutability type of this applet
377 */
378 void setImmutability(const ImmutabilityType immutable);
379
380 /**
381 * Schedules a flush-to-disk synchronization of the configuration state
382 * at the next convenient moment.
383 */
384 void requestConfigSync();
385
386 /**
387 * Schedules a time sensitive flush-to-disk synchronization of the
388 * configuration state. Since this method does not provide any sort of
389 * event compression, it should only be used when an *immediate* disk
390 * sync is *absolutely* required. Otherwise, use @see requestConfigSync()
391 * which does do event compression.
392 */
393 void requireConfigSync();
394
395 /**
396 * @since 4.5
397 * Layout the containments on this corona. The default implementation
398 * organizes them in a grid-like view, but subclasses can reimplement
399 * this slot to provide their own layout.
400 */
401 void layoutContainments();
402
403Q_SIGNALS:
404 /**
405 * This signal indicates a new containment has been added to
406 * the Corona
407 */
408 void containmentAdded(Plasma::Containment *containment);
409
410 /**
411 * This signal indicates that a containment has been newly
412 * associated (or dissociated) with a physical screen.
413 *
414 * @param wasScreen the screen it was associated with
415 * @param isScreen the screen it is now associated with
416 * @param containment the containment switching screens
417 */
418 void screenOwnerChanged(int wasScreen, int isScreen, Plasma::Containment *containment);
419
420 /**
421 * This signal indicates that an application launch, window
422 * creation or window focus event was triggered. This is used, for instance,
423 * to ensure that the Dashboard view in Plasma hides when such an event is
424 * triggered by an item it is displaying.
425 */
426 void releaseVisualFocus();
427
428 /**
429 * This signal indicates that the configuration file was flushed to disc.
430 */
431 void configSynced();
432
433 /**
434 * This signal inicates that a change in available screen goemetry occurred.
435 */
436 void availableScreenRegionChanged();
437
438 /**
439 * emitted when immutability changes.
440 * this is for use by things that don't get contraints events, like plasmaapp.
441 * it's NOT for containments or applets or any of the other stuff on the scene.
442 * if your code's not in shells/ it probably shouldn't be using it.
443 */
444 void immutabilityChanged(Plasma::ImmutabilityType immutability);
445
446 /**
447 * @since 4.3
448 * emitted when the user changes keyboard shortcut settings
449 * connect to this if you've put some extra shortcuts in your app
450 * that are NOT in corona's actioncollection.
451 * if your code's not in shells/ it probably shouldn't be using this function.
452 * @see addShortcuts
453 */
454 void shortcutsChanged();
455
456protected:
457 /**
458 * Loads the default (system wide) layout for this user
459 **/
460 virtual void loadDefaultLayout();
461
462 /**
463 * Maps a stock animation to one of the semantic animations. Used to control things such
464 * as what animation is used to make a Plasma::Appear appear in a containment.
465 * @param from the animation to map a new value to
466 * @param to the animation value to map to from
467 * @since 4.5
468 */
469 void mapAnimation(Animator::Animation from, Animator::Animation to);
470
471 /**
472 * Maps a loadable animation to one of the semantic animations. Used to control things such
473 * as what animation is used to make a Plasma::Appear appear in a containment.
474 * @param from the animation to map a new value to
475 * @param to the animation value to map to from; this must map to a Javascript animation
476 * @since 4.5
477 */
478 void mapAnimation(Animator::Animation from, const QString &to);
479
480 /**
481 * @return The preferred toolbox plugin name for a given containment type.
482 * @param type the containment type of which we want to know the preferred toolbox plugin.
483 * @param plugin the toolbox plugin name
484 * @since 4.6
485 */
486 void setPreferredToolBoxPlugin(const Containment::Type type, const QString &plugin);
487
488 /**
489 * Sets the default containment plugin to try and load
490 * @since 4.7
491 */
492 void setDefaultContainmentPlugin(const QString &name);
493
494 //Reimplemented from QGraphicsScene
495 void dragEnterEvent(QGraphicsSceneDragDropEvent *event);
496 void dragLeaveEvent(QGraphicsSceneDragDropEvent *event);
497 void dragMoveEvent(QGraphicsSceneDragDropEvent *event);
498
499private:
500 CoronaPrivate *const d;
501
502 Q_PRIVATE_SLOT(d, void containmentDestroyed(QObject*))
503 Q_PRIVATE_SLOT(d, void offscreenWidgetDestroyed(QObject *))
504 Q_PRIVATE_SLOT(d, void syncConfig())
505 Q_PRIVATE_SLOT(d, void toggleImmutability())
506 Q_PRIVATE_SLOT(d, void showShortcutConfig())
507
508 friend class CoronaPrivate;
509 friend class View;
510};
511
512} // namespace Plasma
513
514#endif
515
516