1 | /* |
2 | * Copyright 2007 by Aaron Seigo <aseigo@kde.org> |
3 | * Copyright 2008 by Ménard Alexis <darktears31@gmail.com> |
4 | * Copyright (c) 2009 Chani Armitage <chani@kde.org> |
5 | * |
6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU Library General Public License as |
8 | * published by the Free Software Foundation; either version 2, or |
9 | * (at your option) any later version. |
10 | * |
11 | * This program is distributed in the hope that it will be useful, |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | * GNU General Public License for more details |
15 | * |
16 | * You should have received a copy of the GNU Library General Public |
17 | * License along with this program; if not, write to the |
18 | * Free Software Foundation, Inc., |
19 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
20 | */ |
21 | |
22 | #ifndef PLASMA_CONTAINMENT_H |
23 | #define PLASMA_CONTAINMENT_H |
24 | |
25 | #include <QtGui/QGraphicsItem> |
26 | #include <QtGui/QWidget> |
27 | #include <QtGui/QStyleOptionGraphicsItem> |
28 | |
29 | #include <kplugininfo.h> |
30 | #include <ksharedconfig.h> |
31 | #include <kgenericfactory.h> |
32 | |
33 | #include <plasma/applet.h> |
34 | #include <plasma/animator.h> |
35 | |
36 | |
37 | namespace Plasma |
38 | { |
39 | |
40 | class AccessAppletJob; |
41 | class AppletHandle; |
42 | class DataEngine; |
43 | class Package; |
44 | class Corona; |
45 | class View; |
46 | class Wallpaper; |
47 | class ContainmentActions; |
48 | class ContainmentPrivate; |
49 | class AbstractToolBox; |
50 | |
51 | /** |
52 | * @class Containment plasma/containment.h <Plasma/Containment> |
53 | * |
54 | * @short The base class for plugins that provide backgrounds and applet grouping containers |
55 | * |
56 | * Containment objects provide the means to group applets into functional sets. |
57 | * They also provide the following: |
58 | * |
59 | * creation of focussing event |
60 | * - drawing of the background image (which can be interactive) |
61 | * - form factors (e.g. panel, desktop, full screen, etc) |
62 | * - applet layout management |
63 | * |
64 | * Since containment is actually just a Plasma::Applet, all the techniques used |
65 | * for writing the visual presentation of Applets is applicable to Containtments. |
66 | * Containments are differentiated from Applets by being marked with the ServiceType |
67 | * of Plasma/Containment. Plugins registered with both the Applet and the Containment |
68 | * ServiceTypes can be loaded for us in either situation. |
69 | * |
70 | * See techbase.kde.org for a tutorial on writing Containments using this class. |
71 | */ |
72 | class PLASMA_EXPORT Containment : public Applet |
73 | { |
74 | Q_OBJECT |
75 | |
76 | public: |
77 | class PLASMA_EXPORT StyleOption : public QStyleOptionGraphicsItem |
78 | { |
79 | public: |
80 | explicit StyleOption(); |
81 | explicit StyleOption(const StyleOption &other); |
82 | explicit StyleOption(const QStyleOptionGraphicsItem &other); |
83 | |
84 | enum StyleOptionType { |
85 | Type = SO_CustomBase + 1 |
86 | }; |
87 | enum StyleOptionVersion { |
88 | Version = QStyleOptionGraphicsItem::Version + 1 |
89 | }; |
90 | |
91 | /** |
92 | * The View, if any, that this containment is currently |
93 | * being rendered into. Note: this may be NULL, so be |
94 | * sure to check it before using it! |
95 | */ |
96 | Plasma::View *view; |
97 | }; |
98 | |
99 | enum Type { |
100 | NoContainmentType = -1, /**< @internal */ |
101 | DesktopContainment = 0, /**< A desktop containment */ |
102 | PanelContainment, /**< A desktop panel */ |
103 | CustomContainment = 127, /**< A containment that is neither a desktop nor a panel |
104 | but something application specific */ |
105 | CustomPanelContainment = 128 /**< A customized desktop panel */ |
106 | }; |
107 | |
108 | /** |
109 | * @param parent the QGraphicsItem this applet is parented to |
110 | * @param serviceId the name of the .desktop file containing the |
111 | * information about the widget |
112 | * @param containmentId a unique id used to differentiate between multiple |
113 | * instances of the same Applet type |
114 | */ |
115 | explicit Containment(QGraphicsItem *parent = 0, |
116 | const QString &serviceId = QString(), |
117 | uint containmentId = 0); |
118 | |
119 | /** |
120 | * This constructor is to be used with the plugin loading systems |
121 | * found in KPluginInfo and KService. The argument list is expected |
122 | * to have two elements: the KService service ID for the desktop entry |
123 | * and an applet ID which must be a base 10 number. |
124 | * |
125 | * @param parent a QObject parent; you probably want to pass in 0 |
126 | * @param args a list of strings containing two entries: the service id |
127 | * and the applet id |
128 | */ |
129 | Containment(QObject *parent, const QVariantList &args); |
130 | |
131 | ~Containment(); |
132 | |
133 | /** |
134 | * Reimplemented from Applet |
135 | */ |
136 | void init(); |
137 | |
138 | /** |
139 | * Returns the type of containment |
140 | */ |
141 | Type containmentType() const; |
142 | |
143 | /** |
144 | * Returns the Corona (if any) that this Containment is hosted by |
145 | */ |
146 | Corona *corona() const; |
147 | |
148 | /** |
149 | * Returns a list of all known containments. |
150 | * |
151 | * @param category Only containments matching this category will be returned. |
152 | * Useful in conjunction with knownCategories. |
153 | * If "Miscellaneous" is passed in, then applets without a |
154 | * Categories= entry are also returned. |
155 | * If an empty string is passed in, all applets are |
156 | * returned. |
157 | * @param parentApp the application to filter applets on. Uses the |
158 | * X-KDE-ParentApp entry (if any) in the plugin info. |
159 | * The default value of QString() will result in a |
160 | * list containing only applets not specifically |
161 | * registered to an application. |
162 | * @return list of applets |
163 | **/ |
164 | static KPluginInfo::List listContainments(const QString &category = QString(), |
165 | const QString &parentApp = QString()); |
166 | |
167 | /** |
168 | * Returns a list of all known Containments that match the parameters. |
169 | * |
170 | * @param type Only Containments with this string in X-Plasma-ContainmentCategories |
171 | * in their .desktop files will be returned. Common values are panel and |
172 | * desktop |
173 | * @param category Only applets matchin this category will be returned. |
174 | * Useful in conjunction with knownCategories. |
175 | * If "Miscellaneous" is passed in, then applets without a |
176 | * Categories= entry are also returned. |
177 | * If an empty string is passed in, all applets are |
178 | * returned. |
179 | * @param parentApp the application to filter applets on. Uses the |
180 | * X-KDE-ParentApp entry (if any) in the plugin info. |
181 | * The default value of QString() will result in a |
182 | * list containing only applets not specifically |
183 | * registered to an application. |
184 | * @return list of applets |
185 | **/ |
186 | static KPluginInfo::List listContainmentsOfType(const QString &type, |
187 | const QString &category = QString(), |
188 | const QString &parentApp = QString()); |
189 | |
190 | /** |
191 | * @return a list of all known types of Containments on this system |
192 | */ |
193 | static QStringList listContainmentTypes(); |
194 | |
195 | /** |
196 | * Returns a list of all known applets associated with a certain mimetype |
197 | * |
198 | * @return list of applets |
199 | **/ |
200 | static KPluginInfo::List listContainmentsForMimetype(const QString &mimetype); |
201 | |
202 | /** |
203 | * Adds an applet to this Containment |
204 | * |
205 | * @param name the plugin name for the applet, as given by |
206 | * KPluginInfo::pluginName() |
207 | * @param args argument list to pass to the plasmoid |
208 | * @param geometry where to place the applet, or to auto-place it if an invalid |
209 | * is provided |
210 | * |
211 | * @return a pointer to the applet on success, or 0 on failure |
212 | */ |
213 | Applet *addApplet(const QString &name, const QVariantList &args = QVariantList(), |
214 | const QRectF &geometry = QRectF(-1, -1, -1, -1)); |
215 | |
216 | /** |
217 | * Add an existing applet to this Containment |
218 | * |
219 | * If dontInit is true, the pending constraints are not flushed either. |
220 | * So it is your responsibility to call both init() and |
221 | * flushPendingConstraints() on the applet. |
222 | * |
223 | * @param applet the applet that should be added |
224 | * @param pos the containment-relative position |
225 | * @param dontInit if true, init() will not be called on the applet |
226 | */ |
227 | void addApplet(Applet *applet, const QPointF &pos = QPointF(-1, -1), bool dontInit = true); |
228 | |
229 | /** |
230 | * @return the applets currently in this Containment |
231 | */ |
232 | Applet::List applets() const; |
233 | |
234 | /** |
235 | * Removes all applets from this Containment |
236 | */ |
237 | void clearApplets(); |
238 | |
239 | /** |
240 | * Sets the physical screen this Containment is associated with. |
241 | * |
242 | * @param screen the screen number this containment is the desktop for, or -1 |
243 | * if it is not serving as the desktop for any screen |
244 | * @param desktop the virtual desktop to also associate this this screen with |
245 | */ |
246 | void setScreen(int screen, int desktop = -1); |
247 | |
248 | /** |
249 | * @return the screen number this containment is serving as the desktop for |
250 | * or -1 if none |
251 | */ |
252 | int screen() const; |
253 | |
254 | /** |
255 | * @return the last screen number this containment had |
256 | * only returns -1 if it's never ever been on a screen |
257 | * @since 4.5 |
258 | */ |
259 | int lastScreen() const; |
260 | |
261 | /** |
262 | * @return the viewport (e.g. virtual desktop) this Containment is associated with. |
263 | */ |
264 | int desktop() const; |
265 | |
266 | /** |
267 | * @return the viewport (e.g. virtual desktop) this Containment was associated with |
268 | * last time it had a screen |
269 | * @since 4.5 |
270 | */ |
271 | int lastDesktop() const; |
272 | |
273 | /** |
274 | * @reimp |
275 | * @sa Applet::save(KConfigGroup &) |
276 | */ |
277 | void save(KConfigGroup &group) const; |
278 | |
279 | /** |
280 | * @reimp |
281 | * @sa Applet::restore(KConfigGroup &) |
282 | */ |
283 | void restore(KConfigGroup &group); |
284 | |
285 | /** |
286 | * convenience function - enables or disables an action by name |
287 | * |
288 | * @param name the name of the action in our collection |
289 | * @param enable true to enable, false to disable |
290 | */ |
291 | void enableAction(const QString &name, bool enable); |
292 | |
293 | /** |
294 | * Add an action to the toolbox |
295 | */ |
296 | void addToolBoxAction(QAction *action); |
297 | |
298 | /** |
299 | * Remove an action from the toolbox |
300 | */ |
301 | void removeToolBoxAction(QAction *action); |
302 | |
303 | /** |
304 | * Sets the open or closed state of the Containment's toolbox |
305 | * |
306 | * @param open true to open the ToolBox, false to close it |
307 | */ |
308 | void setToolBoxOpen(bool open); |
309 | |
310 | /** |
311 | * @return true if the toolbox is open |
312 | * @since 4.5 |
313 | */ |
314 | bool isToolBoxOpen() const; |
315 | |
316 | /** |
317 | * Open the Containment's toolbox |
318 | */ |
319 | void openToolBox(); |
320 | |
321 | /** |
322 | * Closes Containment's toolbox |
323 | */ |
324 | void closeToolBox(); |
325 | |
326 | /** |
327 | * associate actions with this widget, including ones added after this call. |
328 | * needed to make keyboard shortcuts work. |
329 | */ |
330 | void addAssociatedWidget(QWidget *widget); |
331 | |
332 | /** |
333 | * un-associate actions from this widget, including ones added after this call. |
334 | * needed to make keyboard shortcuts work. |
335 | */ |
336 | void removeAssociatedWidget(QWidget *widget); |
337 | |
338 | /** |
339 | * Return whether wallpaper is painted or not. |
340 | */ |
341 | bool drawWallpaper(); |
342 | |
343 | /** |
344 | * Sets wallpaper plugin. |
345 | * |
346 | * @param pluginName the name of the wallpaper to attempt to load |
347 | * @param mode optional mode or the wallpaper plugin (e.g. "Slideshow"). |
348 | * These values are pugin specific and enumerated in the plugin's |
349 | * .desktop file. |
350 | */ |
351 | void setWallpaper(const QString &pluginName, const QString &mode = QString()); |
352 | |
353 | /** |
354 | * Return wallpaper plugin. |
355 | */ |
356 | Plasma::Wallpaper *wallpaper() const; |
357 | |
358 | /** |
359 | * Sets the current activity by name |
360 | * |
361 | * @param activity the name of the activity |
362 | */ |
363 | void setActivity(const QString &activity); |
364 | |
365 | /** |
366 | * @return the current activity name associated with this containment |
367 | */ |
368 | QString activity() const; |
369 | |
370 | /** |
371 | * @return the context for this containment |
372 | * @since 4.5 |
373 | */ |
374 | Context* context() const; |
375 | |
376 | /** |
377 | * Shows the context menu for the containment directly, bypassing Applets |
378 | * altogether. |
379 | */ |
380 | void (const QPointF &containmentPos, const QPoint &screenPos); |
381 | |
382 | /** |
383 | * Shows a visual clue for drag and drop |
384 | * The default implementation does nothing, |
385 | * reimplement in containments that need it |
386 | * |
387 | * @param pos point where to show the drop target; if an invalid point is passed in |
388 | * the drop zone should not be shown |
389 | */ |
390 | virtual void showDropZone(const QPoint pos); |
391 | |
392 | /** |
393 | * Sets a containmentactions plugin. |
394 | * |
395 | * @param trigger the mouse button (and optional modifier) to associate the plugin with |
396 | * @param pluginName the name of the plugin to attempt to load. blank = set no plugin. |
397 | * @since 4.4 |
398 | */ |
399 | void setContainmentActions(const QString &trigger, const QString &pluginName); |
400 | |
401 | /** |
402 | * @return a list of all triggers that have a containmentactions plugin associated |
403 | * @since 4.4 |
404 | */ |
405 | QStringList containmentActionsTriggers(); |
406 | |
407 | /** |
408 | * @return the plugin name for the given trigger |
409 | * @since 4.4 |
410 | */ |
411 | QString containmentActions(const QString &trigger); |
412 | |
413 | /** |
414 | * @return the config group that containmentactions plugins go in |
415 | * @since 4.6 |
416 | */ |
417 | KConfigGroup containmentActionsConfig(); |
418 | |
419 | Q_SIGNALS: |
420 | /** |
421 | * This signal is emitted when a new applet is created by the containment |
422 | */ |
423 | void appletAdded(Plasma::Applet *applet, const QPointF &pos); |
424 | |
425 | /** |
426 | * This signal is emitted when an applet is destroyed |
427 | */ |
428 | void appletRemoved(Plasma::Applet *applet); |
429 | |
430 | /** |
431 | * Emitted when the containment requests zooming in or out one step. |
432 | * @deprecated |
433 | */ |
434 | void zoomRequested(Plasma::Containment *containment, Plasma::ZoomDirection direction); |
435 | |
436 | /** |
437 | * Emitted when the user clicks on the toolbox |
438 | */ |
439 | void toolBoxToggled(); |
440 | |
441 | /** |
442 | * Emitted when the toolbox is hidden or shown |
443 | * @since 4.3 |
444 | */ |
445 | void toolBoxVisibilityChanged(bool); |
446 | |
447 | /** |
448 | * Emitted when the containment wants a new containment to be created. |
449 | * Usually only used for desktop containments. |
450 | */ |
451 | void addSiblingContainment(Plasma::Containment *); |
452 | |
453 | /** |
454 | * Emitted when the containment requests an add widgets dialog is shown. |
455 | * Usually only used for desktop containments. |
456 | * |
457 | * @param pos where in the containment this request was made from, or |
458 | * an invalid position (QPointF()) is not location specific |
459 | */ |
460 | void showAddWidgetsInterface(const QPointF &pos); |
461 | |
462 | /** |
463 | * This signal indicates that a containment has been newly |
464 | * associated (or dissociated) with a physical screen. |
465 | * |
466 | * @param wasScreen the screen it was associated with |
467 | * @param isScreen the screen it is now associated with |
468 | * @param containment the containment switching screens |
469 | */ |
470 | void screenChanged(int wasScreen, int isScreen, Plasma::Containment *containment); |
471 | |
472 | /** |
473 | * Emitted when the user wants to configure/change containment. |
474 | */ |
475 | void configureRequested(Plasma::Containment *containment); |
476 | |
477 | /** |
478 | * The context associated to this containment has changed |
479 | */ |
480 | void contextChanged(Plasma::Context *context); |
481 | |
482 | public Q_SLOTS: |
483 | /** |
484 | * Informs the Corona as to what position it is in. This is informational |
485 | * only, as the Corona doesn't change its actual location. This is, |
486 | * however, passed on to Applets that may be managed by this Corona. |
487 | * |
488 | * @param location the new location of this Corona |
489 | */ |
490 | void setLocation(Plasma::Location location); |
491 | |
492 | /** |
493 | * Sets the form factor for this Containment. This may cause changes in both |
494 | * the arrangement of Applets as well as the display choices of individual |
495 | * Applets. |
496 | */ |
497 | void setFormFactor(Plasma::FormFactor formFactor); |
498 | |
499 | /** |
500 | * Tells the corona to create a new desktop containment |
501 | */ |
502 | void addSiblingContainment(); |
503 | |
504 | /** |
505 | * switch keyboard focus to the next of our applets |
506 | */ |
507 | void focusNextApplet(); |
508 | |
509 | /** |
510 | * switch keyboard focus to the previous one of our applets |
511 | */ |
512 | void focusPreviousApplet(); |
513 | |
514 | /** |
515 | * Destroys this containment and all its applets (after a confirmation dialog); |
516 | * it will be removed nicely and deleted. |
517 | * Its configuration will also be deleted. |
518 | */ |
519 | void destroy(); |
520 | |
521 | /** |
522 | * Destroys this containment and all its applets (after a confirmation dialog); |
523 | * it will be removed nicely and deleted. |
524 | * Its configuration will also be deleted. |
525 | * |
526 | * @param confirm whether or not confirmation from the user should be requested |
527 | */ |
528 | void destroy(bool confirm); |
529 | |
530 | /** |
531 | * @reimp |
532 | * @sa Applet::showConfigurationInterface() |
533 | */ |
534 | void showConfigurationInterface(); |
535 | |
536 | /** |
537 | * Called when applet configuration values have changed. |
538 | * @reimp |
539 | * @sa Applet::configChanged() |
540 | */ |
541 | void configChanged(); |
542 | |
543 | protected: |
544 | //FIXME plasma2: those should be public to allow scripted containments access them |
545 | /** |
546 | * Sets the type of this containment. |
547 | */ |
548 | void setContainmentType(Containment::Type type); |
549 | |
550 | /** |
551 | * Sets whether wallpaper is painted or not. |
552 | */ |
553 | void setDrawWallpaper(bool drawWallpaper); |
554 | |
555 | /** |
556 | * Called when the contents of the containment should be saved. By default this saves |
557 | * all loaded Applets |
558 | * |
559 | * @param group the KConfigGroup to save settings under |
560 | */ |
561 | virtual void saveContents(KConfigGroup &group) const; |
562 | |
563 | /** |
564 | * Called when the contents of the containment should be loaded. By default this loads |
565 | * all previously saved Applets |
566 | * |
567 | * @param group the KConfigGroup to save settings under |
568 | */ |
569 | virtual void restoreContents(KConfigGroup &group); |
570 | |
571 | void mouseMoveEvent(QGraphicsSceneMouseEvent *event); |
572 | void mousePressEvent(QGraphicsSceneMouseEvent *event); |
573 | void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); |
574 | void (QGraphicsSceneContextMenuEvent *event); |
575 | void keyPressEvent(QKeyEvent *event); |
576 | void wheelEvent(QGraphicsSceneWheelEvent *event); |
577 | bool sceneEventFilter(QGraphicsItem *watched, QEvent *event); |
578 | QVariant itemChange(GraphicsItemChange change, const QVariant &value); |
579 | |
580 | /** |
581 | * @reimp |
582 | * @sa QGraphicsItem::dragEnterEvent() |
583 | */ |
584 | void dragEnterEvent(QGraphicsSceneDragDropEvent *event); |
585 | |
586 | /** |
587 | * @reimp |
588 | * @sa QGraphicsItem::dragLeaveEvent() |
589 | */ |
590 | void dragLeaveEvent(QGraphicsSceneDragDropEvent *event); |
591 | |
592 | /** |
593 | * @reimp |
594 | * @sa QGraphicsItem::dragMoveEvent() |
595 | */ |
596 | void dragMoveEvent(QGraphicsSceneDragDropEvent *event); |
597 | |
598 | /** |
599 | * @reimp |
600 | * @sa QGraphicsItem::dropEvent() |
601 | */ |
602 | void dropEvent(QGraphicsSceneDragDropEvent *event); |
603 | |
604 | /** |
605 | * @reimp |
606 | * @sa QGraphicsItem::resizeEvent() |
607 | */ |
608 | void resizeEvent(QGraphicsSceneResizeEvent *event); |
609 | |
610 | /** |
611 | * @returns the toolbox associated with this containment, or a null pointer if none |
612 | */ |
613 | #ifndef KDE_NO_DEPRECATED |
614 | KDE_DEPRECATED const QGraphicsItem *toolBoxItem() const; |
615 | #endif |
616 | |
617 | /** |
618 | * Sets a custom ToolBox |
619 | * if there was an old one it will be deleted |
620 | * and the new one won't have any actions in it |
621 | * |
622 | * @param item the new toolbox item |
623 | * @since 4.4 |
624 | */ |
625 | void setToolBox(AbstractToolBox *toolBox); |
626 | |
627 | /** |
628 | * @return the ToolBox |
629 | * @since 4.4 |
630 | */ |
631 | AbstractToolBox *toolBox() const; |
632 | |
633 | private: |
634 | /** |
635 | * @internal This constructor is to be used with the Package loading system. |
636 | * |
637 | * @param parent a QObject parent; you probably want to pass in 0 |
638 | * @param args a list of strings containing two entries: the service id |
639 | * and the applet id |
640 | * @since 4.3 |
641 | */ |
642 | Containment(const QString &packagePath, uint appletId, const QVariantList &args); |
643 | |
644 | Q_PRIVATE_SLOT(d, void appletDestroyed(Plasma::Applet*)) |
645 | Q_PRIVATE_SLOT(d, void appletAppearAnimationComplete()) |
646 | Q_PRIVATE_SLOT(d, void triggerShowAddWidgets()) |
647 | Q_PRIVATE_SLOT(d, void positionToolBox()) |
648 | Q_PRIVATE_SLOT(d, void requestConfiguration()) |
649 | Q_PRIVATE_SLOT(d, void updateToolBoxVisibility()) |
650 | Q_PRIVATE_SLOT(d, void showDropZoneDelayed()) |
651 | Q_PRIVATE_SLOT(d, void checkStatus(Plasma::ItemStatus)) |
652 | Q_PRIVATE_SLOT(d, void remoteAppletReady(Plasma::AccessAppletJob *)) |
653 | Q_PRIVATE_SLOT(d, void onContextChanged(Plasma::Context *con)) |
654 | /** |
655 | * This slot is called when the 'stat' after a job event has finished. |
656 | */ |
657 | Q_PRIVATE_SLOT(d, void mimeTypeRetrieved(KIO::Job *, const QString &)) |
658 | Q_PRIVATE_SLOT(d, void dropJobResult(KJob *)) |
659 | |
660 | friend class Applet; |
661 | friend class AppletPrivate; |
662 | friend class AppletScript; |
663 | friend class CoronaPrivate; |
664 | friend class ContainmentPrivate; |
665 | friend class ContainmentActions; |
666 | friend class PopupApplet; |
667 | friend class View; |
668 | ContainmentPrivate *const d; |
669 | }; |
670 | |
671 | } // Plasma namespace |
672 | |
673 | #endif // multiple inclusion guard |
674 | |