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
37namespace Plasma
38{
39
40class AccessAppletJob;
41class AppletHandle;
42class DataEngine;
43class Package;
44class Corona;
45class View;
46class Wallpaper;
47class ContainmentActions;
48class ContainmentPrivate;
49class 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 */
72class 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 showContextMenu(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
419Q_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 contextMenuEvent(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