Plasma
containmentactions.cpp
Go to the documentation of this file.
00001 /* 00002 * Copyright (c) 2009 Chani Armitage <chani@kde.org> 00003 * 00004 * This program is free software; you can redistribute it and/or modify 00005 * it under the terms of the GNU Library General Public License as 00006 * published by the Free Software Foundation; either version 2, or 00007 * (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details 00013 * 00014 * You should have received a copy of the GNU Library General Public 00015 * License along with this program; if not, write to the 00016 * Free Software Foundation, Inc., 00017 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00018 */ 00019 00020 #include "containmentactions.h" 00021 #include "containment.h" 00022 00023 #include "private/dataengineconsumer_p.h" 00024 #include "private/packages_p.h" 00025 #include "private/containmentactions_p.h" 00026 #include "private/containment_p.h" 00027 00028 #include <QMetaEnum> 00029 #include <QMouseEvent> 00030 #include <QWheelEvent> 00031 #include <QGraphicsSceneContextMenuEvent> 00032 #include <QGraphicsSceneMouseEvent> 00033 #include <QGraphicsSceneWheelEvent> 00034 00035 #include <kdebug.h> 00036 #include <kglobal.h> 00037 #include <kservicetypetrader.h> 00038 #include <kstandarddirs.h> 00039 00040 #include <version.h> 00041 00042 namespace Plasma 00043 { 00044 00045 PackageStructure::Ptr ContainmentActionsPrivate::s_packageStructure(0); 00046 00047 ContainmentActions::ContainmentActions(QObject * parentObject) 00048 : d(new ContainmentActionsPrivate(KService::serviceByStorageId(QString()), this)) 00049 { 00050 setParent(parentObject); 00051 } 00052 00053 ContainmentActions::ContainmentActions(QObject *parentObject, const QVariantList &args) 00054 : d(new ContainmentActionsPrivate(KService::serviceByStorageId(args.count() > 0 ? 00055 args[0].toString() : QString()), this)) 00056 { 00057 // now remove first item since those are managed by Wallpaper and subclasses shouldn't 00058 // need to worry about them. yes, it violates the constness of this var, but it lets us add 00059 // or remove items later while applets can just pretend that their args always start at 0 00060 QVariantList &mutableArgs = const_cast<QVariantList &>(args); 00061 if (!mutableArgs.isEmpty()) { 00062 mutableArgs.removeFirst(); 00063 } 00064 00065 setParent(parentObject); 00066 } 00067 00068 ContainmentActions::~ContainmentActions() 00069 { 00070 delete d; 00071 } 00072 00073 KPluginInfo::List ContainmentActions::listContainmentActionsInfo() 00074 { 00075 QString constraint; 00076 00077 KService::List offers = KServiceTypeTrader::self()->query("Plasma/ContainmentActions", constraint); 00078 return KPluginInfo::fromServices(offers); 00079 } 00080 00081 ContainmentActions *ContainmentActions::load(Containment *parent, const QString &containmentActionsName, const QVariantList &args) 00082 { 00083 if (containmentActionsName.isEmpty()) { 00084 return 0; 00085 } 00086 00087 QString constraint = QString("[X-KDE-PluginInfo-Name] == '%1'").arg(containmentActionsName); 00088 KService::List offers = KServiceTypeTrader::self()->query("Plasma/ContainmentActions", constraint); 00089 00090 if (offers.isEmpty()) { 00091 kDebug() << "offers is empty for " << containmentActionsName; 00092 return 0; 00093 } 00094 00095 KService::Ptr offer = offers.first(); 00096 KPluginLoader plugin(*offer); 00097 00098 if (!Plasma::isPluginVersionCompatible(plugin.pluginVersion())) { 00099 return 0; 00100 } 00101 00102 QVariantList allArgs; 00103 allArgs << offer->storageId() << args; 00104 QString error; 00105 ContainmentActions *containmentActions = offer->createInstance<Plasma::ContainmentActions>(parent, allArgs, &error); 00106 00107 if (!containmentActions) { 00108 kDebug() << "Couldn't load containmentActions \"" << containmentActionsName << "\"! reason given: " << error; 00109 } 00110 00111 return containmentActions; 00112 } 00113 00114 ContainmentActions *ContainmentActions::load(Containment *parent, const KPluginInfo &info, const QVariantList &args) 00115 { 00116 if (!info.isValid()) { 00117 return 0; 00118 } 00119 return load(parent, info.pluginName(), args); 00120 } 00121 00122 PackageStructure::Ptr ContainmentActions::packageStructure() 00123 { 00124 if (!ContainmentActionsPrivate::s_packageStructure) { 00125 ContainmentActionsPrivate::s_packageStructure = new ContainmentActionsPackage(); 00126 } 00127 00128 return ContainmentActionsPrivate::s_packageStructure; 00129 } 00130 00131 Containment *ContainmentActions::containment() 00132 { 00133 if (d->containment) { 00134 return d->containment; 00135 } 00136 return qobject_cast<Containment*>(parent()); 00137 } 00138 00139 QString ContainmentActions::name() const 00140 { 00141 if (!d->containmentActionsDescription.isValid()) { 00142 return i18n("Unknown ContainmentActions"); 00143 } 00144 00145 return d->containmentActionsDescription.name(); 00146 } 00147 00148 QString ContainmentActions::icon() const 00149 { 00150 if (!d->containmentActionsDescription.isValid()) { 00151 return QString(); 00152 } 00153 00154 return d->containmentActionsDescription.icon(); 00155 } 00156 00157 QString ContainmentActions::pluginName() const 00158 { 00159 if (!d->containmentActionsDescription.isValid()) { 00160 return QString(); 00161 } 00162 00163 return d->containmentActionsDescription.pluginName(); 00164 } 00165 00166 bool ContainmentActions::isInitialized() const 00167 { 00168 return d->initialized; 00169 } 00170 00171 void ContainmentActions::restore(const KConfigGroup &config) 00172 { 00173 init(config); 00174 d->initialized = true; 00175 } 00176 00177 void ContainmentActions::init(const KConfigGroup &config) 00178 { 00179 Q_UNUSED(config); 00180 } 00181 00182 void ContainmentActions::save(KConfigGroup &config) 00183 { 00184 Q_UNUSED(config); 00185 } 00186 00187 QWidget *ContainmentActions::createConfigurationInterface(QWidget *parent) 00188 { 00189 Q_UNUSED(parent); 00190 return 0; 00191 } 00192 00193 void ContainmentActions::configurationAccepted() 00194 { 00195 //do nothing by default 00196 } 00197 00198 void ContainmentActions::contextEvent(QEvent *event) 00199 { 00200 Q_UNUSED(event) 00201 } 00202 00203 QList<QAction*> ContainmentActions::contextualActions() 00204 { 00205 //empty list 00206 return QList<QAction*>(); 00207 } 00208 00209 DataEngine *ContainmentActions::dataEngine(const QString &name) const 00210 { 00211 return d->dataEngine(name); 00212 } 00213 00214 bool ContainmentActions::configurationRequired() const 00215 { 00216 return d->needsConfig; 00217 } 00218 00219 void ContainmentActions::setConfigurationRequired(bool needsConfig) 00220 { 00221 //TODO: reason? 00222 d->needsConfig = needsConfig; 00223 } 00224 00225 QString ContainmentActions::eventToString(QEvent *event) 00226 { 00227 QString trigger; 00228 Qt::KeyboardModifiers modifiers; 00229 00230 switch (event->type()) { 00231 case QEvent::MouseButtonPress: 00232 case QEvent::MouseButtonRelease: 00233 { 00234 QMouseEvent *e = static_cast<QMouseEvent*>(event); 00235 int m = QObject::staticQtMetaObject.indexOfEnumerator("MouseButtons"); 00236 QMetaEnum mouse = QObject::staticQtMetaObject.enumerator(m); 00237 trigger += mouse.valueToKey(e->button()); 00238 modifiers = e->modifiers(); 00239 break; 00240 } 00241 case QEvent::GraphicsSceneMousePress: 00242 case QEvent::GraphicsSceneMouseRelease: 00243 case QEvent::GraphicsSceneMouseDoubleClick: 00244 { 00245 QGraphicsSceneMouseEvent *e = static_cast<QGraphicsSceneMouseEvent*>(event); 00246 int m = QObject::staticQtMetaObject.indexOfEnumerator("MouseButtons"); 00247 QMetaEnum mouse = QObject::staticQtMetaObject.enumerator(m); 00248 trigger += mouse.valueToKey(e->button()); 00249 modifiers = e->modifiers(); 00250 break; 00251 } 00252 case QEvent::Wheel: 00253 { 00254 QWheelEvent *e = static_cast<QWheelEvent*>(event); 00255 int o = QObject::staticQtMetaObject.indexOfEnumerator("Orientations"); 00256 QMetaEnum orient = QObject::staticQtMetaObject.enumerator(o); 00257 trigger = "wheel:"; 00258 trigger += orient.valueToKey(e->orientation()); 00259 modifiers = e->modifiers(); 00260 break; 00261 } 00262 case QEvent::GraphicsSceneWheel: 00263 { 00264 QGraphicsSceneWheelEvent *e = static_cast<QGraphicsSceneWheelEvent*>(event); 00265 int o = QObject::staticQtMetaObject.indexOfEnumerator("Orientations"); 00266 QMetaEnum orient = QObject::staticQtMetaObject.enumerator(o); 00267 trigger = "wheel:"; 00268 trigger += orient.valueToKey(e->orientation()); 00269 modifiers = e->modifiers(); 00270 break; 00271 } 00272 case QEvent::GraphicsSceneContextMenu: 00273 case QEvent::ContextMenu: 00274 { 00275 int m = QObject::staticQtMetaObject.indexOfEnumerator("MouseButtons"); 00276 QMetaEnum mouse = QObject::staticQtMetaObject.enumerator(m); 00277 trigger = mouse.valueToKey(Qt::RightButton); 00278 modifiers = Qt::NoModifier; 00279 break; 00280 } 00281 default: 00282 return QString(); 00283 } 00284 00285 int k = QObject::staticQtMetaObject.indexOfEnumerator("KeyboardModifiers"); 00286 QMetaEnum kbd = QObject::staticQtMetaObject.enumerator(k); 00287 trigger += ';'; 00288 trigger += kbd.valueToKeys(modifiers); 00289 00290 return trigger; 00291 } 00292 00293 void ContainmentActions::paste(QPointF scenePos, QPoint screenPos) 00294 { 00295 Containment *c = containment(); 00296 if (c) { 00297 c->d->dropData(scenePos, screenPos); 00298 } 00299 } 00300 00301 QPoint screenPosFromEvent(QEvent *event) 00302 { 00303 switch (event->type()) { 00304 case QEvent::GraphicsSceneMousePress: 00305 case QEvent::GraphicsSceneMouseRelease: 00306 case QEvent::GraphicsSceneMouseDoubleClick: 00307 return static_cast<QGraphicsSceneMouseEvent*>(event)->screenPos(); 00308 break; 00309 case QEvent::GraphicsSceneWheel: 00310 return static_cast<QGraphicsSceneWheelEvent*>(event)->screenPos(); 00311 break; 00312 case QEvent::GraphicsSceneContextMenu: 00313 return static_cast<QGraphicsSceneContextMenuEvent*>(event)->screenPos(); 00314 break; 00315 default: 00316 break; 00317 } 00318 00319 return QPoint(); 00320 } 00321 00322 QPointF scenePosFromEvent(QEvent *event) 00323 { 00324 switch (event->type()) { 00325 case QEvent::GraphicsSceneMousePress: 00326 case QEvent::GraphicsSceneMouseRelease: 00327 case QEvent::GraphicsSceneMouseDoubleClick: 00328 return static_cast<QGraphicsSceneMouseEvent*>(event)->scenePos(); 00329 break; 00330 case QEvent::GraphicsSceneWheel: 00331 return static_cast<QGraphicsSceneWheelEvent*>(event)->scenePos(); 00332 break; 00333 case QEvent::GraphicsSceneContextMenu: 00334 return static_cast<QGraphicsSceneContextMenuEvent*>(event)->scenePos(); 00335 break; 00336 default: 00337 break; 00338 } 00339 00340 return QPoint(); 00341 } 00342 00343 bool isNonSceneEvent(QEvent *event) 00344 { 00345 return dynamic_cast<QGraphicsSceneEvent *>(event) == 0; 00346 } 00347 00348 QPoint ContainmentActions::popupPosition(const QSize &s, QEvent *event) 00349 { 00350 if (isNonSceneEvent(event)) { 00351 return screenPosFromEvent(event); 00352 } 00353 00354 Containment *c = containment(); 00355 if (!c) { 00356 return screenPosFromEvent(event); 00357 } 00358 00359 Applet *applet = c->d->appletAt(scenePosFromEvent(event)); 00360 QPoint screenPos = screenPosFromEvent(event); 00361 QPoint pos = screenPos; 00362 if (applet && containment()->d->isPanelContainment()) { 00363 pos = applet->popupPosition(s); 00364 if (event->type() != QEvent::GraphicsSceneContextMenu || 00365 static_cast<QGraphicsSceneContextMenuEvent *>(event)->reason() == QGraphicsSceneContextMenuEvent::Mouse) { 00366 // if the menu pops up way away from the mouse press, then move it 00367 // to the mouse press 00368 if (c->formFactor() == Vertical) { 00369 if (pos.y() + s.height() < screenPos.y()) { 00370 pos.setY(screenPos.y()); 00371 } 00372 } else if (c->formFactor() == Horizontal) { 00373 if (pos.x() + s.width() < screenPos.x()) { 00374 pos.setX(screenPos.x()); 00375 } 00376 } 00377 } 00378 } 00379 00380 return pos; 00381 } 00382 00383 bool ContainmentActions::event(QEvent *) 00384 { 00385 //no longer needed 00386 return false; 00387 } 00388 00389 void ContainmentActions::setContainment(Containment *newContainment) { 00390 d->containment = newContainment; 00391 } 00392 00393 } // Plasma namespace 00394 00395 #include "containmentactions.moc"
KDE 4.6 API Reference