• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdelibs API Reference
  • KDE Home
  • Contact Us
 

Plasma

  • sources
  • kde-4.12
  • kdelibs
  • plasma
popupapplet.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2008 by Montel Laurent <montel@kde.org>
3  * Copyright 2008 by Marco Martin <notmart@gmail.com>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library 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 GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor,
18  * Boston, MA 02110-1301 USA
19  */
20 
21 #include "popupapplet.h"
22 #include "private/popupapplet_p.h"
23 #include "private/dialog_p.h"
24 
25 #include <QApplication>
26 #include <QGraphicsProxyWidget>
27 #include <QGraphicsLinearLayout>
28 #include <QTimer>
29 #include <QVBoxLayout>
30 #include <QDeclarativeItem>
31 
32 #ifdef Q_WS_X11
33 #include <QX11Info>
34 #endif
35 
36 #include <kicon.h>
37 #include <kiconloader.h>
38 #include <kwindowsystem.h>
39 #include <kglobalsettings.h>
40 #include <netwm.h>
41 
42 #include "plasma/private/applet_p.h"
43 #include "plasma/private/extenderitemmimedata_p.h"
44 #include "plasma/corona.h"
45 #include "plasma/containment.h"
46 #include "plasma/private/containment_p.h"
47 #include "plasma/dialog.h"
48 #include "plasma/extenders/extender.h"
49 #include "plasma/extenders/extenderitem.h"
50 #include "plasma/package.h"
51 #include "plasma/theme.h"
52 #include "plasma/scripting/appletscript.h"
53 #include "plasma/tooltipmanager.h"
54 #include "plasma/widgets/iconwidget.h"
55 
56 namespace Plasma
57 {
58 
59 PopupApplet::PopupApplet(QObject *parent, const QVariantList &args)
60  : Plasma::Applet(parent, args),
61  d(new PopupAppletPrivate(this))
62 {
63 }
64 
65 PopupApplet::PopupApplet(const QString &packagePath, uint appletId, const QVariantList &args)
66  : Plasma::Applet(packagePath, appletId, args),
67  d(new PopupAppletPrivate(this))
68 {
69 }
70 
71 PopupApplet::~PopupApplet()
72 {
73  delete widget();
74  delete d;
75 }
76 
77 void PopupApplet::setPopupIcon(const QIcon &icon)
78 {
79  if (icon.isNull()) {
80  if (d->icon) {
81  delete d->icon;
82  d->icon = 0;
83  setLayout(0);
84  setAspectRatioMode(d->savedAspectRatio);
85  d->popupConstraintsEvent(FormFactorConstraint);
86  }
87 
88  return;
89  }
90 
91  d->createIconWidget();
92  d->icon->setIcon(icon);
93 }
94 
95 void PopupApplet::setPopupIcon(const QString &iconName)
96 {
97  // Attempt 1: is it in the plasmoid package?
98  if (package()) {
99  const QString file = package()->filePath("images", iconName);
100  if (!file.isEmpty()) {
101  setPopupIcon(KIcon(file));
102  return;
103  }
104  }
105 
106  // Attempt 2: is it a svg in the icons directory?
107  QString name = QString("icons/") + iconName.split("-").first();
108  if (!Plasma::Theme::defaultTheme()->imagePath(name).isEmpty()) {
109  d->createIconWidget();
110  d->icon->setSvg(name, iconName);
111  if (d->icon->svg().isEmpty()) {
112  setPopupIcon(KIcon(iconName));
113  }
114 
115  return;
116  }
117 
118  // Final Attempt: use KIcon
119  setPopupIcon(KIcon(iconName));
120 }
121 
122 QIcon PopupApplet::popupIcon() const
123 {
124  return d->icon ? d->icon->icon() : QIcon();
125 }
126 
127 QWidget *PopupApplet::widget()
128 {
129  return d->widget;
130 }
131 
132 void PopupApplet::setWidget(QWidget *widget)
133 {
134  if (d->widget) {
135  Plasma::Dialog *dialog = d->dialogPtr.data();
136  if (dialog) {
137  dialog->setGraphicsWidget(0);
138  QVBoxLayout *lay = 0;
139 
140  QLayout *existingLayout = dialog->layout();
141  if (existingLayout) {
142  lay = dynamic_cast<QVBoxLayout *>(existingLayout);
143  if (!lay) {
144  delete existingLayout;
145  }
146  }
147 
148  if (!lay) {
149  lay = new QVBoxLayout;
150  dialog->setLayout(lay);
151  }
152 
153  lay->removeWidget(d->widget);
154  lay->addWidget(widget);
155  } else if (d->proxy) {
156  d->proxy.data()->setWidget(widget);
157  }
158  }
159 
160  d->widget = widget;
161 }
162 
163 QGraphicsWidget *PopupApplet::graphicsWidget()
164 {
165  if (d->graphicsWidget) {
166  return d->graphicsWidget.data();
167  } else {
168  return static_cast<Applet*>(this)->d->extender.data();
169  }
170 }
171 
172 void PopupApplet::setGraphicsWidget(QGraphicsWidget *graphicsWidget)
173 {
174  if (d->graphicsWidget) {
175  if (d->dialogPtr) {
176  d->dialogPtr.data()->setGraphicsWidget(graphicsWidget);
177  } else if (layout()) {
178  QGraphicsLinearLayout *lay = static_cast<QGraphicsLinearLayout *>(layout());
179  lay->removeAt(0);
180  if (graphicsWidget) {
181  lay->addItem(graphicsWidget);
182  }
183  }
184  }
185 
186  d->graphicsWidget = graphicsWidget;
187 }
188 
189 void PopupAppletPrivate::checkExtenderAppearance(Plasma::FormFactor f)
190 {
191  Extender *extender = qobject_cast<Extender*>(q->graphicsWidget());
192  if (extender) {
193  if (f != Plasma::Horizontal && f != Plasma::Vertical) {
194  extender->setAppearance(Extender::NoBorders);
195  } else if (q->location() == TopEdge) {
196  extender->setAppearance(Extender::TopDownStacked);
197  } else {
198  extender->setAppearance(Extender::BottomUpStacked);
199  }
200 
201  if (dialogPtr) {
202  dialogPtr.data()->setGraphicsWidget(extender);
203  }
204  }
205 }
206 
207 void PopupAppletPrivate::popupConstraintsEvent(Plasma::Constraints constraints)
208 {
209  Plasma::FormFactor f = q->formFactor();
210 
211  if (constraints & Plasma::LocationConstraint) {
212  checkExtenderAppearance(f);
213  }
214 
215  if (constraints & Plasma::FormFactorConstraint ||
216  constraints & Plasma::StartupCompletedConstraint ||
217  (constraints & Plasma::SizeConstraint &&
218  (f == Plasma::Vertical || f == Plasma::Horizontal))) {
219  QGraphicsLinearLayout *lay = dynamic_cast<QGraphicsLinearLayout *>(q->layout());
220 
221  if (icon && lay && lay->count() > 0) {
222  lay->removeAt(0);
223  }
224 
225  QSizeF minimum;
226  QSizeF parentSize;
227 
228  QGraphicsWidget *gWidget = q->graphicsWidget();
229  //kDebug() << "graphics widget is" << (QObject*)gWidget;
230  QWidget *qWidget = q->widget();
231 
232  if (gWidget) {
233  minimum = gWidget->minimumSize();
234  // our layout may have been replaced on us in the call to graphicsWidget!
235  lay = dynamic_cast<QGraphicsLinearLayout *>(q->layout());
236 
237  if (!(constraints & LocationConstraint)) {
238  checkExtenderAppearance(f);
239  }
240  } else if (qWidget) {
241  minimum = qWidget->minimumSizeHint();
242  }
243 
244  //99% of the times q->parentWidget() is the containment, but using it we can also manage the applet-in-applet case (i.e. systray)
245  //there are also cases where the parentlayoutitem is bigger than the containment (e.g. newspaper)
246  QDeclarativeItem *di = qobject_cast<QDeclarativeItem *>(q->parentObject());
247  if (q->parentLayoutItem()) {
248  parentSize = q->parentLayoutItem()->geometry().size();
249  } else if (q->parentWidget()) {
250  parentSize = q->parentWidget()->size();
251  } else if (di) {
252  parentSize = QSizeF(di->width(), di->height());
253  }
254 
255  //check if someone did the nasty trick of applets in applets, in this case we always want to be collapsed
256  QGraphicsWidget *candidateParentApplet = q;
257  Plasma::Applet *parentApplet = 0;
258  //this loop should be executed normally a single time, at most 2-3 times for quite complex containments
259  while (candidateParentApplet) {
260  candidateParentApplet = candidateParentApplet->parentWidget();
261  parentApplet = qobject_cast<Plasma::Applet *>(candidateParentApplet);
262  if (parentApplet) {
263  break;
264  }
265  }
266 
267  //If the popup is more than two times larger than the applet
268  //center it (or taller in case of vertical panels
269  if (f == Plasma::Vertical) {
270  if ((gWidget && gWidget->size().height() > q->size().height() / 2) ||
271  (qWidget && qWidget->size().height() > q->size().height() / 2)) {
272  popupAlignment = Qt::AlignCenter;
273  } else {
274  popupAlignment = Qt::AlignLeft;
275  }
276  } else {
277  if ((gWidget && gWidget->size().width() > q->size().width() / 2) ||
278  (qWidget && qWidget->size().width() > q->size().width() / 2)) {
279  popupAlignment = Qt::AlignCenter;
280  } else {
281  popupAlignment = Qt::AlignLeft;
282  }
283  }
284 
285  //Applet on desktop
286  if (((!parentApplet || parentApplet->isContainment() ) && icon && (!icon->svg().isEmpty() || !icon->icon().isNull()) && ((f != Plasma::Vertical && f != Plasma::Horizontal)) ||
287  (((f == Plasma::Vertical && parentSize.width() >= minimum.width()) ||
288  (f == Plasma::Horizontal && parentSize.height() >= minimum.height())) &&
289  (!q->parentWidget() || (q->parentWidget()->size().width() >= minimum.width() && q->parentWidget()->size().height() >= minimum.height()))))) {
290  //kDebug() << "we are expanding the popupapplet";
291 
292 
293  // we only switch to expanded if we aren't horiz/vert constrained and
294  // this applet has an icon.
295  // otherwise, we leave it up to the applet itself to figure it out
296  if (icon) {
297  icon->hide();
298  }
299 
300  if (savedAspectRatio != Plasma::InvalidAspectRatioMode) {
301  q->setAspectRatioMode(savedAspectRatio);
302  }
303 
304  Dialog *dialog = dialogPtr.data();
305  if (dialog) {
306  if (dialog->layout() && qWidget) {
307  //we don't want to delete Widget inside the dialog layout
308  dialog->layout()->removeWidget(qWidget);
309  }
310 
311  if (qWidget) {
312  qWidget->setParent(0);
313  }
314 
315  delete dialog;
316  }
317 
318  if (!lay) {
319  lay = new QGraphicsLinearLayout();
320  lay->setContentsMargins(0, 0, 0, 0);
321  lay->setSpacing(0);
322  lay->setOrientation(Qt::Horizontal);
323  q->setLayout(lay);
324  }
325 
326  QSize prefSize;
327 
328  if (gWidget) {
329  if (proxy) {
330  proxy.data()->setWidget(0);
331  delete proxy.data();
332  }
333 
334  Corona *corona = qobject_cast<Corona *>(gWidget->scene());
335 
336  if (corona) {
337  corona->removeOffscreenWidget(gWidget);
338  }
339 
340  lay->addItem(gWidget);
341  prefSize = gWidget->preferredSize().toSize();
342  } else if (qWidget) {
343  if (!proxy) {
344  proxy = new QGraphicsProxyWidget(q);
345  proxy.data()->setWidget(qWidget);
346  proxy.data()->show();
347  }
348 
349  lay->addItem(proxy.data());
350  prefSize = qWidget->sizeHint();
351  }
352 
353  //we could be on a big panel, but in that case we will be able to resize
354  //more than the natural minimum size, because we'll transform into an icon
355  if (f == Plasma::Horizontal) {
356  minimum.setHeight(0);
357  } else if (f == Plasma::Vertical) {
358  minimum.setWidth(0);
359  }
360 
361  qreal left, top, right, bottom;
362  q->getContentsMargins(&left, &top, &right, &bottom);
363  QSizeF oldSize(q->size());
364 
365  //size not saved/invalid size saved
366  if (oldSize.width() < q->minimumSize().width() || oldSize.height() < q->minimumSize().height()) {
367  q->resize(prefSize);
368  emit q->appletTransformedItself();
369  }
370  } else {
371  //Applet on popup
372  if (icon && lay) {
373  lay->addItem(icon);
374  }
375 
376  //kDebug() << "about to switch to a popup";
377  if (!qWidget && !gWidget) {
378  delete dialogPtr.data();
379  return;
380  }
381 
382  //there was already a dialog? don't make the switch again
383  if (dialogPtr) {
384  return;
385  }
386 
387  if (proxy) {
388  proxy.data()->setWidget(0); // prevent it from deleting our widget!
389  delete proxy.data();
390  }
391 
392  //save the aspect ratio mode in case we drag'n drop in the Desktop later
393  savedAspectRatio = q->aspectRatioMode();
394 
395  if (icon) {
396  icon->show();
397  q->setAspectRatioMode(Plasma::ConstrainedSquare);
398  }
399 
400  Dialog *dialog = new Dialog();
401  dialog->d->appletPtr = q;
402  dialogPtr = dialog;
403 
404  if (icon) {
405  dialog->setAspectRatioMode(savedAspectRatio);
406  }
407 
408  //no longer use Qt::Popup since that seems to cause a lot of problem when you drag
409  //stuff out of your Dialog (extenders). Monitor WindowDeactivate events so we can
410  //emulate the same kind of behavior as Qt::Popup (close when you click somewhere
411  //else.
412 
413  if (gWidget) {
414  Corona *corona = qobject_cast<Corona *>(gWidget->scene());
415  if (!corona) {
416  corona = qobject_cast<Corona *>(q->scene());
417  }
418 
419  if (corona) {
420  corona->addOffscreenWidget(gWidget);
421  }
422 
423  gWidget->show();
424  dialog->setGraphicsWidget(gWidget);
425  dialog->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | (gWidget->windowFlags() & Qt::X11BypassWindowManagerHint));
426  } else if (qWidget) {
427  QVBoxLayout *l_layout = new QVBoxLayout(dialog);
428  l_layout->setSpacing(0);
429  l_layout->setMargin(0);
430  l_layout->addWidget(qWidget);
431  dialog->adjustSize();
432  dialog->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | (qWidget->windowFlags() & Qt::X11BypassWindowManagerHint));
433  } else {
434  dialog->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
435  }
436 
437  restoreDialogSize();
438  KWindowSystem::setState(dialog->winId(), NET::SkipTaskbar | NET::SkipPager);
439  dialog->installEventFilter(q);
440 
441  QObject::connect(dialog, SIGNAL(dialogResized()), q, SLOT(dialogSizeChanged()));
442  QObject::connect(dialog, SIGNAL(dialogVisible(bool)), q, SLOT(dialogStatusChanged(bool)));
443  }
444  }
445 
446  if (constraints & Plasma::PopupConstraint) {
447  updateDialogPosition();
448  }
449 
450  if (icon) {
451  // emit the size hint changing stuff for our applet as we are handling
452  // the size changings
453  emit q->sizeHintChanged(Qt::PreferredSize);
454  }
455 }
456 
457 void PopupAppletPrivate::appletActivated()
458 {
459  internalTogglePopup(true);
460 }
461 
462 QSizeF PopupApplet::sizeHint(Qt::SizeHint which, const QSizeF & constraint) const
463 {
464  if (!d->dialogPtr || which != Qt::PreferredSize) {
465  return Applet::sizeHint(which, constraint);
466  }
467 
468  switch (formFactor()) {
469  case Vertical:
470  case Horizontal: {
471  const int size = IconSize(KIconLoader::Panel);
472  return QSizeF(size, size);
473  }
474  default:
475  break;
476  }
477 
478  const int size = IconSize(KIconLoader::Desktop);
479  return QSizeF(size, size);
480 }
481 
482 void PopupApplet::mousePressEvent(QGraphicsSceneMouseEvent *event)
483 {
484  if (!d->icon && !d->popupLostFocus && event->buttons() == Qt::LeftButton) {
485  d->clicked = scenePos().toPoint();
486  event->setAccepted(true);
487  return;
488  } else {
489  d->popupLostFocus = false;
490  Applet::mousePressEvent(event);
491  }
492 }
493 
494 void PopupApplet::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
495 {
496  if (!d->icon &&
497  (d->clicked - scenePos().toPoint()).manhattanLength() < KGlobalSettings::dndEventDelay()) {
498  d->internalTogglePopup();
499  } else {
500  Applet::mouseReleaseEvent(event);
501  }
502 }
503 
504 bool PopupApplet::eventFilter(QObject *watched, QEvent *event)
505 {
506  if (!d->passive && watched == d->dialogPtr.data() && (event->type() == QEvent::WindowDeactivate)) {
507  d->popupLostFocus = true;
508  QTimer::singleShot(100, this, SLOT(clearPopupLostFocus()));
509  }
510 
511  if (watched == d->dialogPtr.data() && event->type() == QEvent::ContextMenu) {
512  //pass it up to the applet
513  //well, actually we have to pass it to the *containment*
514  //because all the code for showing an applet's contextmenu is actually in Containment.
515  Containment *c = containment();
516  if (c) {
517  Applet *applet = this;
518  Dialog *dialog = d->dialogPtr.data();
519  if (dialog && dialog->graphicsWidget()) {
520  int left, top, right, bottom;
521  dialog->getContentsMargins(&left, &top, &right, &bottom);
522  const QPoint eventPos = static_cast<QContextMenuEvent*>(event)->pos() - QPoint(left, top);
523  QPointF pos = dialog->graphicsWidget()->mapToScene(eventPos);
524 
525  if (Applet *actual = c->d->appletAt(pos)) {
526  applet = actual;
527  }
528  }
529 
530  KMenu desktopMenu;
531  c->d->addAppletActions(desktopMenu, applet, event);
532 
533  if (!desktopMenu.isEmpty()) {
534  desktopMenu.exec(static_cast<QContextMenuEvent*>(event)->globalPos());
535  return true;
536  }
537 
538  return false;
539  }
540  }
541 
542  return Applet::eventFilter(watched, event);
543 }
544 
545 //FIXME: some duplication between the drag events... maybe add some simple helper function?
546 void PopupApplet::dragEnterEvent(QGraphicsSceneDragDropEvent *event)
547 {
548  if (event->mimeData()->hasFormat(ExtenderItemMimeData::mimeType())) {
549  const ExtenderItemMimeData *mimeData =
550  qobject_cast<const ExtenderItemMimeData*>(event->mimeData());
551  if (mimeData && qobject_cast<Extender*>(graphicsWidget())) {
552  event->accept();
553  showPopup();
554  }
555  }
556 }
557 
558 void PopupApplet::dragLeaveEvent(QGraphicsSceneDragDropEvent *event)
559 {
560  if (event->mimeData()->hasFormat(ExtenderItemMimeData::mimeType())) {
561  const ExtenderItemMimeData *mimeData =
562  qobject_cast<const ExtenderItemMimeData*>(event->mimeData());
563  if (mimeData && qobject_cast<Extender*>(graphicsWidget())) {
564  //We want to hide the popup if we're not moving onto the popup AND it is not the popup
565  //we started.
566  if (d->dialogPtr && !d->dialogPtr.data()->geometry().contains(event->screenPos()) &&
567  mimeData->extenderItem()->extender() != qobject_cast<Extender*>(graphicsWidget())) {
568  //We actually try to hide the popup, with a call to showPopup, with a smal timeout,
569  //so if the user moves into the popup fast enough, it remains open (the extender
570  //will call showPopup which will cancel the timeout.
571  showPopup(250);
572  }
573  }
574  }
575 }
576 
577 void PopupApplet::dropEvent(QGraphicsSceneDragDropEvent *event)
578 {
579  if (event->mimeData()->hasFormat(ExtenderItemMimeData::mimeType())) {
580  const ExtenderItemMimeData *mimeData =
581  qobject_cast<const ExtenderItemMimeData*>(event->mimeData());
582  if (mimeData && qobject_cast<Extender*>(graphicsWidget())) {
583  mimeData->extenderItem()->setExtender(extender());
584  QApplication::restoreOverrideCursor();
585  }
586  }
587 }
588 
589 void PopupApplet::showPopup(uint popupDuration)
590 {
591  // use autohideTimer to store when the next show should be
592  if (popupDuration > 0 || d->autohideTimer) {
593  if (!d->autohideTimer) {
594  d->autohideTimer = new QTimer(this);
595  d->autohideTimer->setSingleShot(true);
596  connect(d->autohideTimer, SIGNAL(timeout()), this, SLOT(hideTimedPopup()));
597  }
598 
599  d->autohideTimer->stop();
600  d->autohideTimer->setInterval(popupDuration);
601  }
602 
603  //kDebug() << "starting delayed show, duration for popup is" << popupDuration;
604  d->delayedShowTimer.start(0, this);
605 }
606 
607 void PopupApplet::timerEvent(QTimerEvent *event)
608 {
609  if (event->timerId() == d->delayedShowTimer.timerId()) {
610  d->delayedShowTimer.stop();
611  Dialog *dialog = d->dialogPtr.data();
612  if (dialog) {
613  // move the popup before its fist show, even if the show isn't triggered by
614  // a click, this should fix the first random position seen in some widgets
615  if (!dialog->isVisible()) {
616  d->internalTogglePopup();
617  }
618 
619  const int popupDuration = d->autohideTimer ? d->autohideTimer->interval() : 0;
620  //kDebug() << "popupDuration is:" << (d->autohideTimer ? d->autohideTimer->interval() : 0);
621  if (popupDuration > 0) {
622  d->autohideTimer->start();
623  } else if (d->autohideTimer) {
624  d->autohideTimer->stop();
625  }
626  }
627  } else if (event->timerId() == d->showDialogTimer.timerId()) {
628  d->showDialogTimer.stop();
629  d->showDialog();
630  } else {
631  Applet::timerEvent(event);
632  }
633 }
634 
635 void PopupApplet::hidePopup()
636 {
637  d->showDialogTimer.stop();
638  d->delayedShowTimer.stop();
639 
640  Dialog *dialog = d->dialogPtr.data();
641  if (dialog && dialog->isVisible()) {
642  if (location() != Floating) {
643  dialog->animatedHide(locationToInverseDirection(location()));
644  } else {
645  dialog->hide();
646  }
647  }
648 }
649 
650 void PopupApplet::togglePopup()
651 {
652  d->internalTogglePopup();
653 }
654 
655 Plasma::PopupPlacement PopupApplet::popupPlacement() const
656 {
657  return d->popupPlacement;
658 }
659 
660 void PopupApplet::setPopupAlignment(Qt::AlignmentFlag alignment)
661 {
662  d->popupAlignment = alignment;
663 }
664 
665 Qt::AlignmentFlag PopupApplet::popupAlignment() const
666 {
667  return d->popupAlignment;
668 }
669 
670 void PopupApplet::popupEvent(bool popped)
671 {
672  if (Applet::d->script) {
673  emit Applet::d->script->popupEvent(popped);
674  }
675 }
676 
677 void PopupApplet::setPassivePopup(bool passive)
678 {
679  d->passive = passive;
680 }
681 
682 bool PopupApplet::isPassivePopup() const
683 {
684  return d->passive;
685 }
686 
687 bool PopupApplet::isPopupShowing() const
688 {
689  return d->dialogPtr && d->dialogPtr.data()->isVisible();
690 }
691 
692 bool PopupApplet::isIconified() const
693 {
694  return d->dialogPtr;
695 }
696 
697 PopupAppletPrivate::PopupAppletPrivate(PopupApplet *applet)
698  : q(applet),
699  icon(0),
700  widget(0),
701  popupPlacement(Plasma::FloatingPopup),
702  popupAlignment(Qt::AlignLeft),
703  savedAspectRatio(Plasma::InvalidAspectRatioMode),
704  autohideTimer(0),
705  preShowStatus(UnknownStatus),
706  popupLostFocus(false),
707  passive(false)
708 {
709  int iconSize = IconSize(KIconLoader::Desktop);
710  q->resize(iconSize, iconSize);
711  q->setAcceptDrops(true);
712  QObject::disconnect(q, SIGNAL(activate()), static_cast<Applet*>(q), SLOT(setFocus()));
713  QObject::connect(q, SIGNAL(activate()), q, SLOT(appletActivated()));
714  QObject::connect(KGlobalSettings::self(), SIGNAL(iconChanged(int)), q, SLOT(iconSizeChanged(int)));
715 }
716 
717 PopupAppletPrivate::~PopupAppletPrivate()
718 {
719  if (proxy) {
720  proxy.data()->setWidget(0);
721  }
722 
723  delete dialogPtr.data();
724  delete icon;
725 }
726 
727 void PopupAppletPrivate::iconSizeChanged(int group)
728 {
729  if (icon && (group == KIconLoader::Desktop || group == KIconLoader::Panel)) {
730  q->updateGeometry();
731  }
732 }
733 
734 void PopupAppletPrivate::internalTogglePopup(bool fromActivatedSignal)
735 {
736  if (autohideTimer) {
737  autohideTimer->stop();
738  }
739 
740  delayedShowTimer.stop();
741 
742  Plasma::Dialog *dialog = dialogPtr.data();
743  if (!dialog) {
744  q->setFocus(Qt::ShortcutFocusReason);
745  if (!fromActivatedSignal) {
746  QObject::disconnect(q, SIGNAL(activate()), q, SLOT(appletActivated()));
747  emit q->activate();
748  QObject::connect(q, SIGNAL(activate()), q, SLOT(appletActivated()));
749  }
750  return;
751  }
752 
753  if (!q->view()) {
754  return;
755  }
756 
757  if (dialog->isVisible()) {
758  if (q->location() != Floating) {
759  dialog->animatedHide(locationToInverseDirection(q->location()));
760  } else {
761  dialog->hide();
762  }
763 
764  dialog->clearFocus();
765  } else {
766  if (q->graphicsWidget() &&
767  q->graphicsWidget() == static_cast<Applet*>(q)->d->extender.data() &&
768  static_cast<Applet*>(q)->d->extender.data()->isEmpty()) {
769  // we have nothing to show, so let's not.
770  if (!fromActivatedSignal) {
771  QObject::disconnect(q, SIGNAL(activate()), q, SLOT(appletActivated()));
772  emit q->activate();
773  QObject::connect(q, SIGNAL(activate()), q, SLOT(appletActivated()));
774  }
775  return;
776  }
777 
778  ToolTipManager::self()->hide(q);
779  showDialogTimer.start(0, q);
780  }
781 }
782 
783 void PopupAppletPrivate::showDialog()
784 {
785  Plasma::Dialog *dialog = dialogPtr.data();
786  if (!dialog) {
787  return;
788  }
789 
790  updateDialogPosition();
791 
792  KWindowSystem::setOnAllDesktops(dialog->winId(), true);
793  KWindowSystem::setState(dialog->winId(), NET::SkipTaskbar | NET::SkipPager);
794 
795  if (icon) {
796  dialog->setAspectRatioMode(savedAspectRatio);
797  }
798 
799  if (q->location() != Floating) {
800  dialog->animatedShow(locationToDirection(q->location()));
801  } else {
802  dialog->show();
803  }
804 
805  if (!(dialog->windowFlags() & Qt::X11BypassWindowManagerHint)) {
806  KWindowSystem::activateWindow(dialog->winId());
807  }
808 }
809 
810 void PopupAppletPrivate::hideTimedPopup()
811 {
812  autohideTimer->stop();
813  q->hidePopup();
814 }
815 
816 void PopupAppletPrivate::clearPopupLostFocus()
817 {
818  if (!icon || !icon->isDown()) {
819  q->hidePopup();
820  }
821 
822  popupLostFocus = false;
823 }
824 
825 KConfigGroup PopupAppletPrivate::popupConfigGroup()
826 {
827  KConfigGroup *mainGroup = static_cast<Applet*>(q)->d->mainConfigGroup();
828  return KConfigGroup(mainGroup, "PopupApplet");
829 }
830 
831 void PopupAppletPrivate::dialogSizeChanged()
832 {
833  //Reposition the dialog
834  Plasma::Dialog *dialog = dialogPtr.data();
835  if (dialog) {
836  KConfigGroup sizeGroup = popupConfigGroup();
837  sizeGroup.writeEntry("DialogHeight", dialog->height());
838  sizeGroup.writeEntry("DialogWidth", dialog->width());
839 
840  updateDialogPosition(!dialog->isUserResizing());
841 
842  emit q->configNeedsSaving();
843  emit q->appletTransformedByUser();
844  }
845 }
846 
847 void PopupAppletPrivate::dialogStatusChanged(bool shown)
848 {
849  if (shown) {
850  preShowStatus = q->status();
851  q->setStatus(NeedsAttentionStatus);
852  QObject::connect(q, SIGNAL(newStatus(Plasma::ItemStatus)),
853  q, SLOT(statusChangeWhileShown(Plasma::ItemStatus)),
854  Qt::UniqueConnection);
855  } else {
856  QObject::disconnect(q, SIGNAL(newStatus(Plasma::ItemStatus)),
857  q, SLOT(statusChangeWhileShown(Plasma::ItemStatus)));
858  q->setStatus(preShowStatus);
859  }
860 
861  q->popupEvent(shown);
862 }
863 
864 void PopupAppletPrivate::statusChangeWhileShown(Plasma::ItemStatus status)
865 {
866  preShowStatus = status;
867 }
868 
869 void PopupAppletPrivate::createIconWidget()
870 {
871  if (icon) {
872  return;
873  }
874 
875  icon = new Plasma::IconWidget(q);
876  QObject::connect(icon, SIGNAL(clicked()), q, SLOT(internalTogglePopup()));
877 
878  QGraphicsLinearLayout *layout = new QGraphicsLinearLayout();
879  layout->setContentsMargins(0, 0, 0, 0);
880  layout->setSpacing(0);
881  layout->setOrientation(Qt::Horizontal);
882  layout->addItem(icon);
883  layout->setAlignment(icon, Qt::AlignCenter);
884  q->setLayout(layout);
885 }
886 
887 void PopupAppletPrivate::restoreDialogSize()
888 {
889  Plasma::Dialog *dialog = dialogPtr.data();
890  if (!dialog) {
891  return;
892  }
893 
894  Corona *corona = qobject_cast<Corona *>(q->scene());
895  if (!corona) {
896  return;
897  }
898 
899  KConfigGroup sizeGroup = popupConfigGroup();
900 
901  int preferredWidth = 0;
902  int preferredHeight = 0;
903  QGraphicsWidget *gWidget = dialog->graphicsWidget();
904  if (gWidget) {
905  preferredWidth = gWidget->preferredSize().width();
906  preferredHeight = gWidget->preferredSize().height();
907  }
908 
909  const int width = qMin(sizeGroup.readEntry("DialogWidth", preferredWidth),
910  corona->screenGeometry(-1).width() - 50);
911  const int height = qMin(sizeGroup.readEntry("DialogHeight", preferredHeight),
912  corona->screenGeometry(-1).height() - 50);
913 
914  QSize saved(width, height);
915 
916  if (saved.isNull()) {
917  saved = dialog->sizeHint();
918  } else {
919  saved = saved.expandedTo(dialog->minimumSizeHint());
920  }
921 
922  if (saved.width() != dialog->width() || saved.height() != dialog->height()) {
923  dialog->resize(saved);
924  /*if (gWidget) {
925  gWidget->resize(saved);
926  }*/
927  }
928 }
929 
930 void PopupAppletPrivate::updateDialogPosition(bool move)
931 {
932  Plasma::Dialog *dialog = dialogPtr.data();
933  if (!dialog) {
934  return;
935  }
936 
937  Corona *corona = qobject_cast<Corona *>(q->scene());
938  if (!corona) {
939  return;
940  }
941 
942  QGraphicsView *view = q->view();
943  if (!view) {
944  return;
945  }
946 
947  const QPoint appletPos = view->mapToGlobal(view->mapFromScene(q->scenePos()));
948 
949  QPoint dialogPos = dialog->pos();
950  if (move) {
951  if (!q->containment() || view == q->containment()->view()) {
952  dialogPos = corona->popupPosition(q, dialog->size(), popupAlignment);
953  } else {
954  dialogPos = corona->popupPosition(q->parentItem(), dialog->size(), popupAlignment);
955  }
956  }
957 
958  bool reverse = false;
959  if (q->formFactor() == Plasma::Vertical) {
960  reverse = (appletPos.y() + (q->size().height() / 2)) < (dialogPos.y() + (dialog->size().height() / 2));
961  dialog->setMinimumResizeLimits(-1, appletPos.y(), -1, appletPos.y() + q->size().height());
962  } else {
963  reverse = (appletPos.x() + (q->size().width() / 2)) < (dialogPos.x() + (dialog->size().width() / 2));
964  dialog->setMinimumResizeLimits(appletPos.x(), -1, appletPos.x() + q->size().width(), -1);
965  }
966 
967  Dialog::ResizeCorners resizeCorners = Dialog::NoCorner;
968  switch (q->location()) {
969  case BottomEdge:
970  resizeCorners = Dialog::NorthEast | Dialog::NorthWest;
971  popupPlacement = reverse ? TopPosedLeftAlignedPopup : TopPosedRightAlignedPopup;
972  break;
973  case TopEdge:
974  resizeCorners = Dialog::SouthEast | Dialog::SouthWest;
975  popupPlacement = reverse ? Plasma::BottomPosedLeftAlignedPopup : Plasma::BottomPosedRightAlignedPopup;
976  break;
977  case LeftEdge:
978  resizeCorners = Dialog::SouthEast | Dialog::NorthEast;
979  popupPlacement = reverse ? RightPosedTopAlignedPopup : RightPosedBottomAlignedPopup;
980  break;
981 
982  case RightEdge:
983  resizeCorners = Dialog::SouthWest | Dialog::NorthWest;
984  popupPlacement = reverse ? LeftPosedTopAlignedPopup : LeftPosedBottomAlignedPopup;
985  break;
986 
987  default:
988  popupPlacement = FloatingPopup;
989  resizeCorners = Dialog::All;
990  break;
991  }
992 
993  dialog->setResizeHandleCorners(resizeCorners);
994  if (move) {
995  dialog->move(dialogPos);
996  }
997 }
998 
999 } // Plasma namespace
1000 
1001 #include "popupapplet.moc"
1002 
Plasma::PopupApplet::setPopupAlignment
void setPopupAlignment(Qt::AlignmentFlag alignment)
Sets the default alignment of the popup relative to the applet.
Definition: popupapplet.cpp:660
Plasma::SizeConstraint
the size of the applet was changed
Definition: plasma.h:49
Plasma::Vertical
The applet is constrained horizontally, but can expand vertically.
Definition: plasma.h:77
Plasma::Applet::package
const Package * package() const
Accessor for the associated Package object if any.
Definition: applet.cpp:691
Plasma::Applet::activate
void activate()
Emitted when activation is requested due to, for example, a global keyboard shortcut.
Plasma::StartupCompletedConstraint
application startup has completed
Definition: plasma.h:51
Plasma::UnknownStatus
The status is unknown.
Definition: plasma.h:257
Plasma::Extender
Extends applets to allow detachable parts.
Definition: extender.h:65
Plasma::NeedsAttentionStatus
The Item needs attention.
Definition: plasma.h:260
Plasma::Dialog::All
Definition: dialog.h:64
Plasma::Extender::NoBorders
Draws no borders on the extender's items.
Definition: extender.h:80
Plasma::PopupApplet::isPassivePopup
bool isPassivePopup() const
Definition: popupapplet.cpp:682
Plasma::Applet::timerEvent
void timerEvent(QTimerEvent *event)
Reimplemented from QObject.
Definition: applet.cpp:2553
Plasma::Dialog::animatedShow
void animatedShow(Plasma::Direction direction)
Causes an animated show; requires compositing to work, otherwise the dialog will simply show...
Definition: dialog.cpp:829
extender.h
Plasma::Applet::location
virtual Location location() const
Returns the location of the scene which is displaying applet.
Definition: applet.cpp:1618
Plasma::PopupApplet::timerEvent
void timerEvent(QTimerEvent *event)
Reimplemented from QGraphicsLayoutItem.
Definition: popupapplet.cpp:607
Plasma::Applet::formFactor
virtual FormFactor formFactor() const
Returns the current form factor the applet is being displayed in.
Definition: applet.cpp:1479
Plasma::ConstrainedSquare
The applet is no wider (in horizontal formfactors) or no higher (in vertical ones) than a square...
Definition: plasma.h:215
QWidget
Plasma::ToolTipManager::self
static ToolTipManager * self()
Definition: tooltipmanager.cpp:119
Plasma::Desktop
On the planar desktop layer, extending across the full screen from edge to edge.
Definition: plasma.h:111
Plasma::LeftPosedBottomAlignedPopup
Popup positioned on the left, aligned to the bottom of the widget.
Definition: plasma.h:145
theme.h
Plasma::PopupApplet::hidePopup
void hidePopup()
Hides the popup.
Definition: popupapplet.cpp:635
Plasma::Dialog::isUserResizing
bool isUserResizing() const
Definition: dialog.cpp:764
Plasma::PopupApplet::setWidget
void setWidget(QWidget *widget)
Definition: popupapplet.cpp:132
Plasma::PopupApplet::dragLeaveEvent
void dragLeaveEvent(QGraphicsSceneDragDropEvent *event)
Reimplemented from QGraphicsLayoutItem.
Definition: popupapplet.cpp:558
iconwidget.h
containment.h
QObject
Plasma::BottomPosedLeftAlignedPopup
Popup positioned on the bottom, aligned to the left of the wigdet.
Definition: plasma.h:147
Plasma::PopupApplet::popupEvent
virtual void popupEvent(bool show)
This event handler can be reimplemented in a subclass to receive an event before the popup is shown o...
Definition: popupapplet.cpp:670
Plasma::Horizontal
The applet is constrained vertically, but can expand horizontally.
Definition: plasma.h:75
tooltipmanager.h
Plasma::PopupApplet::eventFilter
bool eventFilter(QObject *watched, QEvent *event)
Reimplemented from QGraphicsLayoutItem.
Definition: popupapplet.cpp:504
Plasma::Dialog::graphicsWidget
QGraphicsWidget * graphicsWidget()
Definition: dialog.cpp:668
Plasma::PopupApplet::dropEvent
void dropEvent(QGraphicsSceneDragDropEvent *event)
Reimplemented from QGraphicsLayoutItem.
Definition: popupapplet.cpp:577
Plasma::LeftPosedTopAlignedPopup
Popup positioned on the left, aligned to the right of the wigdet.
Definition: plasma.h:143
Plasma::RightPosedBottomAlignedPopup
Popup positioned on the right, aligned to the bottom of the widget.
Definition: plasma.h:153
Plasma::PopupApplet::graphicsWidget
virtual QGraphicsWidget * graphicsWidget()
Implement either this function or widget().
Definition: popupapplet.cpp:163
Plasma::RightPosedTopAlignedPopup
Popup positioned on the right, aligned to the top of the wigdet.
Definition: plasma.h:151
Plasma::Dialog::setGraphicsWidget
void setGraphicsWidget(QGraphicsWidget *widget)
Sets a QGraphicsWidget to be shown as the content in this dialog.
Definition: dialog.cpp:614
Plasma::Applet
The base Applet class.
Definition: applet.h:77
Plasma::Extender::TopDownStacked
Draws no borders on the bottom extenderitem, but draws the left, bottom and right border on subsequen...
Definition: extender.h:89
Plasma::PopupPlacement
PopupPlacement
The popup position enumeration relatively to his attached widget.
Definition: plasma.h:137
Plasma::Dialog
A dialog that uses the Plasma style.
Definition: dialog.h:51
Plasma::PopupConstraint
the position of the popup needs to be recalculated
Definition: plasma.h:53
Plasma::PopupApplet::widget
virtual QWidget * widget()
Implement either this function or graphicsWidget().
Definition: popupapplet.cpp:127
Plasma::PopupApplet::dragEnterEvent
void dragEnterEvent(QGraphicsSceneDragDropEvent *event)
Reimplemented from QGraphicsLayoutItem.
Definition: popupapplet.cpp:546
Plasma::PopupApplet::mouseReleaseEvent
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
Reimplemented from QGraphicsLayoutItem.
Definition: popupapplet.cpp:494
Plasma::PopupApplet::popupPlacement
Plasma::PopupPlacement popupPlacement() const
Definition: popupapplet.cpp:655
Plasma::PopupApplet
Allows applets to automatically 'collapse' into an icon when put in an panel, and is a convenient bas...
Definition: popupapplet.h:52
Plasma::Extender::BottomUpStacked
Draws no borders on the topmost extenderitem, but draws the left, top and right border on subsequent ...
Definition: extender.h:83
Plasma::BottomPosedRightAlignedPopup
Popup positioned on the bottom, aligned to the right of the widget.
Definition: plasma.h:149
Plasma::FormFactor
FormFactor
The FormFactor enumeration describes how a Plasma::Applet should arrange itself.
Definition: plasma.h:64
Plasma::Applet::containment
Containment * containment() const
Definition: applet.cpp:1518
Plasma::Applet::sizeHint
QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint=QSizeF()) const
Reimplemented from QGraphicsLayoutItem.
Definition: applet.cpp:2509
Plasma::locationToDirection
Direction locationToDirection(Location location)
Converts a location to a direction.
Definition: plasma.cpp:51
Plasma::Dialog::setMinimumResizeLimits
void setMinimumResizeLimits(int left, int top, int right, int bottom)
Sets the minimum values that each of four sides of the rect may expand to or from.
Definition: dialog.cpp:769
Plasma::ToolTipManager::hide
void hide(QGraphicsWidget *widget)
Hides the tooltip for a widget immediately.
Definition: tooltipmanager.cpp:188
QGraphicsProxyWidget
Plasma::TopEdge
Along the top of the screen.
Definition: plasma.h:114
Plasma::FormFactorConstraint
The FormFactor for an object.
Definition: plasma.h:46
Plasma::Dialog::animatedHide
void animatedHide(Plasma::Direction direction)
Causes an animated hide; requires compositing to work, otherwise the dialog will simply hide...
Definition: dialog.cpp:796
Plasma::FloatingPopup
Free floating, non attached popup.
Definition: plasma.h:138
Plasma::PopupApplet::showPopup
void showPopup(uint displayTime=0)
Shows the dialog showing the widget if the applet is in a panel.
Definition: popupapplet.cpp:589
Plasma::Dialog::setAspectRatioMode
void setAspectRatioMode(Plasma::AspectRatioMode mode)
Sets the preferred aspect ratio mode for placement and resizing.
Definition: dialog.cpp:877
Plasma::locationToInverseDirection
Direction locationToInverseDirection(Location location)
Converts a location to the direction facing it.
Definition: plasma.cpp:72
Plasma::TopPosedRightAlignedPopup
Popup positioned on the top, aligned to the right of the widget.
Definition: plasma.h:141
Plasma::Dialog::SouthEast
Definition: dialog.h:61
Plasma::PopupApplet::setGraphicsWidget
void setGraphicsWidget(QGraphicsWidget *widget)
Definition: popupapplet.cpp:172
Plasma::PopupApplet::isIconified
bool isIconified() const
Definition: popupapplet.cpp:692
Plasma::Floating
Free floating.
Definition: plasma.h:109
Plasma::Dialog::NorthEast
Definition: dialog.h:60
Plasma::TopPosedLeftAlignedPopup
Popup positioned on the top, aligned to the left of the wigdet.
Definition: plasma.h:139
Plasma::BottomEdge
Along the bottom of the screen.
Definition: plasma.h:115
dialog.h
Plasma::PopupApplet::sizeHint
QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint=QSizeF()) const
Reimplemented from QGraphicsLayoutItem.
Definition: popupapplet.cpp:462
Plasma::Extender::setAppearance
void setAppearance(Appearance appearance)
Use this function to instruct the extender on how to render its items.
Definition: extender.cpp:329
Plasma::LocationConstraint
The Location of an object.
Definition: plasma.h:47
Plasma::Dialog::SouthWest
Definition: dialog.h:63
package.h
Plasma::Theme::defaultTheme
static Theme * defaultTheme()
Singleton pattern accessor.
Definition: theme.cpp:544
Plasma::Applet::name
QString name() const
Returns the user-visible name for the applet, as specified in the .desktop file.
Plasma::InvalidAspectRatioMode
Unset mode used for dev convenience when there is a need to store the aspectRatioMode somewhere...
Definition: plasma.h:209
corona.h
Plasma::Applet::extender
Extender * extender() const
Definition: applet.cpp:782
Plasma::IconWidget
Definition: iconwidget.h:56
QGraphicsView
Plasma::PopupApplet::setPassivePopup
void setPassivePopup(bool passive)
Sets whether or not the dialog popup that gets created should be a "passive" popup that does not stea...
Definition: popupapplet.cpp:677
Plasma::Dialog::NorthWest
Definition: dialog.h:62
Plasma::PopupApplet::popupIcon
QIcon popupIcon() const
Definition: popupapplet.cpp:122
Plasma::PopupApplet::mousePressEvent
void mousePressEvent(QGraphicsSceneMouseEvent *event)
Reimplemented from QGraphicsLayoutItem.
Definition: popupapplet.cpp:482
Plasma::Applet::setAspectRatioMode
void setAspectRatioMode(Plasma::AspectRatioMode)
Sets the preferred aspect ratio mode for placement and resizing.
Definition: applet.cpp:1636
Plasma::PopupApplet::PopupApplet
PopupApplet(QObject *parent, const QVariantList &args)
Definition: popupapplet.cpp:59
Plasma::Applet::eventFilter
bool eventFilter(QObject *o, QEvent *e)
Definition: applet.cpp:1774
Plasma::Containment
The base class for plugins that provide backgrounds and applet grouping containers.
Definition: containment.h:72
Plasma::ItemStatus
ItemStatus
Status of an applet.
Definition: plasma.h:256
Plasma::RightEdge
Along the right side of the screen.
Definition: plasma.h:117
Plasma::Dialog::setResizeHandleCorners
void setResizeHandleCorners(ResizeCorners corners)
Definition: dialog.cpp:751
appletscript.h
Plasma::PopupApplet::setPopupIcon
void setPopupIcon(const QIcon &icon)
Definition: popupapplet.cpp:77
Plasma::Applet::isContainment
bool isContainment() const
Definition: applet.cpp:2647
popupapplet.h
Plasma::LeftEdge
Along the left side of the screen.
Definition: plasma.h:116
Plasma::PopupApplet::isPopupShowing
bool isPopupShowing() const
Definition: popupapplet.cpp:687
Plasma::PopupApplet::togglePopup
void togglePopup()
Toggles the popup.
Definition: popupapplet.cpp:650
extenderitem.h
Plasma::Dialog::NoCorner
Definition: dialog.h:59
Plasma::PopupApplet::popupAlignment
Qt::AlignmentFlag popupAlignment() const
Plasma::PopupApplet::~PopupApplet
~PopupApplet()
Definition: popupapplet.cpp:71
Plasma::Package::filePath
QString filePath(const char *fileType, const QString &filename) const
Get the path to a given file.
Definition: package.cpp:213
QGraphicsWidget
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:48:33 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

Plasma

Skip menu "Plasma"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdelibs API Reference

Skip menu "kdelibs API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  • kjsembed
  •   WTF
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Nepomuk-Core
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal