24 #include "private/corona_p.h" 26 #include <QApplication> 27 #include <QDesktopWidget> 28 #include <QGraphicsView> 29 #include <QGraphicsSceneDragDropEvent> 30 #include <QGraphicsGridLayout> 38 #include <kauthorized.h> 42 #include <kmimetype.h> 43 #include <kshortcutsdialog.h> 44 #include <kwindowsystem.h> 51 #include "private/animator_p.h" 52 #include "private/applet_p.h" 53 #include "private/containment_p.h" 62 bool CoronaPrivate::s_positioningContainments =
false;
66 d(new CoronaPrivate(this))
68 kDebug() <<
"!!{} STARTUP TIME" << QTime().msecsTo(QTime::currentTime()) <<
"Corona ctor start";
76 KConfigGroup trans(KGlobal::config(),
"PlasmaTransientsConfig");
102 d->defaultContainmentPlugin = name;
107 return d->defaultContainmentPlugin;
114 if (configName.isEmpty() || configName == d->configName) {
117 c = KSharedConfig::openConfig(configName, KConfig::SimpleConfig);
125 foreach (
const QString &group,
config.groupList()) {
126 KConfigGroup cg(&
config, group);
134 KConfigGroup dest(&
config,
"Containments");
138 c->
config().reparent(&dest);
151 d->immutability = oldImm;
160 static const int CONFIG_SYNC_TIMEOUT = 10000;
169 if (!d->configSyncTimer.isActive()) {
170 d->configSyncTimer.start(CONFIG_SYNC_TIMEOUT);
184 if (d->containments.isEmpty()) {
186 if (!d->containments.isEmpty()) {
191 if (
config()->isImmutable() ||
192 !KAuthorized::authorize(
"plasma/" + KGlobal::mainComponent().aboutData()->appName() +
193 "/unlockedDesktop")) {
196 KConfigGroup coronaConfig(
config(),
"General");
203 return c1->
id() < c2->
id();
208 if (CoronaPrivate::s_positioningContainments) {
212 CoronaPrivate::s_positioningContainments =
true;
217 QMutableListIterator<Containment*> it(c);
219 while (it.hasNext()) {
234 CoronaPrivate::s_positioningContainments =
false;
244 while (it.hasNext()) {
246 containment->setPos(x, y);
249 int height = containment->size().height();
250 if (height > rowHeight) {
256 if (column == CONTAINMENT_COLUMNS) {
259 y += rowHeight + INTER_CONTAINMENT_MARGIN + TOOLBOX_MARGIN;
262 x += containment->size().width() + INTER_CONTAINMENT_MARGIN;
268 CoronaPrivate::s_positioningContainments =
false;
274 if (!configName.isEmpty() && configName != d->configName) {
277 d->configName = configName;
280 KSharedConfigPtr conf =
config();
281 d->importLayout(*conf,
false);
286 return d->importLayout(conf,
true);
289 #ifndef KDE_NO_DEPRECATED 292 return d->importLayout(conf,
true);
298 foreach (
Containment *containment, d->containments) {
299 if (containment->
screen() == screen &&
300 (desktop < 0 || containment->
desktop() == desktop) &&
311 const QString &defaultPluginIfNonExistent,
const QVariantList &defaultArgs)
314 if (!containment && !defaultPluginIfNonExistent.isEmpty()) {
317 desktop >= -1 && desktop < KWindowSystem::numberOfDesktops()) {
318 containment = d->addContainment(defaultPluginIfNonExistent, defaultArgs, 0,
false);
330 return d->containments;
335 foreach (
Containment *containment, d->containments) {
343 d->config = KSharedConfig::openConfig(d->configName, KConfig::SimpleConfig);
351 if (d->immutability ==
Mutable) {
352 return d->addContainment(name, args, 0,
false);
360 if (d->immutability ==
Mutable) {
361 return d->addContainment(name, args, 0,
true);
369 AnimatorPrivate::mapAnimation(from, to);
374 AnimatorPrivate::mapAnimation(from, to);
381 kDebug() <<
"widget is already an offscreen widget!";
389 while (d->offscreenWidgets.contains(i)) {
393 d->offscreenWidgets[i] = widget;
394 #if defined(arm) || defined(__arm__) 395 widget->setPos((-i - 1) * 2000, -2000);
397 widget->setPos((-i - 1) * QWIDGETSIZE_MAX, -QWIDGETSIZE_MAX);
401 widget->setParentItem(0);
403 widget->setParent(pw);
407 if (!widget->scene()) {
411 connect(widget, SIGNAL(destroyed(
QObject*)),
this, SLOT(offscreenWidgetDestroyed(
QObject*)));
416 QMutableHashIterator<uint, QGraphicsWidget *> it(d->offscreenWidgets);
418 while (it.hasNext()) {
419 if (it.next().value() == widget) {
428 return d->offscreenWidgets.values();
431 void CoronaPrivate::offscreenWidgetDestroyed(
QObject *o)
437 q->removeOffscreenWidget(widget);
450 QRect r = sceneRect().toRect();
451 r.moveTo(v->mapToGlobal(QPoint(0, 0)));
455 return sceneRect().toRect();
473 const QGraphicsItem *actualItem = item;
483 if (!v->isVisible()) {
484 actualItem = item->parentItem();
488 actualItem = qobject_cast<QGraphicsItem*>(widget->parent());
507 QTransform sceneTransform = actualItem->sceneTransform();
510 if (QApplication::isRightToLeft() && alignment != Qt::AlignCenter) {
511 if (alignment == Qt::AlignRight) {
512 alignment = Qt::AlignLeft;
514 alignment = Qt::AlignRight;
519 if (sceneTransform.isRotating()) {
520 qreal angle = acos(sceneTransform.m11());
521 QTransform newTransform;
522 QPointF center = actualItem->sceneBoundingRect().center();
524 newTransform.translate(center.x(), center.y());
525 newTransform.rotateRadians(-angle);
526 newTransform.translate(-center.x(), -center.y());
527 pos = v->mapFromScene(newTransform.inverted().map(actualItem->scenePos()));
529 pos = v->mapFromScene(actualItem->scenePos());
532 pos = v->mapToGlobal(pos);
544 if (alignment == Qt::AlignCenter) {
545 pos.setX(pos.x() + actualItem->boundingRect().width()/2 - s.width()/2);
546 }
else if (alignment == Qt::AlignRight) {
547 pos.setX(pos.x() + actualItem->boundingRect().width() - s.width());
550 if (pos.x() + s.width() > v->geometry().x() + v->geometry().width()) {
551 pos.setX((v->geometry().x() + v->geometry().width()) - s.width());
553 pos.setX(qMax(pos.x(), v->geometry().left()));
559 if (alignment == Qt::AlignCenter) {
560 pos.setY(pos.y() + actualItem->boundingRect().height()/2 - s.height()/2);
561 }
else if (alignment == Qt::AlignRight) {
562 pos.setY(pos.y() + actualItem->boundingRect().height() - s.height());
565 if (pos.y() + s.height() > v->geometry().y() + v->geometry().height()) {
566 pos.setY((v->geometry().y() + v->geometry().height()) - s.height());
568 pos.setY(qMax(pos.y(), v->geometry().top()));
573 if (alignment == Qt::AlignCenter) {
574 pos.setX(pos.x() + actualItem->boundingRect().width()/2 - s.width()/2);
575 }
else if (alignment == Qt::AlignRight) {
576 pos.setX(pos.x() + actualItem->boundingRect().width() - s.width());
590 screen = QApplication::desktop()->screenNumber(v);
598 pos.setY(v->geometry().y() - s.height());
601 pos.setY(v->geometry().y() + v->geometry().height());
604 pos.setX(v->geometry().x() + v->geometry().width());
607 pos.setX(v->geometry().x() - s.width());
610 if (pos.y() - s.height() > screenRect.top()) {
611 pos.ry() = pos.y() - s.height();
613 pos.ry() = pos.y() + (int)actualItem->boundingRect().size().height() + 1;
619 if (loc !=
LeftEdge && pos.x() + s.width() > screenRect.x() + screenRect.width()) {
620 pos.rx() -= ((pos.x() + s.width()) - (screenRect.x() + screenRect.width()));
623 if (loc !=
TopEdge && pos.y() + s.height() > screenRect.y() + screenRect.height()) {
624 pos.ry() -= ((pos.y() + s.height()) - (screenRect.y() + screenRect.height()));
627 pos.rx() = qMax(0, pos.x());
628 pos.ry() = qMax(0, pos.y());
638 d->toolBoxPlugins[
type] = plugin;
644 return d->toolBoxPlugins.value(
type);
649 QGraphicsScene::dragEnterEvent(event);
654 QGraphicsScene::dragLeaveEvent(event);
659 QGraphicsScene::dragMoveEvent(event);
664 return d->immutability;
669 if (d->immutability == immutable || d->immutability ==
SystemImmutable) {
673 kDebug() <<
"setting immutability to" << immutable;
674 d->immutability = immutable;
675 d->updateContainmentImmutability();
680 QAction *
action = d->actions.action(
"lock widgets");
683 action->setEnabled(
false);
684 action->setVisible(
false);
686 bool unlocked = d->immutability ==
Mutable;
687 action->setText(unlocked ? i18n(
"Lock Widgets") : i18n(
"Unlock Widgets"));
688 action->setIcon(KIcon(unlocked ?
"object-locked" :
"object-unlocked"));
695 KConfigGroup cg(
config(),
"General");
699 cg.writeEntry(
"immutability", (
int)d->immutability);
711 if (containment->
screen() == screen &&
722 return d->actions.action(name);
727 d->actions.addAction(name,
action);
732 return d->actions.addAction(name);
737 return d->actions.actions();
742 QAction *
action = d->actions.action(name);
744 action->setEnabled(enable);
745 action->setVisible(enable);
751 QMutableListIterator<QWeakPointer<KActionCollection> > it(d->actionCollections);
752 while (it.hasNext()) {
754 KActionCollection *collection = it.value().data();
761 collection->readSettings();
762 if (d->shortcutsDlg) {
763 d->shortcutsDlg.data()->addCollection(collection);
770 d->actionCollections << newShortcuts;
771 if (d->shortcutsDlg) {
772 d->shortcutsDlg.data()->addCollection(newShortcuts);
778 d->containmentActionsDefaults.insert(containmentType,
config);
783 return d->containmentActionsDefaults.value(containmentType);
793 return d->dialogManager.data();
796 CoronaPrivate::CoronaPrivate(
Corona *corona)
799 mimetype(
"text/x-plasmoidservicename"),
800 defaultContainmentPlugin(
"desktop"),
804 if (KGlobal::hasMainComponent()) {
805 configName = KGlobal::mainComponent().componentName() +
"-appletsrc";
807 configName =
"plasma-appletsrc";
811 CoronaPrivate::~CoronaPrivate()
813 qDeleteAll(containments);
816 void CoronaPrivate::init()
818 q->setStickyFocus(
true);
819 configSyncTimer.setSingleShot(
true);
820 QObject::connect(&configSyncTimer, SIGNAL(timeout()), q, SLOT(syncConfig()));
823 actions.setConfigGroup(
"Shortcuts");
825 KAction *lockAction = actions.addAction(
"lock widgets");
826 QObject::connect(lockAction, SIGNAL(triggered(
bool)), q, SLOT(toggleImmutability()));
827 lockAction->setText(i18n(
"Lock Widgets"));
828 lockAction->setAutoRepeat(
true);
829 lockAction->setIcon(KIcon(
"object-locked"));
831 lockAction->setShortcut(KShortcut(
"alt+d, l"));
832 lockAction->setShortcutContext(Qt::ApplicationShortcut);
837 KAction *action = actions.addAction(
"configure shortcuts");
838 QObject::connect(action, SIGNAL(triggered()), q, SLOT(showShortcutConfig()));
839 action->setText(i18n(
"Shortcut Settings"));
840 action->setIcon(KIcon(
"configure-shortcuts"));
841 action->setAutoRepeat(
false);
844 action->setShortcutContext(Qt::ApplicationShortcut);
847 KActionCollection *containmentActions = AppletPrivate::defaultActions(q);
848 ContainmentPrivate::addDefaultActions(containmentActions);
849 actionCollections << &actions << AppletPrivate::defaultActions(q) << containmentActions;
850 q->updateShortcuts();
853 void CoronaPrivate::showShortcutConfig()
856 KShortcutsDialog *dlg = shortcutsDlg.data();
858 dlg =
new KShortcutsDialog();
859 dlg->setModal(
false);
860 dlg->setAttribute(Qt::WA_DeleteOnClose,
true);
861 QObject::connect(dlg, SIGNAL(saved()), q, SIGNAL(shortcutsChanged()));
863 dlg->addCollection(&actions);
864 QMutableListIterator<QWeakPointer<KActionCollection> > it(actionCollections);
865 while (it.hasNext()) {
867 KActionCollection *collection = it.value().data();
874 dlg->addCollection(collection);
878 KWindowSystem::setOnDesktop(dlg->winId(), KWindowSystem::currentDesktop());
883 void CoronaPrivate::toggleImmutability()
892 void CoronaPrivate::saveLayout(KSharedConfigPtr cg)
const 894 KConfigGroup containmentsGroup(cg,
"Containments");
895 foreach (
const Containment *containment, containments) {
896 QString cid = QString::number(containment->
id());
897 KConfigGroup containmentConfig(&containmentsGroup, cid);
898 containment->
save(containmentConfig);
902 void CoronaPrivate::updateContainmentImmutability()
910 void CoronaPrivate::containmentDestroyed(
QObject *obj)
917 int index = containments.indexOf(containment);
920 containments.removeAt(index);
921 q->requestConfigSync();
925 void CoronaPrivate::syncConfig()
928 emit q->configSynced();
931 Containment *CoronaPrivate::addContainment(
const QString &name,
const QVariantList &args, uint
id,
bool delayedInit)
933 QString pluginName = name;
939 if (pluginName.isEmpty() || pluginName ==
"default") {
941 pluginName = defaultContainmentPlugin;
944 bool loadingNull = pluginName ==
"null";
952 kDebug() <<
"loading of containment" << name <<
"failed.";
962 q->removeItem(applet);
980 KConfigGroup conf(q->config(),
"Containments");
981 conf = KConfigGroup(&conf, QString::number(containment->
id()));
985 applet->d->isContainment =
true;
986 containment->setPos(containment->d->preferredPos(q));
987 q->addItem(containment);
988 applet->d->setIsContainment(
true,
true);
989 containments.append(containment);
993 KConfigGroup cg = containment->
config();
996 containment->
save(cg);
997 q->requestConfigSync();
1001 QObject::connect(containment, SIGNAL(destroyed(
QObject*)),
1002 q, SLOT(containmentDestroyed(
QObject*)));
1003 QObject::connect(containment, SIGNAL(configNeedsSaving()),
1004 q, SLOT(requestConfigSync()));
1005 QObject::connect(containment, SIGNAL(releaseVisualFocus()),
1006 q, SIGNAL(releaseVisualFocus()));
1011 emit q->containmentAdded(containment);
1017 QList<Plasma::Containment *> CoronaPrivate::importLayout(
const KConfigBase &conf,
bool mergeConfig)
1019 if (
const KConfigGroup *group = dynamic_cast<const KConfigGroup *>(&conf)) {
1020 if (!group->isValid()) {
1021 return QList<Containment *>();
1025 QList<Plasma::Containment *> newContainments;
1026 QSet<uint> containmentsIds;
1028 foreach (
Containment *containment, containments) {
1029 containmentsIds.insert(containment->
id());
1032 KConfigGroup containmentsGroup(&conf,
"Containments");
1034 foreach (
const QString &group, containmentsGroup.groupList()) {
1035 KConfigGroup containmentConfig(&containmentsGroup, group);
1037 if (containmentConfig.entryMap().isEmpty()) {
1041 uint cid = group.toUInt();
1042 if (containmentsIds.contains(cid)) {
1043 cid = ++AppletPrivate::s_maxAppletId;
1044 }
else if (cid > AppletPrivate::s_maxAppletId) {
1045 AppletPrivate::s_maxAppletId = cid;
1049 KConfigGroup realConf(q->config(),
"Containments");
1050 realConf = KConfigGroup(&realConf, QString::number(cid));
1052 realConf.deleteGroup();
1053 containmentConfig.copyTo(&realConf);
1057 kDebug() <<
"!!{} STARTUP TIME" << QTime().msecsTo(QTime::currentTime()) <<
"Adding Containment" << containmentConfig.readEntry(
"plugin", QString());
1058 Containment *c = addContainment(containmentConfig.readEntry(
"plugin", QString()), QVariantList(), cid,
true);
1063 newContainments.append(c);
1064 containmentsIds.insert(c->
id());
1067 kDebug() <<
"!!{} STARTUP TIME" << QTime().msecsTo(QTime::currentTime()) <<
"Init Containment" << c->
pluginName();
1068 c->
restore(containmentConfig);
1069 kDebug() <<
"!!{} STARTUP TIME" << QTime().msecsTo(QTime::currentTime()) <<
"Restored Containment" << c->
pluginName();
1072 foreach (
Containment *containment, newContainments) {
1074 containment->d->initApplets();
1075 emit q->containmentAdded(containment);
1076 kDebug() <<
"!!{} STARTUP TIME" << QTime().msecsTo(QTime::currentTime()) <<
"Containment" << containment->
name();
1079 return newContainments;
1084 #include "corona.moc" ImmutabilityType immutability
void immutabilityChanged(Plasma::ImmutabilityType immutability)
emitted when immutability changes.
application startup has completed
void loadLayout(const QString &config=QString())
Load applet layout from a config file.
void flushPendingConstraintsEvents()
Sends all pending contraints updates to the applet.
ImmutabilityType
Defines the immutability of items like applets, corona and containments they can be free to modify...
void destroy()
Destroys this containment and all its applets (after a confirmation dialog); it will be removed nicel...
void addAction(QString name, QAction *action)
Adds the action to our collection under the given name.
void setDrawWallpaper(bool drawWallpaper)
Sets whether wallpaper is painted or not.
Type containmentType() const
Returns the type of containment.
void setFormFactor(Plasma::FormFactor formFactor)
Sets the form factor for this Containment.
the item is locked down by the system, the user can't unlock it
QList< Plasma::Containment * > importLayout(const KConfigBase &config)
Imports an applet layout from a config file.
void setContainmentActionsDefaults(Containment::Type containmentType, const ContainmentActionsPluginsConfig &config)
void setImmutability(const ImmutabilityType immutable)
Sets the immutability type for this Corona (not immutable, user immutable or system immutable) ...
Containment * containment() const
void requireConfigSync()
Schedules a time sensitive flush-to-disk synchronization of the configuration state.
QString defaultContainmentPlugin() const
int screen() const
Returns the screen this view is associated with.
void enableAction(const QString &name, bool enable)
convenience function - enables or disables an action by name
ContainmentActionsPluginsConfig containmentActionsDefaults(Containment::Type containmentType)
QList< Plasma::Location > freeEdges(int screen) const
This method is useful in order to retrieve the list of available screen edges for panel type containm...
the immutability (locked) nature of the applet changed
void addShortcuts(KActionCollection *newShortcuts)
void setPreferredToolBoxPlugin(const Containment::Type type, const QString &plugin)
Namespace for everything in libplasma.
The item can be modified in any way.
A containment that is neither a desktop nor a panel but something application specific.
virtual void loadDefaultLayout()
Loads the default (system wide) layout for this user.
void initializeLayout(const QString &config=QString())
Initializes the layout from a config file.
QPoint popupPosition(const QGraphicsItem *item, const QSize &size)
Recommended position for a popup window like a menu or a tooltip given its size.
void setScreen(int screen, int desktop=-1)
Sets the physical screen this Containment is associated with.
A QGraphicsView for a single Containment.
Location
The Location enumeration describes where on screen an element, such as an Applet or its managing cont...
void requestConfigSync()
Schedules a flush-to-disk synchronization of the configuration state at the next convenient moment...
Corona(QObject *parent=0)
void setDialogManager(AbstractDialogManager *manager)
void clearContainments()
Clear the Corona from all applets.
void mapAnimation(Animator::Animation from, Animator::Animation to)
Maps a stock animation to one of the semantic animations.
Applet::List applets() const
The user has requested a lock down, and can undo the lock down at any time.
QAction * action(QString name) const
Returns the QAction with the given name from our collection.
AbstractDialogManager * dialogManager()
QString preferredToolBoxPlugin(const Containment::Type type) const
Returns the name of the preferred plugin to be used as containment toolboxes.
KSharedConfig::Ptr config() const
Returns the config file used to store the configuration for this Corona.
void restore(KConfigGroup &group)
void dragLeaveEvent(QGraphicsSceneDragDropEvent *event)
void init()
Reimplemented from Applet.
Along the top of the screen.
void layoutContainments()
bool containmentSortByPosition(const Containment *c1, const Containment *c2)
Containment * containmentForScreen(int screen, int desktop=-1) const
Returns the Containment, if any, for a given physical screen and desktop.
QList< Containment * > containments() const
virtual Location location() const
Returns the location of the scene which is displaying applet.
void saveLayout(const QString &config=QString()) const
Save applets layout to file.
QList< QGraphicsWidget * > offscreenWidgets() const
void clearApplets()
Removes all applets from this Containment.
void setFailedToLaunch(bool failed, const QString &reason=QString())
Call this method when the applet fails to launch properly.
A customized desktop panel.
Along the bottom of the screen.
KConfigGroup config() const
Returns the KConfigGroup to access the applets configuration.
void exportLayout(KConfigGroup &config, QList< Containment *> containments)
Exports a set of containments to a config file.
The applet lives in a plane and has two degrees of freedom to grow.
ImmutabilityType immutability() const
void save(KConfigGroup &group) const
void setDefaultContainmentPlugin(const QString &name)
Sets the default containment plugin to try and load.
Containment * addContainmentDelayed(const QString &name, const QVariantList &args=QVariantList())
Loads a containment with delayed initialization, primarily useful for implementations of loadDefaultL...
static QScriptValue type(QScriptContext *ctx, QScriptEngine *eng)
QList< QAction * > actions() const
Returns all the actions in our collection.
void updateConstraints(Plasma::Constraints constraints=Plasma::AllConstraints)
Called when any of the geometry constraints have been updated.
The AbstractDialogManager class shows the dialogs shown by applets and the rest of the shell...
Containment * addContainment(const QString &name, const QVariantList &args=QVariantList())
Adds a Containment to the Corona.
virtual QRect screenGeometry(int id) const
Returns the geometry of a given screen.
The base class for plugins that provide backgrounds and applet grouping containers.
Along the right side of the screen.
void setAppletMimeType(const QString &mimetype)
Sets the mimetype of Drag/Drop items.
virtual int numScreens() const
Returns the number of screens available to plasma.
void addOffscreenWidget(QGraphicsWidget *widget)
Adds a widget in the topleft quadrant in the scene.
virtual void init()
This method is called once the applet is loaded and added to a Corona.
void dragMoveEvent(QGraphicsSceneDragDropEvent *event)
QString appletMimeType()
The current mime type of Drag/Drop items.
void dragEnterEvent(QGraphicsSceneDragDropEvent *event)
void removeOffscreenWidget(QGraphicsWidget *widget)
Removes a widget from the topleft quadrant in the scene.
Along the left side of the screen.
A class that holds a map of triggers to plugin names.
virtual QRegion availableScreenRegion(int id) const
Returns the available region for a given screen.
QGraphicsView * viewFor(const QGraphicsItem *item)
Returns the most appropriate QGraphicsView for the item.
A QGraphicsScene for Plasma::Applets.
static Applet * load(const QString &name, uint appletId=0, const QVariantList &args=QVariantList())
Attempts to load an applet.