mirror of
https://bitbucket.org/smil3y/kde-workspace.git
synced 2025-02-24 19:02:51 +00:00
735 lines
23 KiB
C++
735 lines
23 KiB
C++
/*
|
|
* Copyright (C) 2007 by Ivan Cukic <ivan.cukic+kde@gmail.com>
|
|
* Copyright (C) 2009 by Ana Cecília Martins <anaceciliamb@gmail.com>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU Library/Lesser General Public License
|
|
* version 2, or (at your option) any later version, as published by the
|
|
* Free Software Foundation
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details
|
|
*
|
|
* You should have received a copy of the GNU Library/Lesser General Public
|
|
* License along with this program; if not, write to the
|
|
* Free Software Foundation, Inc.,
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*/
|
|
|
|
#include "widgetexplorer.h"
|
|
|
|
#include <QMutex>
|
|
#include <QApplication>
|
|
#include <QGraphicsGridLayout>
|
|
#include <QGraphicsLinearLayout>
|
|
#include <QGraphicsSceneMouseEvent>
|
|
#include <Plasma/LineEdit>
|
|
#include <Plasma/ToolButton>
|
|
#include <Plasma/ScrollWidget>
|
|
#include <Plasma/Frame>
|
|
#include <Plasma/IconWidget>
|
|
#include <Plasma/Label>
|
|
#include <klineedit.h>
|
|
#include <ksycoca.h>
|
|
#include <kicon.h>
|
|
#include <kdebug.h>
|
|
|
|
namespace Plasma
|
|
{
|
|
|
|
// hardcoded but ok because the widget is not resizable, that implies issue with big font sizes tho
|
|
static const int s_margin = 4;
|
|
static const QSizeF s_appletframesize = QSize(300, 100);
|
|
static const QSizeF s_appleticonsize = QSize(86, 86);
|
|
static const int s_filterwidth = 305;
|
|
static const int s_dragpixmapsize = 64;
|
|
static const int s_appletactiveiconsize = 22;
|
|
// the default Plasma::Corona MIME type, see:
|
|
// kdelibs/plasma/corona.cpp
|
|
static const QString s_coronamimetype = QString::fromLatin1("text/x-plasmoidservicename");
|
|
|
|
static Qt::Orientation kOrientationForLocation(const Plasma::Location location)
|
|
{
|
|
switch (location) {
|
|
case Plasma::Location::LeftEdge:
|
|
case Plasma::Location::RightEdge: {
|
|
return Qt::Vertical;
|
|
}
|
|
default: {
|
|
return Qt::Horizontal;
|
|
}
|
|
}
|
|
Q_UNREACHABLE();
|
|
}
|
|
|
|
// similar to Plasma::Applet::view(), the important thing is to get a window (preferably active
|
|
// one)
|
|
static QGraphicsView* kSceneWindow(const QGraphicsScene *scene)
|
|
{
|
|
if (!scene) {
|
|
kWarning() << "No WidgetExplorer scene";
|
|
return nullptr;
|
|
}
|
|
foreach (QGraphicsView *view, scene->views()) {
|
|
if (view->isActiveWindow()) {
|
|
return view;
|
|
}
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
class AppletIcon : public Plasma::IconWidget
|
|
{
|
|
Q_OBJECT
|
|
public:
|
|
AppletIcon(QGraphicsItem *parent, const KPluginInfo &appletInfo);
|
|
|
|
protected:
|
|
void mousePressEvent(QGraphicsSceneMouseEvent *event) final;
|
|
void mouseMoveEvent(QGraphicsSceneMouseEvent *event) final;
|
|
|
|
private:
|
|
KPluginInfo m_appletinfo;
|
|
QPointF m_dragstartpos;
|
|
};
|
|
|
|
AppletIcon::AppletIcon(QGraphicsItem *parent, const KPluginInfo &appletInfo)
|
|
: Plasma::IconWidget(parent),
|
|
m_appletinfo(appletInfo)
|
|
{
|
|
}
|
|
|
|
void AppletIcon::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
|
{
|
|
m_dragstartpos = event->pos();
|
|
// don't propagate
|
|
event->accept();
|
|
}
|
|
|
|
void AppletIcon::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
|
{
|
|
if (event->buttons() & Qt::LeftButton &&
|
|
(event->pos() - m_dragstartpos).manhattanLength() > KGlobalSettings::dndEventDelay())
|
|
{
|
|
QGraphicsView* sceneview = kSceneWindow(scene());
|
|
QDrag* drag = new QDrag(sceneview ? sceneview : qApp->activeWindow());
|
|
QMimeData* mimedata = new QMimeData();
|
|
mimedata->setData(s_coronamimetype, m_appletinfo.pluginName().toUtf8());
|
|
drag->setMimeData(mimedata);
|
|
drag->setPixmap(KIcon(m_appletinfo.icon()).pixmap(s_dragpixmapsize));
|
|
static const int halfdragpixmapsize = (s_dragpixmapsize / 2);
|
|
drag->setHotSpot(QPoint(halfdragpixmapsize, halfdragpixmapsize));
|
|
setPressed(true);
|
|
drag->exec();
|
|
setPressed(false);
|
|
}
|
|
}
|
|
|
|
|
|
class AppletFrame : public Plasma::Frame
|
|
{
|
|
Q_OBJECT
|
|
public:
|
|
AppletFrame(QGraphicsWidget *parent, const KPluginInfo &appletInfo);
|
|
|
|
KPluginInfo pluginInfo() const;
|
|
void setRunning(const bool isrunning);
|
|
|
|
Q_SIGNALS:
|
|
void addApplet(const QString &applet);
|
|
void removeApplet(const QString &applet);
|
|
|
|
private Q_SLOTS:
|
|
void slotAddApplet();
|
|
void slotRemoveApplet();
|
|
void slotUpdateFonts();
|
|
|
|
private:
|
|
KPluginInfo m_appletinfo;
|
|
AppletIcon* m_appleticon;
|
|
Plasma::Label* m_appletname;
|
|
Plasma::IconWidget* m_appletactive;
|
|
Plasma::Label* m_appletcomment;
|
|
};
|
|
|
|
AppletFrame::AppletFrame(QGraphicsWidget *parent, const KPluginInfo &appletInfo)
|
|
: Plasma::Frame(parent),
|
|
m_appletinfo(appletInfo),
|
|
m_appleticon(nullptr),
|
|
m_appletname(nullptr),
|
|
m_appletactive(nullptr),
|
|
m_appletcomment(nullptr)
|
|
{
|
|
setFrameShadow(Plasma::Frame::Sunken);
|
|
|
|
QGraphicsGridLayout* appletLayout = new QGraphicsGridLayout(this);
|
|
m_appleticon = new AppletIcon(this, appletInfo);
|
|
m_appleticon->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
|
|
m_appleticon->setMinimumSize(s_appleticonsize);
|
|
m_appleticon->setMaximumSize(s_appleticonsize);
|
|
m_appleticon->setIcon(appletInfo.icon());
|
|
// multiple applet instances can be added thus not conditional
|
|
m_appleticon->setToolTip(i18n("Double-click or drag to add this applet."));
|
|
connect(
|
|
m_appleticon, SIGNAL(doubleClicked()),
|
|
this, SLOT(slotAddApplet())
|
|
);
|
|
appletLayout->addItem(m_appleticon, 0, 0, 2, 1);
|
|
|
|
m_appletname = new Plasma::Label(this);
|
|
m_appletname->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
|
|
QFont appletNameFont = KGlobalSettings::generalFont();
|
|
appletNameFont.setBold(true);
|
|
m_appletname->setFont(appletNameFont);
|
|
m_appletname->setText(appletInfo.name());
|
|
appletLayout->addItem(m_appletname, 0, 1);
|
|
|
|
m_appletactive = new Plasma::IconWidget(this);
|
|
m_appletactive->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
|
|
m_appletactive->setMaximumSize(s_appletactiveiconsize, s_appletactiveiconsize);
|
|
m_appletactive->setIcon(KIcon());
|
|
// all applet instances are removed
|
|
m_appletactive->setToolTip(i18n("Click to remove this applet."));
|
|
connect(
|
|
m_appletactive, SIGNAL(clicked()),
|
|
this, SLOT(slotRemoveApplet())
|
|
);
|
|
appletLayout->addItem(m_appletactive, 0, 2);
|
|
|
|
m_appletcomment = new Plasma::Label(this);
|
|
m_appletcomment->setAlignment(Qt::AlignLeft | Qt::AlignTop);
|
|
m_appletcomment->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
|
m_appletcomment->setFont(KGlobalSettings::smallestReadableFont());
|
|
m_appletcomment->setText(appletInfo.comment());
|
|
appletLayout->addItem(m_appletcomment, 1, 1, 1, 2);
|
|
|
|
setLayout(appletLayout);
|
|
|
|
connect(
|
|
KGlobalSettings::self(), SIGNAL(kdisplayFontChanged()),
|
|
this, SLOT(slotUpdateFonts())
|
|
);
|
|
}
|
|
|
|
KPluginInfo AppletFrame::pluginInfo() const
|
|
{
|
|
return m_appletinfo;
|
|
}
|
|
|
|
void AppletFrame::setRunning(const bool isrunning)
|
|
{
|
|
m_appletactive->setIcon(isrunning ? KIcon("edit-delete") : KIcon());
|
|
}
|
|
|
|
void AppletFrame::slotAddApplet()
|
|
{
|
|
m_appleticon->setPressed(false);
|
|
emit addApplet(m_appletinfo.pluginName());
|
|
}
|
|
|
|
void AppletFrame::slotRemoveApplet()
|
|
{
|
|
m_appletactive->setPressed(false);
|
|
emit removeApplet(m_appletinfo.pluginName());
|
|
}
|
|
|
|
void AppletFrame::slotUpdateFonts()
|
|
{
|
|
QFont appletNameFont = KGlobalSettings::generalFont();
|
|
appletNameFont.setBold(true);
|
|
m_appletname->setFont(appletNameFont);
|
|
m_appletcomment->setFont(KGlobalSettings::smallestReadableFont());
|
|
}
|
|
|
|
|
|
class WidgetExplorerPrivate
|
|
{
|
|
public:
|
|
WidgetExplorerPrivate(WidgetExplorer *w)
|
|
: q(w),
|
|
containment(nullptr),
|
|
mainLayout(nullptr),
|
|
filterEdit(nullptr),
|
|
topSpacer(nullptr),
|
|
categoriesButton(nullptr),
|
|
categoriesMenu(nullptr),
|
|
closeButton(nullptr),
|
|
scrollWidget(nullptr),
|
|
appletsWidget(nullptr),
|
|
appletsLayout(nullptr),
|
|
appletsPlaceholder(nullptr)
|
|
{
|
|
}
|
|
|
|
void init(Plasma::Location loc);
|
|
void updateApplets();
|
|
void updateRunningApplets();
|
|
void filterApplets(const QString &text);
|
|
void updateOrientation(const Qt::Orientation orientation);
|
|
|
|
void _k_appletAdded(Plasma::Applet *applet);
|
|
void _k_appletRemoved(Plasma::Applet *applet);
|
|
void _k_containmentDestroyed();
|
|
void _k_immutabilityChanged(const Plasma::ImmutabilityType type);
|
|
void _k_textChanged(const QString &text);
|
|
void _k_closePressed();
|
|
void _k_categoriesClicked();
|
|
void _k_menuTriggered(QAction *action);
|
|
void _k_menuAboutToHide();
|
|
void _k_addApplet(const QString &pluginName);
|
|
void _k_removeApplet(const QString &pluginName);
|
|
void _k_databaseChanged(const QStringList &resources);
|
|
|
|
Plasma::Location location;
|
|
WidgetExplorer* q;
|
|
Plasma::Containment* containment;
|
|
|
|
QMutex mutex;
|
|
QGraphicsGridLayout* mainLayout;
|
|
Plasma::LineEdit* filterEdit;
|
|
Plasma::Label* topSpacer;
|
|
Plasma::ToolButton* categoriesButton;
|
|
QMenu* categoriesMenu;
|
|
Plasma::ToolButton* closeButton;
|
|
Plasma::ScrollWidget* scrollWidget;
|
|
QGraphicsWidget* appletsWidget;
|
|
QGraphicsLinearLayout* appletsLayout;
|
|
QList<AppletFrame*> appletFrames;
|
|
Plasma::Label* appletsPlaceholder;
|
|
QMap<Plasma::Applet*,QString> runningApplets;
|
|
};
|
|
|
|
void WidgetExplorerPrivate::init(Plasma::Location loc)
|
|
{
|
|
q->setFocusPolicy(Qt::StrongFocus);
|
|
|
|
const Qt::Orientation orientation = kOrientationForLocation(location);
|
|
|
|
location = loc;
|
|
mainLayout = new QGraphicsGridLayout(q);
|
|
mainLayout->setContentsMargins(s_margin, s_margin, s_margin, s_margin);
|
|
mainLayout->setSpacing(s_margin);
|
|
|
|
filterEdit = new Plasma::LineEdit(q);
|
|
filterEdit->setClickMessage(i18n("Enter search term..."));
|
|
filterEdit->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum);
|
|
QSizeF filterEditMinimumSize = filterEdit->minimumSize();
|
|
filterEditMinimumSize.setWidth(s_filterwidth);
|
|
filterEdit->setMinimumSize(filterEditMinimumSize);
|
|
filterEdit->setMaximumSize(filterEditMinimumSize);
|
|
q->setFocusProxy(filterEdit);
|
|
q->connect(
|
|
filterEdit, SIGNAL(textChanged(QString)),
|
|
q, SLOT(_k_textChanged(QString))
|
|
);
|
|
mainLayout->addItem(filterEdit, 0, 0);
|
|
|
|
topSpacer = new Plasma::Label(q);
|
|
topSpacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
|
|
topSpacer->setMinimumSize(1, 1);
|
|
mainLayout->addItem(topSpacer, 0, 1);
|
|
|
|
categoriesButton = new Plasma::ToolButton(q);
|
|
categoriesButton->setText(i18n("All Widgets"));
|
|
q->connect(
|
|
categoriesButton, SIGNAL(clicked()),
|
|
q, SLOT(_k_categoriesClicked())
|
|
);
|
|
categoriesMenu = new QMenu();
|
|
q->connect(
|
|
categoriesMenu, SIGNAL(triggered(QAction*)),
|
|
q, SLOT(_k_menuTriggered(QAction*))
|
|
);
|
|
q->connect(
|
|
categoriesMenu, SIGNAL(aboutToHide()),
|
|
q, SLOT(_k_menuAboutToHide())
|
|
);
|
|
mainLayout->addItem(categoriesButton, 0, 2);
|
|
|
|
closeButton = new Plasma::ToolButton(q);
|
|
closeButton->setIcon(KIcon("window-close"));
|
|
q->connect(
|
|
closeButton, SIGNAL(pressed()),
|
|
q, SLOT(_k_closePressed())
|
|
);
|
|
mainLayout->addItem(closeButton, 0, 3);
|
|
|
|
scrollWidget = new Plasma::ScrollWidget(q);
|
|
scrollWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
|
|
scrollWidget->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
|
|
scrollWidget->setOverShoot(false);
|
|
scrollWidget->setOverflowBordersVisible(false);
|
|
scrollWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
|
appletsWidget = new QGraphicsWidget(scrollWidget);
|
|
appletsWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
|
appletsLayout = new QGraphicsLinearLayout(orientation, appletsWidget);
|
|
appletsPlaceholder = new Plasma::Label(appletsWidget);
|
|
appletsPlaceholder->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
|
appletsPlaceholder->setAlignment(Qt::AlignCenter);
|
|
appletsPlaceholder->setText(i18n("No applets found."));
|
|
appletsLayout->addItem(appletsPlaceholder);
|
|
appletsWidget->setLayout(appletsLayout);
|
|
scrollWidget->setWidget(appletsWidget);
|
|
mainLayout->addItem(scrollWidget, 1, 0, 1, 4);
|
|
|
|
updateOrientation(orientation);
|
|
|
|
q->setLayout(mainLayout);
|
|
|
|
q->connect(
|
|
KSycoca::self(), SIGNAL(databaseChanged(QStringList)),
|
|
q, SLOT(_k_databaseChanged(QStringList))
|
|
);
|
|
}
|
|
|
|
void WidgetExplorerPrivate::updateApplets()
|
|
{
|
|
filterEdit->setEnabled(false);
|
|
|
|
QMutexLocker locker(&mutex);
|
|
foreach (AppletFrame* appletFrame, appletFrames) {
|
|
appletsLayout->removeItem(appletFrame);
|
|
}
|
|
qDeleteAll(appletFrames);
|
|
appletFrames.clear();
|
|
|
|
QStringList appletCategories;
|
|
bool hasapplets = false;
|
|
const QString containmentsCategory = i18n("Containments");
|
|
foreach (const KPluginInfo &appletInfo, Plasma::Applet::listAppletInfo()) {
|
|
const QString appletCategory = appletInfo.category();
|
|
if (appletInfo.property("NoDisplay").toBool() || appletCategory == containmentsCategory) {
|
|
continue;
|
|
}
|
|
if (!appletCategory.isEmpty() && !appletCategories.contains(appletCategory)) {
|
|
appletCategories.append(appletCategory);
|
|
}
|
|
|
|
hasapplets = true;
|
|
AppletFrame* appletFrame = new AppletFrame(appletsWidget, appletInfo);
|
|
appletFrame->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
|
|
appletFrame->setMinimumSize(s_appletframesize);
|
|
appletFrame->setPreferredSize(s_appletframesize);
|
|
q->connect(
|
|
appletFrame, SIGNAL(addApplet(QString)),
|
|
q, SLOT(_k_addApplet(QString))
|
|
);
|
|
q->connect(
|
|
appletFrame, SIGNAL(removeApplet(QString)),
|
|
q, SLOT(_k_removeApplet(QString))
|
|
);
|
|
appletsLayout->addItem(appletFrame);
|
|
appletFrames.append(appletFrame);
|
|
}
|
|
|
|
appletsPlaceholder->setVisible(!hasapplets);
|
|
|
|
categoriesMenu->clear();
|
|
categoriesMenu->addAction(i18n("All Widgets"));
|
|
categoriesMenu->addAction(i18n("Running"));
|
|
categoriesMenu->addSeparator();
|
|
foreach (const QString &appletCategory, appletCategories) {
|
|
categoriesMenu->addAction(appletCategory);
|
|
}
|
|
|
|
filterEdit->setEnabled(true);
|
|
}
|
|
|
|
void WidgetExplorerPrivate::updateRunningApplets()
|
|
{
|
|
QMutexLocker locker(&mutex);
|
|
const QStringList running = runningApplets.values();
|
|
foreach (AppletFrame* appletFrame, appletFrames) {
|
|
appletFrame->setRunning(running.contains(appletFrame->pluginInfo().pluginName()));
|
|
}
|
|
}
|
|
|
|
void WidgetExplorerPrivate::filterApplets(const QString &text)
|
|
{
|
|
QMutexLocker locker(&mutex);
|
|
const QString categoriesButtonText = categoriesButton->text();
|
|
const bool allwidgets = (categoriesButtonText == i18n("All Widgets"));
|
|
const bool onlyrunning = (categoriesButtonText == i18n("Running"));
|
|
const QStringList running = runningApplets.values();
|
|
bool hasapplets = false;
|
|
foreach (AppletFrame* appletFrame, appletFrames) {
|
|
appletFrame->setVisible(false);
|
|
const KPluginInfo appletInfo = appletFrame->pluginInfo();
|
|
const QString appletPluginName = appletInfo.pluginName();
|
|
if (onlyrunning && !running.contains(appletPluginName)) {
|
|
continue;
|
|
}
|
|
if (!onlyrunning && !allwidgets && categoriesButtonText != appletInfo.category()) {
|
|
continue;
|
|
}
|
|
if (!text.isEmpty()) {
|
|
if (appletInfo.name().contains(text, Qt::CaseInsensitive)
|
|
|| appletPluginName.contains(text, Qt::CaseInsensitive)
|
|
|| appletInfo.comment().contains(text, Qt::CaseInsensitive))
|
|
{
|
|
appletFrame->setVisible(true);
|
|
hasapplets = true;
|
|
}
|
|
} else {
|
|
appletFrame->setVisible(true);
|
|
hasapplets = true;
|
|
}
|
|
}
|
|
appletsPlaceholder->setVisible(!hasapplets);
|
|
appletsPlaceholder->setText(
|
|
// NOTE: this uses translation from:
|
|
// kdelibs/kdeui/findreplace/kfind.cpp
|
|
text.isEmpty() ? i18n("No applets found.") : i18n("<qt>No matches found for '<b>%1</b>'.</qt>", text)
|
|
);
|
|
if (hasapplets) {
|
|
appletsWidget->adjustSize();
|
|
} else {
|
|
appletsWidget->resize(scrollWidget->size());
|
|
}
|
|
}
|
|
|
|
void WidgetExplorerPrivate::updateOrientation(const Qt::Orientation orientation)
|
|
{
|
|
appletsLayout->setOrientation(orientation);
|
|
topSpacer->setVisible(false);
|
|
mainLayout->removeItem(topSpacer);
|
|
categoriesButton->setVisible(false);
|
|
mainLayout->removeItem(categoriesButton);
|
|
if (orientation == Qt::Horizontal) {
|
|
filterEdit->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum);
|
|
mainLayout->addItem(topSpacer, 0, 1);
|
|
topSpacer->setVisible(true);
|
|
mainLayout->addItem(categoriesButton, 0, 2);
|
|
categoriesButton->setVisible(true);
|
|
} else {
|
|
filterEdit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
|
|
// TODO: put the categories button bellow the filter and close button
|
|
}
|
|
}
|
|
|
|
void WidgetExplorerPrivate::_k_textChanged(const QString &text)
|
|
{
|
|
filterApplets(text);
|
|
}
|
|
|
|
void WidgetExplorerPrivate::_k_categoriesClicked()
|
|
{
|
|
categoriesButton->setDown(true);
|
|
categoriesMenu->exec(QCursor::pos());
|
|
}
|
|
|
|
void WidgetExplorerPrivate::_k_menuTriggered(QAction *action)
|
|
{
|
|
categoriesButton->setText(action->text());
|
|
categoriesButton->setDown(false);
|
|
filterApplets(filterEdit->text());
|
|
}
|
|
|
|
void WidgetExplorerPrivate::_k_menuAboutToHide()
|
|
{
|
|
categoriesButton->setDown(false);
|
|
}
|
|
|
|
void WidgetExplorerPrivate::_k_closePressed()
|
|
{
|
|
emit q->closeClicked();
|
|
}
|
|
|
|
void WidgetExplorerPrivate::_k_addApplet(const QString &pluginName)
|
|
{
|
|
if (!containment) {
|
|
return;
|
|
}
|
|
containment->addApplet(pluginName);
|
|
}
|
|
|
|
void WidgetExplorerPrivate::_k_removeApplet(const QString &pluginName)
|
|
{
|
|
if (!containment) {
|
|
return;
|
|
}
|
|
Plasma::Corona *corona = containment->corona();
|
|
if (!corona) {
|
|
return;
|
|
}
|
|
QList<Containment*> containments = corona->containments();
|
|
foreach (Containment *containment, containments) {
|
|
foreach (Applet *applet, containment->applets()) {
|
|
if (applet->pluginName() == pluginName) {
|
|
applet->destroy();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void WidgetExplorerPrivate::_k_databaseChanged(const QStringList &resources)
|
|
{
|
|
if (resources.contains("services")) {
|
|
updateApplets();
|
|
filterApplets(filterEdit->text());
|
|
}
|
|
}
|
|
|
|
void WidgetExplorerPrivate::_k_appletAdded(Plasma::Applet *applet)
|
|
{
|
|
runningApplets.insert(applet, applet->pluginName());
|
|
updateRunningApplets();
|
|
filterApplets(filterEdit->text());
|
|
}
|
|
|
|
void WidgetExplorerPrivate::_k_appletRemoved(Plasma::Applet *applet)
|
|
{
|
|
runningApplets.remove(applet);
|
|
updateRunningApplets();
|
|
filterApplets(filterEdit->text());
|
|
}
|
|
|
|
void WidgetExplorerPrivate::_k_containmentDestroyed()
|
|
{
|
|
q->setContainment(nullptr);
|
|
}
|
|
|
|
void WidgetExplorerPrivate::_k_immutabilityChanged(const Plasma::ImmutabilityType type)
|
|
{
|
|
if (type != Plasma::Mutable) {
|
|
emit q->closeClicked();
|
|
}
|
|
}
|
|
|
|
WidgetExplorer::WidgetExplorer(const Plasma::Location loc, QGraphicsItem *parent)
|
|
: QGraphicsWidget(parent),
|
|
d(new WidgetExplorerPrivate(this))
|
|
{
|
|
d->init(loc);
|
|
}
|
|
|
|
WidgetExplorer::WidgetExplorer(QGraphicsItem *parent)
|
|
: QGraphicsWidget(parent),
|
|
d(new WidgetExplorerPrivate(this))
|
|
{
|
|
d->init(Plasma::BottomEdge);
|
|
}
|
|
|
|
WidgetExplorer::~WidgetExplorer()
|
|
{
|
|
if (d->containment) {
|
|
d->containment->disconnect(this);
|
|
}
|
|
foreach (AppletFrame* appletFrame, d->appletFrames) {
|
|
d->appletsLayout->removeItem(appletFrame);
|
|
}
|
|
qDeleteAll(d->appletFrames);
|
|
d->appletFrames.clear();
|
|
d->appletsLayout->removeItem(d->appletsPlaceholder);
|
|
delete d->appletsPlaceholder;
|
|
d->mainLayout->removeItem(d->filterEdit);
|
|
delete d->filterEdit;
|
|
d->mainLayout->removeItem(d->topSpacer);
|
|
delete d->topSpacer;
|
|
d->mainLayout->removeItem(d->categoriesButton);
|
|
delete d->categoriesButton;
|
|
delete d->categoriesMenu;
|
|
d->mainLayout->removeItem(d->closeButton);
|
|
delete d->closeButton;
|
|
delete d->appletsWidget;
|
|
delete d;
|
|
}
|
|
|
|
void WidgetExplorer::setLocation(const Plasma::Location loc)
|
|
{
|
|
d->location = loc;
|
|
d->updateOrientation(kOrientationForLocation(loc));
|
|
emit locationChanged(loc);
|
|
}
|
|
|
|
Plasma::Location WidgetExplorer::location() const
|
|
{
|
|
return d->location;
|
|
}
|
|
|
|
void WidgetExplorer::setContainment(Plasma::Containment *containment)
|
|
{
|
|
if (d->containment != containment) {
|
|
if (d->containment) {
|
|
d->containment->disconnect(this);
|
|
}
|
|
|
|
d->runningApplets.clear();
|
|
d->containment = containment;
|
|
|
|
if (d->containment) {
|
|
connect(
|
|
d->containment, SIGNAL(destroyed(QObject*)),
|
|
this, SLOT(_k_containmentDestroyed())
|
|
);
|
|
connect(
|
|
d->containment, SIGNAL(immutabilityChanged(Plasma::ImmutabilityType)),
|
|
this, SLOT(_k_immutabilityChanged(Plasma::ImmutabilityType))
|
|
);
|
|
|
|
setLocation(containment->location());
|
|
}
|
|
|
|
if (containment) {
|
|
Plasma::Corona *corona = containment->corona();
|
|
if (corona) {
|
|
QList<Containment*> containments = corona->containments();
|
|
foreach (Containment *containment, containments) {
|
|
connect(
|
|
containment, SIGNAL(appletAdded(Plasma::Applet*,QPointF)),
|
|
this, SLOT(_k_appletAdded(Plasma::Applet*))
|
|
);
|
|
connect(
|
|
containment, SIGNAL(appletRemoved(Plasma::Applet*)),
|
|
this, SLOT(_k_appletRemoved(Plasma::Applet*))
|
|
);
|
|
|
|
foreach (Applet *applet, containment->applets()) {
|
|
d->runningApplets.insert(applet, applet->pluginName());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
d->updateApplets();
|
|
d->updateRunningApplets();
|
|
d->filterApplets(d->filterEdit->text());
|
|
}
|
|
}
|
|
|
|
Containment* WidgetExplorer::containment() const
|
|
{
|
|
return d->containment;
|
|
}
|
|
|
|
void WidgetExplorer::keyPressEvent(QKeyEvent *event)
|
|
{
|
|
if (event->key() == Qt::Key_Escape) {
|
|
emit closeClicked();
|
|
event->accept();
|
|
return;
|
|
}
|
|
// arrow keys go to the scroll widget
|
|
switch (event->key()) {
|
|
case Qt::Key_Left:
|
|
case Qt::Key_Right:
|
|
case Qt::Key_Up:
|
|
case Qt::Key_Down: {
|
|
QApplication::sendEvent(d->scrollWidget, event);
|
|
return;
|
|
}
|
|
}
|
|
// if the scroll area or any other widget steals the focus the focus goes back to the filter
|
|
// widget tho
|
|
if (!d->filterEdit->hasFocus()) {
|
|
d->filterEdit->setFocus();
|
|
}
|
|
QApplication::sendEvent(d->filterEdit->nativeWidget(), event);
|
|
}
|
|
|
|
} // namespace Plasma
|
|
|
|
#include "moc_widgetexplorer.cpp"
|
|
#include "widgetexplorer.moc"
|