2024-04-12 03:33:58 +03:00
|
|
|
/*
|
|
|
|
This file is part of the KDE project
|
|
|
|
Copyright (C) 2024 Ivailo Monev <xakepa10@gmail.com>
|
|
|
|
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
|
|
modify it under the terms of the GNU Library General Public
|
|
|
|
License version 2, as published by the Free Software Foundation.
|
|
|
|
|
|
|
|
This library 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
|
|
|
|
Library General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU Library General Public License
|
|
|
|
along with this library; see the file COPYING.LIB. If not, write to
|
|
|
|
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
|
|
Boston, MA 02110-1301, USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "launcher.h"
|
|
|
|
#include "kworkspace/kworkspace.h"
|
|
|
|
#include "kworkspace/kdisplaymanager.h"
|
|
|
|
|
|
|
|
#include <QMutex>
|
|
|
|
#include <QGraphicsLinearLayout>
|
|
|
|
#include <QGraphicsGridLayout>
|
|
|
|
#include <QHostInfo>
|
|
|
|
#include <QDBusInterface>
|
|
|
|
#include <KUser>
|
|
|
|
#include <kdbusconnectionpool.h>
|
|
|
|
#include <KIcon>
|
|
|
|
#include <KIconLoader>
|
|
|
|
#include <KStandardDirs>
|
|
|
|
#include <KSycoca>
|
2024-04-12 19:29:16 +03:00
|
|
|
#include <KToolInvocation>
|
2024-04-12 03:33:58 +03:00
|
|
|
#include <KRun>
|
|
|
|
#include <KBookmarkManager>
|
|
|
|
#include <KServiceGroup>
|
|
|
|
#include <KDirWatch>
|
|
|
|
#include <KDesktopFile>
|
|
|
|
#include <KRecentDocument>
|
|
|
|
#include <Solid/PowerManagement>
|
|
|
|
#include <Plasma/IconWidget>
|
|
|
|
#include <Plasma/Separator>
|
|
|
|
#include <Plasma/Label>
|
|
|
|
#include <Plasma/LineEdit>
|
|
|
|
#include <Plasma/TabBar>
|
2024-04-15 01:08:52 +03:00
|
|
|
#include <Plasma/Frame>
|
2024-04-15 00:48:47 +03:00
|
|
|
#include <Plasma/SvgWidget>
|
|
|
|
#include <Plasma/ToolButton>
|
2024-04-12 03:33:58 +03:00
|
|
|
#include <Plasma/ScrollWidget>
|
|
|
|
#include <Plasma/RunnerManager>
|
2024-04-16 21:00:37 +03:00
|
|
|
#include <Plasma/Animation>
|
2024-04-12 03:33:58 +03:00
|
|
|
#include <KDebug>
|
|
|
|
|
2024-04-15 17:54:25 +03:00
|
|
|
// TODO: mime data for drag-n-drop, animated layout updates
|
2024-04-12 19:29:16 +03:00
|
|
|
|
2024-04-12 03:33:58 +03:00
|
|
|
static const QString s_defaultpopupicon = QString::fromLatin1("start-here-kde");
|
|
|
|
static const QSizeF s_minimumsize = QSizeF(450, 350);
|
|
|
|
static const QString s_firsttimeaddress = QString::fromLatin1("_k_firsttime");
|
|
|
|
static const QStringList s_firsttimeservices = QStringList()
|
|
|
|
<< QString::fromLatin1("konsole")
|
|
|
|
<< QString::fromLatin1("dolphin")
|
|
|
|
<< QString::fromLatin1("systemsettings");
|
2024-04-17 00:04:35 +03:00
|
|
|
static const QString s_usericon = QString::fromLatin1("user-identity");
|
2024-04-12 17:38:43 +03:00
|
|
|
static const QString s_genericicon = QString::fromLatin1("applications-other");
|
|
|
|
static const QString s_favoriteicon = QString::fromLatin1("bookmarks");
|
|
|
|
static const QString s_recenticon = QString::fromLatin1("document-open-recent");
|
2024-04-12 19:17:25 +03:00
|
|
|
static const int s_searchdelay = 500; // ms
|
2024-04-17 00:04:35 +03:00
|
|
|
static const int s_polltimeout = 5000; // ms
|
2024-04-12 03:33:58 +03:00
|
|
|
|
|
|
|
static QSizeF kIconSize()
|
|
|
|
{
|
|
|
|
const int iconsize = KIconLoader::global()->currentSize(KIconLoader::Desktop);
|
|
|
|
return QSizeF(iconsize, iconsize);
|
|
|
|
}
|
|
|
|
|
2024-04-15 00:48:47 +03:00
|
|
|
static QGraphicsWidget* kMakeSpacer(QGraphicsWidget *parent)
|
|
|
|
{
|
|
|
|
QGraphicsWidget* widget = new QGraphicsWidget(parent);
|
|
|
|
widget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
|
|
|
widget->setMinimumSize(0, 0);
|
2024-04-15 07:33:01 +03:00
|
|
|
widget->setPreferredSize(0, 0);
|
2024-04-17 21:41:42 +03:00
|
|
|
widget->setFlag(QGraphicsItem::ItemHasNoContents);
|
2024-04-15 00:48:47 +03:00
|
|
|
return widget;
|
|
|
|
}
|
|
|
|
|
2024-04-12 17:11:13 +03:00
|
|
|
static Plasma::ScrollWidget* kMakeScrollWidget(QGraphicsWidget *parent)
|
|
|
|
{
|
|
|
|
Plasma::ScrollWidget* scrollwidget = new Plasma::ScrollWidget(parent);
|
|
|
|
scrollwidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
|
|
|
return scrollwidget;
|
|
|
|
}
|
|
|
|
|
2024-04-13 15:35:55 +03:00
|
|
|
static void kRunService(const QString &entrypath, LauncherApplet* launcherapplet)
|
2024-04-12 17:11:13 +03:00
|
|
|
{
|
2024-04-13 15:35:55 +03:00
|
|
|
Q_ASSERT(launcherapplet != nullptr);
|
2024-04-14 10:34:13 +03:00
|
|
|
launcherapplet->resetState();
|
2024-04-13 15:35:55 +03:00
|
|
|
|
2024-04-12 17:11:13 +03:00
|
|
|
KService::Ptr service = KService::serviceByDesktopPath(entrypath);
|
|
|
|
Q_ASSERT(!service.isNull());
|
|
|
|
if (!KRun::run(*service.data(), KUrl::List(), nullptr)) {
|
|
|
|
kWarning() << "could not run" << entrypath;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-04-13 15:35:55 +03:00
|
|
|
static void kRunUrl(const QString &urlpath, LauncherApplet* launcherapplet)
|
2024-04-12 18:23:04 +03:00
|
|
|
{
|
2024-04-13 15:35:55 +03:00
|
|
|
Q_ASSERT(launcherapplet != nullptr);
|
2024-04-14 10:34:13 +03:00
|
|
|
launcherapplet->resetState();
|
2024-04-13 15:35:55 +03:00
|
|
|
|
2024-04-12 18:23:04 +03:00
|
|
|
(void)new KRun(KUrl(urlpath), nullptr);
|
|
|
|
}
|
|
|
|
|
2024-04-15 05:23:22 +03:00
|
|
|
static KIcon kGenericIcon(const QString &name)
|
2024-04-12 17:38:43 +03:00
|
|
|
{
|
|
|
|
if (!name.isEmpty()) {
|
2024-04-15 05:23:22 +03:00
|
|
|
return KIcon(name);
|
2024-04-12 17:38:43 +03:00
|
|
|
}
|
2024-04-15 05:23:22 +03:00
|
|
|
return KIcon(s_genericicon);
|
2024-04-12 17:38:43 +03:00
|
|
|
}
|
|
|
|
|
2024-04-15 05:23:22 +03:00
|
|
|
static KIcon kFavoriteIcon(const QString &name)
|
2024-04-12 17:38:43 +03:00
|
|
|
{
|
|
|
|
if (!name.isEmpty()) {
|
2024-04-15 05:23:22 +03:00
|
|
|
return KIcon(name);
|
2024-04-12 17:38:43 +03:00
|
|
|
}
|
2024-04-15 05:23:22 +03:00
|
|
|
return KIcon(s_favoriteicon);
|
2024-04-12 17:38:43 +03:00
|
|
|
}
|
|
|
|
|
2024-04-15 05:23:22 +03:00
|
|
|
static KIcon kRecentIcon(const QString &name)
|
2024-04-12 17:38:43 +03:00
|
|
|
{
|
|
|
|
if (!name.isEmpty()) {
|
2024-04-15 05:23:22 +03:00
|
|
|
return KIcon(name);
|
2024-04-12 17:38:43 +03:00
|
|
|
}
|
2024-04-15 05:23:22 +03:00
|
|
|
return KIcon(s_recenticon);
|
2024-04-12 17:38:43 +03:00
|
|
|
}
|
|
|
|
|
2024-04-12 03:33:58 +03:00
|
|
|
static void kLockScreen()
|
|
|
|
{
|
|
|
|
QDBusInterface screensaver(
|
|
|
|
"org.freedesktop.ScreenSaver", "/ScreenSaver", "org.freedesktop.ScreenSaver",
|
|
|
|
QDBusConnection::sessionBus()
|
|
|
|
);
|
|
|
|
screensaver.call("Lock");
|
|
|
|
}
|
|
|
|
|
2024-04-14 11:58:56 +03:00
|
|
|
static QStringList kAllowedRunners(KConfigGroup configgroup)
|
|
|
|
{
|
|
|
|
QStringList result;
|
|
|
|
foreach (KPluginInfo &plugin, Plasma::RunnerManager::listRunnerInfo()) {
|
|
|
|
plugin.load(configgroup);
|
|
|
|
if (plugin.isPluginEnabled()) {
|
|
|
|
result.append(plugin.pluginName());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// qDebug() << Q_FUNC_INFO << result << configgroup.name();
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2024-04-15 05:23:22 +03:00
|
|
|
class LauncherWidget : public QGraphicsWidget
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
public:
|
|
|
|
LauncherWidget(QGraphicsWidget *parent);
|
|
|
|
|
|
|
|
void setup(const QSizeF &iconsize, const QIcon &icon, const QString &text, const QString &subtext);
|
|
|
|
void disableHover();
|
2024-04-16 21:00:37 +03:00
|
|
|
void disableAnimations();
|
2024-04-15 05:23:22 +03:00
|
|
|
|
|
|
|
QString data() const;
|
|
|
|
void setData(const QString &data);
|
|
|
|
|
|
|
|
void addAction(QAction *action);
|
2024-04-15 17:54:25 +03:00
|
|
|
void removeAction(const int action);
|
2024-04-15 05:23:22 +03:00
|
|
|
|
|
|
|
Q_SIGNALS:
|
|
|
|
void activated();
|
|
|
|
|
|
|
|
private Q_SLOTS:
|
|
|
|
void slotUpdateFonts();
|
|
|
|
|
2024-04-16 21:00:37 +03:00
|
|
|
protected:
|
|
|
|
void hoverEnterEvent(QGraphicsSceneHoverEvent *event) final;
|
|
|
|
void hoverLeaveEvent(QGraphicsSceneHoverEvent *event) final;
|
|
|
|
|
2024-04-15 05:23:22 +03:00
|
|
|
private:
|
2024-04-16 21:00:37 +03:00
|
|
|
void animateFadeIn(Plasma::Animation *animation, Plasma::ToolButton *toolbutton);
|
|
|
|
void animateFadeOut(Plasma::Animation *animation, Plasma::ToolButton *toolbutton);
|
|
|
|
|
2024-04-15 05:23:22 +03:00
|
|
|
QGraphicsLinearLayout* m_layout;
|
|
|
|
Plasma::IconWidget* m_iconwidget;
|
|
|
|
QGraphicsLinearLayout* m_textlayout;
|
|
|
|
Plasma::Label* m_textwidget;
|
|
|
|
Plasma::Label* m_subtextwidget;
|
2024-04-15 17:54:25 +03:00
|
|
|
QGraphicsGridLayout* m_actionslayout;
|
|
|
|
Plasma::ToolButton* m_action1widget;
|
|
|
|
Plasma::ToolButton* m_action2widget;
|
|
|
|
Plasma::ToolButton* m_action3widget;
|
|
|
|
Plasma::ToolButton* m_action4widget;
|
2024-04-15 05:23:22 +03:00
|
|
|
QString m_data;
|
2024-04-15 06:06:57 +03:00
|
|
|
int m_actioncounter;
|
2024-04-16 21:00:37 +03:00
|
|
|
Plasma::Animation* m_action1animation;
|
|
|
|
Plasma::Animation* m_action2animation;
|
|
|
|
Plasma::Animation* m_action3animation;
|
|
|
|
Plasma::Animation* m_action4animation;
|
2024-04-15 05:23:22 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
LauncherWidget::LauncherWidget(QGraphicsWidget *parent)
|
|
|
|
: QGraphicsWidget(parent),
|
|
|
|
m_layout(nullptr),
|
|
|
|
m_iconwidget(nullptr),
|
|
|
|
m_textlayout(nullptr),
|
|
|
|
m_textwidget(nullptr),
|
|
|
|
m_subtextwidget(nullptr),
|
|
|
|
m_actionslayout(nullptr),
|
|
|
|
m_action1widget(nullptr),
|
|
|
|
m_action2widget(nullptr),
|
|
|
|
m_action3widget(nullptr),
|
2024-04-15 06:06:57 +03:00
|
|
|
m_action4widget(nullptr),
|
2024-04-16 21:25:06 +03:00
|
|
|
m_actioncounter(0),
|
2024-04-16 21:00:37 +03:00
|
|
|
m_action1animation(nullptr),
|
|
|
|
m_action2animation(nullptr),
|
|
|
|
m_action3animation(nullptr),
|
2024-04-16 21:25:06 +03:00
|
|
|
m_action4animation(nullptr)
|
2024-04-15 05:23:22 +03:00
|
|
|
{
|
2024-04-16 21:00:37 +03:00
|
|
|
setAcceptHoverEvents(true);
|
|
|
|
|
2024-04-15 05:23:22 +03:00
|
|
|
m_layout = new QGraphicsLinearLayout(Qt::Horizontal, this);
|
|
|
|
setLayout(m_layout);
|
|
|
|
|
|
|
|
m_iconwidget = new Plasma::IconWidget(this);
|
|
|
|
m_layout->addItem(m_iconwidget);
|
|
|
|
connect(
|
|
|
|
m_iconwidget, SIGNAL(activated()),
|
|
|
|
this, SIGNAL(activated())
|
|
|
|
);
|
|
|
|
|
|
|
|
m_textlayout = new QGraphicsLinearLayout(Qt::Vertical, m_layout);
|
|
|
|
m_textlayout->setContentsMargins(6, 6, 6, 6);
|
|
|
|
m_layout->addItem(m_textlayout);
|
|
|
|
m_layout->setStretchFactor(m_textlayout, 100);
|
|
|
|
m_textwidget = new Plasma::Label(this);
|
|
|
|
m_textwidget->setWordWrap(false);
|
|
|
|
m_textlayout->addItem(m_textwidget);
|
|
|
|
m_subtextwidget = new Plasma::Label(this);
|
|
|
|
m_subtextwidget->setWordWrap(false);
|
|
|
|
m_textlayout->addItem(m_subtextwidget);
|
|
|
|
|
2024-04-15 17:54:25 +03:00
|
|
|
m_actionslayout = new QGraphicsGridLayout(m_layout);
|
2024-04-15 05:23:22 +03:00
|
|
|
m_layout->addItem(m_actionslayout);
|
2024-04-15 17:54:25 +03:00
|
|
|
m_action1widget = new Plasma::ToolButton(this);
|
|
|
|
m_action1widget->setVisible(false);
|
|
|
|
m_actionslayout->addItem(m_action1widget, 0, 0);
|
|
|
|
m_action2widget = new Plasma::ToolButton(this);
|
|
|
|
m_action2widget->setVisible(false);
|
|
|
|
m_actionslayout->addItem(m_action2widget, 1, 0);
|
|
|
|
m_action3widget = new Plasma::ToolButton(this);
|
|
|
|
m_action3widget->setVisible(false);
|
|
|
|
m_actionslayout->addItem(m_action3widget, 0, 1);
|
|
|
|
m_action4widget = new Plasma::ToolButton(this);
|
|
|
|
m_action4widget->setVisible(false);
|
|
|
|
m_actionslayout->addItem(m_action4widget, 1, 1);
|
2024-04-15 05:23:22 +03:00
|
|
|
|
|
|
|
slotUpdateFonts();
|
|
|
|
connect(
|
|
|
|
KGlobalSettings::self(), SIGNAL(kdisplayFontChanged()),
|
|
|
|
this, SLOT(slotUpdateFonts())
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
void LauncherWidget::setup(const QSizeF &iconsize, const QIcon &icon, const QString &text, const QString &subtext)
|
|
|
|
{
|
|
|
|
m_iconwidget->setMinimumIconSize(iconsize);
|
|
|
|
m_iconwidget->setIcon(icon);
|
|
|
|
m_textwidget->setText(text);
|
|
|
|
m_subtextwidget->setText(subtext);
|
|
|
|
m_subtextwidget->setVisible(!subtext.isEmpty());
|
|
|
|
}
|
|
|
|
|
|
|
|
void LauncherWidget::disableHover()
|
|
|
|
{
|
|
|
|
m_iconwidget->setAcceptHoverEvents(false);
|
|
|
|
m_iconwidget->setAcceptedMouseButtons(Qt::NoButton);
|
|
|
|
}
|
|
|
|
|
2024-04-16 21:00:37 +03:00
|
|
|
void LauncherWidget::disableAnimations()
|
|
|
|
{
|
|
|
|
setAcceptHoverEvents(false);
|
|
|
|
}
|
|
|
|
|
2024-04-15 05:23:22 +03:00
|
|
|
QString LauncherWidget::data() const
|
|
|
|
{
|
|
|
|
return m_data;
|
|
|
|
}
|
|
|
|
|
|
|
|
void LauncherWidget::setData(const QString &data)
|
|
|
|
{
|
|
|
|
m_data = data;
|
|
|
|
}
|
|
|
|
|
|
|
|
void LauncherWidget::addAction(QAction *action)
|
|
|
|
{
|
2024-04-15 07:56:45 +03:00
|
|
|
// qDebug() << Q_FUNC_INFO << m_actioncounter << action;
|
2024-04-15 16:14:29 +03:00
|
|
|
// 4 actions are packed into a small area, the text is getting in the way. however if there is
|
2024-04-15 08:03:15 +03:00
|
|
|
// no tooltip use the text as tooltip
|
|
|
|
if (action->toolTip().isEmpty() && !action->text().isEmpty()) {
|
|
|
|
action->setToolTip(action->text());
|
|
|
|
}
|
2024-04-15 06:06:57 +03:00
|
|
|
action->setText(QString());
|
|
|
|
if (action->icon().isNull()) {
|
|
|
|
kWarning() << "action does not have icon" << action;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
switch (m_actioncounter) {
|
|
|
|
case 0: {
|
2024-04-15 17:54:25 +03:00
|
|
|
m_action1widget->setVisible(true);
|
2024-04-16 21:00:37 +03:00
|
|
|
m_action1widget->setOpacity(0.0);
|
2024-04-15 06:06:57 +03:00
|
|
|
m_action1widget->setAction(action);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 1: {
|
2024-04-15 17:54:25 +03:00
|
|
|
m_action2widget->setVisible(true);
|
2024-04-16 21:00:37 +03:00
|
|
|
m_action2widget->setOpacity(0.0);
|
2024-04-15 06:06:57 +03:00
|
|
|
m_action2widget->setAction(action);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 2: {
|
2024-04-15 17:54:25 +03:00
|
|
|
m_action3widget->setVisible(true);
|
2024-04-16 21:00:37 +03:00
|
|
|
m_action3widget->setOpacity(0.0);
|
2024-04-15 06:06:57 +03:00
|
|
|
m_action3widget->setAction(action);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 3: {
|
2024-04-15 17:54:25 +03:00
|
|
|
m_action4widget->setVisible(true);
|
2024-04-16 21:00:37 +03:00
|
|
|
m_action4widget->setOpacity(0.0);
|
2024-04-15 06:06:57 +03:00
|
|
|
m_action4widget->setAction(action);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default: {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
m_actioncounter++;
|
2024-04-15 05:23:22 +03:00
|
|
|
}
|
|
|
|
|
2024-04-15 17:54:25 +03:00
|
|
|
void LauncherWidget::removeAction(const int actionnumber)
|
|
|
|
{
|
|
|
|
QAction* action = nullptr;
|
|
|
|
switch (actionnumber) {
|
|
|
|
case 0: {
|
|
|
|
m_action1widget->setVisible(false);
|
|
|
|
action = m_action1widget->action();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 1: {
|
|
|
|
m_action2widget->setVisible(false);
|
|
|
|
action = m_action2widget->action();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 2: {
|
|
|
|
m_action3widget->setVisible(false);
|
|
|
|
action = m_action3widget->action();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 3: {
|
|
|
|
m_action4widget->setVisible(false);
|
|
|
|
action = m_action4widget->action();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default: {
|
|
|
|
kWarning() << "invalid action number" << action;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (action) {
|
|
|
|
action->deleteLater();
|
|
|
|
if (m_actioncounter > 0) {
|
|
|
|
m_actioncounter--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-04-16 21:00:37 +03:00
|
|
|
void LauncherWidget::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
|
|
|
|
{
|
|
|
|
animateFadeIn(m_action1animation, m_action1widget);
|
|
|
|
animateFadeIn(m_action2animation, m_action2widget);
|
|
|
|
animateFadeIn(m_action3animation, m_action3widget);
|
|
|
|
animateFadeIn(m_action4animation, m_action4widget);
|
|
|
|
}
|
|
|
|
|
|
|
|
void LauncherWidget::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
|
|
|
|
{
|
|
|
|
animateFadeOut(m_action1animation, m_action1widget);
|
|
|
|
animateFadeOut(m_action2animation, m_action2widget);
|
|
|
|
animateFadeOut(m_action3animation, m_action3widget);
|
|
|
|
animateFadeOut(m_action4animation, m_action4widget);
|
|
|
|
}
|
|
|
|
|
|
|
|
void LauncherWidget::animateFadeIn(Plasma::Animation *animation, Plasma::ToolButton *toolbutton)
|
|
|
|
{
|
|
|
|
if (!toolbutton->isVisible()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (animation) {
|
|
|
|
animation->stop();
|
2024-04-17 21:17:06 +03:00
|
|
|
} else {
|
|
|
|
animation = Plasma::Animator::create(Plasma::Animator::FadeAnimation, this);
|
2024-04-16 21:00:37 +03:00
|
|
|
Q_ASSERT(animation != nullptr);
|
|
|
|
animation->setTargetWidget(toolbutton);
|
|
|
|
}
|
|
|
|
animation->setProperty("startOpacity", 0.0);
|
|
|
|
animation->setProperty("targetOpacity", 1.0);
|
|
|
|
animation->start(QAbstractAnimation::KeepWhenStopped);
|
|
|
|
}
|
|
|
|
|
|
|
|
void LauncherWidget::animateFadeOut(Plasma::Animation *animation, Plasma::ToolButton *toolbutton)
|
|
|
|
{
|
|
|
|
if (!toolbutton->isVisible()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (animation) {
|
|
|
|
animation->stop();
|
2024-04-17 21:17:06 +03:00
|
|
|
} else {
|
|
|
|
animation = Plasma::Animator::create(Plasma::Animator::FadeAnimation, this);
|
2024-04-16 21:00:37 +03:00
|
|
|
Q_ASSERT(animation != nullptr);
|
|
|
|
animation->setTargetWidget(toolbutton);
|
|
|
|
}
|
|
|
|
animation->setProperty("startOpacity", 1.0);
|
|
|
|
animation->setProperty("targetOpacity", 0.0);
|
|
|
|
animation->start(QAbstractAnimation::KeepWhenStopped);
|
|
|
|
}
|
|
|
|
|
2024-04-15 05:23:22 +03:00
|
|
|
void LauncherWidget::slotUpdateFonts()
|
|
|
|
{
|
|
|
|
QFont textfont = KGlobalSettings::generalFont();
|
|
|
|
textfont.setBold(true);
|
|
|
|
m_textwidget->setFont(textfont);
|
|
|
|
QFont subtextfont = KGlobalSettings::smallestReadableFont();
|
|
|
|
subtextfont.setItalic(true);
|
|
|
|
m_subtextwidget->setFont(subtextfont);
|
|
|
|
}
|
|
|
|
|
2024-04-12 03:33:58 +03:00
|
|
|
class LauncherSearch : public QGraphicsWidget
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
public:
|
2024-04-14 10:34:13 +03:00
|
|
|
LauncherSearch(QGraphicsWidget *parent, LauncherApplet *launcherapplet);
|
2024-04-12 03:33:58 +03:00
|
|
|
|
2024-04-14 11:58:56 +03:00
|
|
|
void setAllowedRunners(const QStringList &runners);
|
2024-04-12 03:33:58 +03:00
|
|
|
void prepare();
|
|
|
|
void query(const QString &text);
|
|
|
|
void finish();
|
|
|
|
|
|
|
|
private Q_SLOTS:
|
|
|
|
void slotUpdateLayout(const QList<Plasma::QueryMatch> &matches);
|
|
|
|
void slotTriggered();
|
2024-04-15 06:06:57 +03:00
|
|
|
void slotActivated();
|
2024-04-12 03:33:58 +03:00
|
|
|
|
|
|
|
private:
|
|
|
|
QMutex m_mutex;
|
2024-04-14 10:34:13 +03:00
|
|
|
LauncherApplet* m_launcherapplet;
|
2024-04-12 03:33:58 +03:00
|
|
|
QGraphicsLinearLayout* m_layout;
|
2024-04-15 05:23:22 +03:00
|
|
|
QList<LauncherWidget*> m_launcherwidgets;
|
2024-04-12 03:33:58 +03:00
|
|
|
Plasma::Label* m_label;
|
|
|
|
Plasma::RunnerManager* m_runnermanager;
|
|
|
|
};
|
|
|
|
|
2024-04-14 10:34:13 +03:00
|
|
|
LauncherSearch::LauncherSearch(QGraphicsWidget *parent, LauncherApplet *launcherapplet)
|
2024-04-12 03:33:58 +03:00
|
|
|
: QGraphicsWidget(parent),
|
2024-04-14 10:34:13 +03:00
|
|
|
m_launcherapplet(launcherapplet),
|
2024-04-12 03:33:58 +03:00
|
|
|
m_layout(nullptr),
|
|
|
|
m_label(nullptr),
|
|
|
|
m_runnermanager(nullptr)
|
|
|
|
{
|
|
|
|
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
|
|
|
m_layout = new QGraphicsLinearLayout(Qt::Vertical, this);
|
|
|
|
setLayout(m_layout);
|
|
|
|
|
|
|
|
m_label = new Plasma::Label(this);
|
|
|
|
m_label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
|
|
|
m_label->setAlignment(Qt::AlignCenter);
|
|
|
|
m_label->setText(i18n("No matches found"));
|
|
|
|
m_layout->addItem(m_label);
|
|
|
|
|
|
|
|
m_runnermanager = new Plasma::RunnerManager(this);
|
|
|
|
connect(
|
|
|
|
m_runnermanager, SIGNAL(matchesChanged(QList<Plasma::QueryMatch>)),
|
|
|
|
this, SLOT(slotUpdateLayout(QList<Plasma::QueryMatch>))
|
|
|
|
);
|
2024-04-16 23:27:44 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void LauncherSearch::setAllowedRunners(const QStringList &runners)
|
|
|
|
{
|
2024-04-14 11:58:56 +03:00
|
|
|
m_runnermanager->setAllowedRunners(runners);
|
2024-04-12 03:33:58 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void LauncherSearch::prepare()
|
|
|
|
{
|
|
|
|
// qDebug() << Q_FUNC_INFO;
|
|
|
|
QMutexLocker locker(&m_mutex);
|
2024-04-15 05:23:22 +03:00
|
|
|
foreach (LauncherWidget* launcherwidget, m_launcherwidgets) {
|
|
|
|
m_layout->removeItem(launcherwidget);
|
2024-04-12 03:33:58 +03:00
|
|
|
}
|
2024-04-15 05:23:22 +03:00
|
|
|
qDeleteAll(m_launcherwidgets);
|
|
|
|
m_launcherwidgets.clear();
|
2024-04-12 03:33:58 +03:00
|
|
|
|
|
|
|
m_label->setVisible(true);
|
|
|
|
adjustSize();
|
|
|
|
|
|
|
|
m_runnermanager->reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
void LauncherSearch::query(const QString &text)
|
|
|
|
{
|
|
|
|
// qDebug() << Q_FUNC_INFO << text;
|
|
|
|
m_runnermanager->launchQuery(text);
|
|
|
|
}
|
|
|
|
|
|
|
|
void LauncherSearch::finish()
|
|
|
|
{
|
|
|
|
// qDebug() << Q_FUNC_INFO;
|
|
|
|
m_runnermanager->matchSessionComplete();
|
|
|
|
}
|
|
|
|
|
|
|
|
void LauncherSearch::slotUpdateLayout(const QList<Plasma::QueryMatch> &matches)
|
|
|
|
{
|
|
|
|
// qDebug() << Q_FUNC_INFO;
|
|
|
|
QMutexLocker locker(&m_mutex);
|
2024-04-12 19:17:25 +03:00
|
|
|
m_label->setVisible(matches.isEmpty());
|
2024-04-12 03:33:58 +03:00
|
|
|
adjustSize();
|
|
|
|
|
|
|
|
const QSizeF iconsize = kIconSize();
|
|
|
|
foreach (const Plasma::QueryMatch &match, matches) {
|
|
|
|
// qDebug() << Q_FUNC_INFO << match.text() << match.subtext();
|
2024-04-15 05:23:22 +03:00
|
|
|
LauncherWidget* launcherwidget = new LauncherWidget(this);
|
|
|
|
launcherwidget->setup(
|
|
|
|
iconsize, match.icon(), match.text(), match.subtext()
|
2024-04-12 03:33:58 +03:00
|
|
|
);
|
2024-04-15 05:23:22 +03:00
|
|
|
launcherwidget->setData(match.id());
|
2024-04-17 23:13:09 +03:00
|
|
|
if (!match.isEnabled()) {
|
2024-04-15 05:23:22 +03:00
|
|
|
launcherwidget->disableHover();
|
2024-04-12 03:33:58 +03:00
|
|
|
}
|
2024-04-16 21:25:06 +03:00
|
|
|
int counter = 0;
|
2024-04-15 06:06:57 +03:00
|
|
|
const QList<QAction*> matchactions = m_runnermanager->actionsForMatch(match);
|
|
|
|
// qDebug() << Q_FUNC_INFO << match.id() << matchactions.size();
|
|
|
|
foreach (QAction* action, matchactions) {
|
|
|
|
action->setProperty("_k_id", match.id());
|
2024-04-15 05:23:22 +03:00
|
|
|
launcherwidget->addAction(action);
|
2024-04-15 06:06:57 +03:00
|
|
|
connect(
|
|
|
|
action, SIGNAL(triggered()),
|
|
|
|
this, SLOT(slotTriggered())
|
|
|
|
);
|
2024-04-12 17:11:13 +03:00
|
|
|
counter++;
|
2024-04-12 03:33:58 +03:00
|
|
|
if (counter >= 4) {
|
2024-04-15 06:06:57 +03:00
|
|
|
kWarning() << "the limit of LauncherWidget actions has been reached" << matchactions.size();
|
2024-04-12 03:33:58 +03:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2024-04-15 05:23:22 +03:00
|
|
|
m_launcherwidgets.append(launcherwidget);
|
|
|
|
m_layout->addItem(launcherwidget);
|
2024-04-12 03:33:58 +03:00
|
|
|
connect(
|
2024-04-15 05:23:22 +03:00
|
|
|
launcherwidget, SIGNAL(activated()),
|
2024-04-12 03:33:58 +03:00
|
|
|
this, SLOT(slotActivated())
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void LauncherSearch::slotTriggered()
|
|
|
|
{
|
2024-04-15 06:06:57 +03:00
|
|
|
QAction* matchaction = qobject_cast<QAction*>(sender());
|
|
|
|
const QString matchid = matchaction->property("_k_id").toString();
|
|
|
|
foreach (Plasma::QueryMatch match, m_runnermanager->matches()) {
|
|
|
|
if (match.id() == matchid) {
|
|
|
|
match.setSelectedAction(matchaction);
|
|
|
|
m_launcherapplet->resetState();
|
|
|
|
m_runnermanager->run(match);
|
|
|
|
return;
|
|
|
|
}
|
2024-04-12 03:33:58 +03:00
|
|
|
}
|
2024-04-15 06:06:57 +03:00
|
|
|
kWarning() << "could not find match for" << matchid;
|
2024-04-12 03:33:58 +03:00
|
|
|
}
|
|
|
|
|
2024-04-15 06:06:57 +03:00
|
|
|
void LauncherSearch::slotActivated()
|
|
|
|
{
|
|
|
|
LauncherWidget* launcherwidget = qobject_cast<LauncherWidget*>(sender());
|
|
|
|
m_launcherapplet->resetState();
|
|
|
|
m_runnermanager->run(launcherwidget->data());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2024-04-12 03:33:58 +03:00
|
|
|
class LauncherFavorites : public QGraphicsWidget
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
public:
|
2024-04-13 15:35:55 +03:00
|
|
|
LauncherFavorites(QGraphicsWidget *parent, LauncherApplet* launcherapplet);
|
2024-04-12 03:33:58 +03:00
|
|
|
|
|
|
|
private Q_SLOTS:
|
|
|
|
void slotUpdateLayout();
|
|
|
|
void slotActivated();
|
2024-04-15 07:56:45 +03:00
|
|
|
void slotTriggered();
|
2024-04-12 03:33:58 +03:00
|
|
|
|
|
|
|
private:
|
|
|
|
QMutex m_mutex;
|
2024-04-13 15:35:55 +03:00
|
|
|
LauncherApplet* m_launcherapplet;
|
2024-04-15 17:54:25 +03:00
|
|
|
KBookmarkManager* m_bookmarkmanager;
|
2024-04-12 03:33:58 +03:00
|
|
|
QGraphicsLinearLayout* m_layout;
|
2024-04-15 05:23:22 +03:00
|
|
|
QList<LauncherWidget*> m_launcherwidgets;
|
2024-04-12 03:33:58 +03:00
|
|
|
};
|
|
|
|
|
2024-04-13 15:35:55 +03:00
|
|
|
LauncherFavorites::LauncherFavorites(QGraphicsWidget *parent, LauncherApplet* launcherapplet)
|
2024-04-12 03:33:58 +03:00
|
|
|
: QGraphicsWidget(parent),
|
2024-04-13 15:35:55 +03:00
|
|
|
m_launcherapplet(launcherapplet),
|
2024-04-15 17:54:25 +03:00
|
|
|
m_bookmarkmanager(launcherapplet->bookmarkManager()),
|
|
|
|
m_layout(nullptr)
|
2024-04-12 03:33:58 +03:00
|
|
|
{
|
|
|
|
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
|
|
|
m_layout = new QGraphicsLinearLayout(Qt::Vertical, this);
|
|
|
|
setLayout(m_layout);
|
|
|
|
|
|
|
|
slotUpdateLayout();
|
|
|
|
connect(
|
|
|
|
m_bookmarkmanager, SIGNAL(changed(QString,QString)),
|
|
|
|
this, SLOT(slotUpdateLayout())
|
|
|
|
);
|
2024-04-15 07:56:45 +03:00
|
|
|
connect(
|
|
|
|
m_bookmarkmanager, SIGNAL(bookmarksChanged(QString)),
|
|
|
|
this, SLOT(slotUpdateLayout())
|
|
|
|
);
|
2024-04-12 03:33:58 +03:00
|
|
|
connect(
|
|
|
|
KSycoca::self(), SIGNAL(databaseChanged(QStringList)),
|
|
|
|
this, SLOT(slotUpdateLayout())
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
void LauncherFavorites::slotUpdateLayout()
|
|
|
|
{
|
|
|
|
QMutexLocker locker(&m_mutex);
|
2024-04-15 05:23:22 +03:00
|
|
|
foreach (LauncherWidget* launcherwidget, m_launcherwidgets) {
|
|
|
|
m_layout->removeItem(launcherwidget);
|
2024-04-12 03:33:58 +03:00
|
|
|
}
|
2024-04-15 05:23:22 +03:00
|
|
|
qDeleteAll(m_launcherwidgets);
|
|
|
|
m_launcherwidgets.clear();
|
2024-04-12 03:33:58 +03:00
|
|
|
|
|
|
|
adjustSize();
|
|
|
|
|
|
|
|
bool isfirsttime = true;
|
|
|
|
KBookmarkGroup bookmarkgroup = m_bookmarkmanager->root();
|
|
|
|
// first time gets a special treatment
|
|
|
|
KBookmark bookmark = bookmarkgroup.first();
|
|
|
|
while (!bookmark.isNull()) {
|
|
|
|
if (bookmark.url().url() == s_firsttimeaddress) {
|
|
|
|
isfirsttime = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
bookmark = bookmarkgroup.next(bookmark);
|
|
|
|
}
|
|
|
|
if (isfirsttime) {
|
|
|
|
bookmark = bookmarkgroup.createNewSeparator();
|
|
|
|
bookmark.setUrl(s_firsttimeaddress);
|
|
|
|
bookmark.setDescription("internal bookmark");
|
|
|
|
foreach (const QString &name, s_firsttimeservices) {
|
|
|
|
KService::Ptr service = KService::serviceByDesktopName(name);
|
|
|
|
if (!service.isNull()) {
|
|
|
|
bookmarkgroup.addBookmark(service->desktopEntryName(), KUrl(service->entryPath()), service->icon());
|
|
|
|
} else {
|
|
|
|
kWarning() << "invalid first-time serivce" << name;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
m_bookmarkmanager->emitChanged(bookmarkgroup);
|
|
|
|
}
|
|
|
|
|
|
|
|
const QSizeF iconsize = kIconSize();
|
|
|
|
bookmark = bookmarkgroup.first();
|
|
|
|
while (!bookmark.isNull()) {
|
|
|
|
// qDebug() << Q_FUNC_INFO << bookmark.text() << bookmark.description() << bookmark.icon() << bookmark.url();
|
|
|
|
if (bookmark.isSeparator()) {
|
|
|
|
bookmark = bookmarkgroup.next(bookmark);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
const QString serviceentrypath = bookmark.url().url();
|
|
|
|
KService::Ptr service = KService::serviceByDesktopPath(serviceentrypath);
|
|
|
|
if (service.isNull()) {
|
|
|
|
service = KService::serviceByDesktopName(bookmark.text());
|
|
|
|
}
|
|
|
|
if (service.isNull()) {
|
|
|
|
kWarning() << "could not find service for" << serviceentrypath;
|
|
|
|
bookmark = bookmarkgroup.next(bookmark);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
// qDebug() << Q_FUNC_INFO << service->entryPath() << service->name() << service->comment();
|
2024-04-15 05:23:22 +03:00
|
|
|
LauncherWidget* launcherwidget = new LauncherWidget(this);
|
|
|
|
launcherwidget->setup(
|
|
|
|
iconsize, kFavoriteIcon(service->icon()), service->name(), service->genericName()
|
2024-04-12 03:33:58 +03:00
|
|
|
);
|
2024-04-15 05:23:22 +03:00
|
|
|
launcherwidget->setData(service->entryPath());
|
2024-04-15 07:56:45 +03:00
|
|
|
QAction* favoriteaction = new QAction(launcherwidget);
|
|
|
|
favoriteaction->setIcon(KIcon("edit-delete"));
|
2024-04-15 08:03:15 +03:00
|
|
|
favoriteaction->setToolTip(i18n("Remove"));
|
2024-04-15 07:56:45 +03:00
|
|
|
favoriteaction->setProperty("_k_id", serviceentrypath);
|
|
|
|
connect(
|
|
|
|
favoriteaction, SIGNAL(triggered()),
|
|
|
|
this, SLOT(slotTriggered()),
|
|
|
|
Qt::QueuedConnection
|
|
|
|
);
|
|
|
|
launcherwidget->addAction(favoriteaction);
|
2024-04-15 05:23:22 +03:00
|
|
|
m_launcherwidgets.append(launcherwidget);
|
|
|
|
m_layout->addItem(launcherwidget);
|
2024-04-12 03:33:58 +03:00
|
|
|
connect(
|
2024-04-15 05:23:22 +03:00
|
|
|
launcherwidget, SIGNAL(activated()),
|
2024-04-12 03:33:58 +03:00
|
|
|
this, SLOT(slotActivated())
|
|
|
|
);
|
|
|
|
bookmark = bookmarkgroup.next(bookmark);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void LauncherFavorites::slotActivated()
|
|
|
|
{
|
2024-04-15 05:23:22 +03:00
|
|
|
LauncherWidget* launcherwidget = qobject_cast<LauncherWidget*>(sender());
|
|
|
|
kRunService(launcherwidget->data(), m_launcherapplet);
|
2024-04-12 03:33:58 +03:00
|
|
|
}
|
|
|
|
|
2024-04-15 07:56:45 +03:00
|
|
|
void LauncherFavorites::slotTriggered()
|
|
|
|
{
|
|
|
|
QAction* favoriteaction = qobject_cast<QAction*>(sender());
|
|
|
|
const QString favoriteid = favoriteaction->property("_k_id").toString();
|
|
|
|
KBookmarkGroup bookmarkgroup = m_bookmarkmanager->root();
|
|
|
|
KBookmark bookmark = bookmarkgroup.first();
|
|
|
|
while (!bookmark.isNull()) {
|
|
|
|
if (bookmark.url().url() == favoriteid) {
|
|
|
|
bookmarkgroup.deleteBookmark(bookmark);
|
|
|
|
m_bookmarkmanager->emitChanged(bookmarkgroup);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
bookmark = bookmarkgroup.next(bookmark);
|
|
|
|
}
|
|
|
|
kWarning() << "invalid bookmark" << favoriteid;
|
|
|
|
}
|
|
|
|
|
2024-04-12 03:33:58 +03:00
|
|
|
|
2024-04-15 00:48:47 +03:00
|
|
|
class LauncherNavigatorStruct
|
|
|
|
{
|
|
|
|
public:
|
2024-04-15 05:23:22 +03:00
|
|
|
LauncherNavigatorStruct(Plasma::SvgWidget *_svgwidget, Plasma::ToolButton *_toolbutton)
|
2024-04-15 01:49:10 +03:00
|
|
|
: svgwidget(_svgwidget), toolbutton(_toolbutton)
|
2024-04-15 00:48:47 +03:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
Plasma::SvgWidget* svgwidget;
|
|
|
|
Plasma::ToolButton* toolbutton;
|
|
|
|
};
|
|
|
|
|
2024-04-15 01:08:52 +03:00
|
|
|
class LauncherNavigator : public Plasma::Frame
|
2024-04-12 03:33:58 +03:00
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
public:
|
2024-04-15 00:48:47 +03:00
|
|
|
LauncherNavigator(QGraphicsWidget *parent);
|
2024-04-12 03:33:58 +03:00
|
|
|
|
2024-04-15 00:48:47 +03:00
|
|
|
void reset();
|
|
|
|
void addNavigation(const QString &id, const QString &text);
|
2024-04-15 16:14:29 +03:00
|
|
|
void finish();
|
2024-04-15 00:48:47 +03:00
|
|
|
|
|
|
|
Q_SIGNALS:
|
|
|
|
void navigate(const QString &id);
|
|
|
|
|
|
|
|
private Q_SLOTS:
|
|
|
|
void slotReleased();
|
2024-04-12 03:33:58 +03:00
|
|
|
|
|
|
|
private:
|
2024-04-15 00:48:47 +03:00
|
|
|
QMutex m_mutex;
|
2024-04-12 03:33:58 +03:00
|
|
|
QGraphicsLinearLayout* m_layout;
|
2024-04-15 05:23:22 +03:00
|
|
|
Plasma::Svg* m_svg;
|
2024-04-15 00:48:47 +03:00
|
|
|
QList<LauncherNavigatorStruct*> m_navigations;
|
|
|
|
QGraphicsWidget* m_spacer;
|
2024-04-12 03:33:58 +03:00
|
|
|
};
|
|
|
|
|
2024-04-15 00:48:47 +03:00
|
|
|
LauncherNavigator::LauncherNavigator(QGraphicsWidget *parent)
|
2024-04-15 01:08:52 +03:00
|
|
|
: Plasma::Frame(parent),
|
|
|
|
m_layout(nullptr),
|
2024-04-15 05:23:22 +03:00
|
|
|
m_svg(nullptr),
|
2024-04-15 00:48:47 +03:00
|
|
|
m_spacer(nullptr)
|
2024-04-12 03:33:58 +03:00
|
|
|
{
|
2024-04-15 00:48:47 +03:00
|
|
|
setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Minimum);
|
2024-04-15 01:08:52 +03:00
|
|
|
setFrameShadow(Plasma::Frame::Sunken);
|
2024-04-15 00:48:47 +03:00
|
|
|
m_layout = new QGraphicsLinearLayout(Qt::Horizontal, this);
|
2024-04-12 03:33:58 +03:00
|
|
|
setLayout(m_layout);
|
2024-04-15 05:23:22 +03:00
|
|
|
|
|
|
|
m_svg = new Plasma::Svg(this);
|
|
|
|
m_svg->setImagePath("widgets/arrows");
|
2024-04-12 03:33:58 +03:00
|
|
|
}
|
|
|
|
|
2024-04-15 00:48:47 +03:00
|
|
|
void LauncherNavigator::reset()
|
2024-04-12 03:33:58 +03:00
|
|
|
{
|
2024-04-15 00:48:47 +03:00
|
|
|
QMutexLocker locker(&m_mutex);
|
|
|
|
foreach (LauncherNavigatorStruct *navigation, m_navigations) {
|
|
|
|
m_layout->removeItem(navigation->toolbutton);
|
|
|
|
delete navigation->toolbutton;
|
|
|
|
m_layout->removeItem(navigation->svgwidget);
|
|
|
|
delete navigation->svgwidget;
|
|
|
|
}
|
|
|
|
qDeleteAll(m_navigations);
|
|
|
|
m_navigations.clear();
|
|
|
|
if (m_spacer) {
|
|
|
|
m_layout->removeItem(m_spacer);
|
|
|
|
delete m_spacer;
|
|
|
|
m_spacer = nullptr;
|
|
|
|
}
|
|
|
|
m_spacer = kMakeSpacer(this);
|
|
|
|
m_layout->addItem(m_spacer);
|
2024-04-12 03:33:58 +03:00
|
|
|
}
|
|
|
|
|
2024-04-15 00:48:47 +03:00
|
|
|
void LauncherNavigator::addNavigation(const QString &id, const QString &text)
|
2024-04-12 03:33:58 +03:00
|
|
|
{
|
2024-04-15 00:48:47 +03:00
|
|
|
// qDebug() << Q_FUNC_INFO << id << text;
|
|
|
|
QMutexLocker locker(&m_mutex);
|
|
|
|
Plasma::SvgWidget* svgwidget = new Plasma::SvgWidget(this);
|
|
|
|
svgwidget->setElementID("right-arrow");
|
2024-04-15 05:23:22 +03:00
|
|
|
svgwidget->setSvg(m_svg);
|
2024-04-15 00:48:47 +03:00
|
|
|
m_layout->addItem(svgwidget);
|
|
|
|
Plasma::ToolButton* toolbutton = new Plasma::ToolButton(this);
|
|
|
|
toolbutton->setText(text);
|
|
|
|
toolbutton->setProperty("_k_id", id);
|
|
|
|
m_layout->addItem(toolbutton);
|
2024-04-12 03:33:58 +03:00
|
|
|
connect(
|
2024-04-15 00:48:47 +03:00
|
|
|
toolbutton, SIGNAL(released()),
|
|
|
|
this, SLOT(slotReleased())
|
2024-04-12 03:33:58 +03:00
|
|
|
);
|
2024-04-15 00:48:47 +03:00
|
|
|
if (m_spacer) {
|
|
|
|
m_layout->removeItem(m_spacer);
|
|
|
|
delete m_spacer;
|
|
|
|
m_spacer = nullptr;
|
|
|
|
}
|
|
|
|
m_spacer = kMakeSpacer(this);
|
|
|
|
m_layout->addItem(m_spacer);
|
2024-04-15 01:49:10 +03:00
|
|
|
m_navigations.append(new LauncherNavigatorStruct(svgwidget, toolbutton));
|
2024-04-12 03:33:58 +03:00
|
|
|
}
|
|
|
|
|
2024-04-15 16:14:29 +03:00
|
|
|
void LauncherNavigator::finish()
|
|
|
|
{
|
|
|
|
QMutexLocker locker(&m_mutex);
|
|
|
|
if (m_navigations.size() > 0) {
|
|
|
|
// make the last navigator button match the tabbar
|
|
|
|
LauncherNavigatorStruct *navigation = m_navigations.last();
|
|
|
|
navigation->toolbutton->setAutoRaise(false);
|
|
|
|
navigation->toolbutton->setAcceptedMouseButtons(Qt::NoButton);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-04-15 00:48:47 +03:00
|
|
|
void LauncherNavigator::slotReleased()
|
2024-04-12 18:23:04 +03:00
|
|
|
{
|
2024-04-15 00:48:47 +03:00
|
|
|
Plasma::ToolButton* toolbutton = qobject_cast<Plasma::ToolButton*>(sender());
|
|
|
|
emit navigate(toolbutton->property("_k_id").toString());
|
2024-04-12 18:23:04 +03:00
|
|
|
}
|
|
|
|
|
2024-04-15 00:48:47 +03:00
|
|
|
class LauncherApplications : public QGraphicsWidget
|
2024-04-12 03:33:58 +03:00
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
public:
|
2024-04-13 15:35:55 +03:00
|
|
|
LauncherApplications(QGraphicsWidget *parent, LauncherApplet *launcherapplet);
|
2024-04-12 03:33:58 +03:00
|
|
|
|
|
|
|
private Q_SLOTS:
|
|
|
|
void slotUpdateLayout();
|
2024-04-15 00:48:47 +03:00
|
|
|
void slotNavigate(const QString &id);
|
|
|
|
void slotDelayedNavigate();
|
|
|
|
void slotGroupActivated();
|
|
|
|
void slotAppActivated();
|
2024-04-15 17:54:25 +03:00
|
|
|
void slotCheckBookmarks();
|
|
|
|
void slotTriggered();
|
2024-04-12 03:33:58 +03:00
|
|
|
|
|
|
|
private:
|
2024-04-15 01:08:52 +03:00
|
|
|
static int serviceCount(KServiceGroup::Ptr servicegroup);
|
2024-04-15 00:48:47 +03:00
|
|
|
void addGroup(KServiceGroup::Ptr servicegroup);
|
2024-04-12 03:33:58 +03:00
|
|
|
|
|
|
|
QMutex m_mutex;
|
2024-04-13 15:35:55 +03:00
|
|
|
LauncherApplet* m_launcherapplet;
|
2024-04-15 17:54:25 +03:00
|
|
|
KBookmarkManager* m_bookmarkmanager;
|
2024-04-15 00:48:47 +03:00
|
|
|
QGraphicsLinearLayout* m_layout;
|
|
|
|
LauncherNavigator* m_launchernavigator;
|
2024-04-15 01:49:10 +03:00
|
|
|
Plasma::ScrollWidget* m_scrollwidget;
|
2024-04-15 05:23:22 +03:00
|
|
|
QGraphicsWidget* m_launchersswidget;
|
|
|
|
QGraphicsLinearLayout* m_launcherslayout;
|
|
|
|
QList<LauncherWidget*> m_launcherwidgets;
|
2024-04-15 00:48:47 +03:00
|
|
|
QString m_id;
|
2024-04-12 03:33:58 +03:00
|
|
|
};
|
|
|
|
|
2024-04-13 15:35:55 +03:00
|
|
|
LauncherApplications::LauncherApplications(QGraphicsWidget *parent, LauncherApplet *launcherapplet)
|
2024-04-15 00:48:47 +03:00
|
|
|
: QGraphicsWidget(parent),
|
|
|
|
m_launcherapplet(launcherapplet),
|
2024-04-15 17:54:25 +03:00
|
|
|
m_bookmarkmanager(launcherapplet->bookmarkManager()),
|
2024-04-15 00:48:47 +03:00
|
|
|
m_layout(nullptr),
|
2024-04-15 01:49:10 +03:00
|
|
|
m_launchernavigator(nullptr),
|
|
|
|
m_scrollwidget(nullptr),
|
2024-04-15 05:23:22 +03:00
|
|
|
m_launchersswidget(nullptr),
|
|
|
|
m_launcherslayout(nullptr)
|
2024-04-15 01:49:10 +03:00
|
|
|
|
2024-04-12 03:33:58 +03:00
|
|
|
{
|
2024-04-15 00:48:47 +03:00
|
|
|
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
|
|
|
m_layout = new QGraphicsLinearLayout(Qt::Vertical, this);
|
|
|
|
setLayout(m_layout);
|
|
|
|
|
|
|
|
m_launchernavigator = new LauncherNavigator(this);
|
|
|
|
m_layout->addItem(m_launchernavigator);
|
2024-04-12 03:33:58 +03:00
|
|
|
|
2024-04-15 01:49:10 +03:00
|
|
|
m_scrollwidget = kMakeScrollWidget(this);
|
2024-04-15 05:23:22 +03:00
|
|
|
m_launchersswidget = new QGraphicsWidget(m_scrollwidget);
|
|
|
|
m_launchersswidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
|
|
|
m_launcherslayout = new QGraphicsLinearLayout(Qt::Vertical, m_launchersswidget);
|
|
|
|
m_launchersswidget->setLayout(m_launcherslayout);
|
|
|
|
m_scrollwidget->setWidget(m_launchersswidget);
|
2024-04-15 01:49:10 +03:00
|
|
|
m_layout->addItem(m_scrollwidget);
|
|
|
|
|
2024-04-12 03:33:58 +03:00
|
|
|
slotUpdateLayout();
|
|
|
|
|
2024-04-15 00:48:47 +03:00
|
|
|
connect(
|
|
|
|
m_launchernavigator, SIGNAL(navigate(QString)),
|
|
|
|
this, SLOT(slotNavigate(QString))
|
|
|
|
);
|
2024-04-15 17:54:25 +03:00
|
|
|
connect(
|
|
|
|
m_bookmarkmanager, SIGNAL(changed(QString,QString)),
|
|
|
|
this, SLOT(slotCheckBookmarks())
|
|
|
|
);
|
|
|
|
connect(
|
|
|
|
m_bookmarkmanager, SIGNAL(bookmarksChanged(QString)),
|
|
|
|
this, SLOT(slotCheckBookmarks())
|
|
|
|
);
|
2024-04-12 03:33:58 +03:00
|
|
|
connect(
|
|
|
|
KSycoca::self(), SIGNAL(databaseChanged(QStringList)),
|
|
|
|
this, SLOT(slotUpdateLayout())
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
void LauncherApplications::slotUpdateLayout()
|
|
|
|
{
|
|
|
|
QMutexLocker locker(&m_mutex);
|
2024-04-15 05:23:22 +03:00
|
|
|
foreach (LauncherWidget* launcherwidget, m_launcherwidgets) {
|
|
|
|
m_launcherslayout->removeItem(launcherwidget);
|
2024-04-13 15:17:15 +03:00
|
|
|
}
|
2024-04-15 05:23:22 +03:00
|
|
|
qDeleteAll(m_launcherwidgets);
|
|
|
|
m_launcherwidgets.clear();
|
2024-04-15 00:48:47 +03:00
|
|
|
|
|
|
|
m_launchernavigator->reset();
|
2024-04-12 03:33:58 +03:00
|
|
|
|
2024-04-15 05:23:22 +03:00
|
|
|
m_launchersswidget->adjustSize();
|
2024-04-15 00:48:47 +03:00
|
|
|
adjustSize();
|
2024-04-12 19:10:50 +03:00
|
|
|
|
2024-04-15 00:48:47 +03:00
|
|
|
m_id.clear();
|
|
|
|
KServiceGroup::Ptr rootgroup = KServiceGroup::root();
|
|
|
|
if (!rootgroup.isNull() && rootgroup->isValid()) {
|
|
|
|
m_id = rootgroup->relPath();
|
|
|
|
m_launchernavigator->addNavigation(m_id, rootgroup->caption());
|
|
|
|
addGroup(rootgroup);
|
2024-04-15 16:14:29 +03:00
|
|
|
m_launchernavigator->finish();
|
2024-04-12 03:33:58 +03:00
|
|
|
}
|
2024-04-15 17:54:25 +03:00
|
|
|
|
|
|
|
locker.unlock();
|
|
|
|
slotCheckBookmarks();
|
2024-04-12 03:33:58 +03:00
|
|
|
}
|
|
|
|
|
2024-04-15 00:48:47 +03:00
|
|
|
int LauncherApplications::serviceCount(KServiceGroup::Ptr servicegroup)
|
2024-04-12 03:33:58 +03:00
|
|
|
{
|
2024-04-15 00:48:47 +03:00
|
|
|
int result = 0;
|
|
|
|
foreach (const KServiceGroup::Ptr subgroup, servicegroup->groupEntries(KServiceGroup::NoOptions)) {
|
|
|
|
if (serviceCount(subgroup) > 0) {
|
|
|
|
result++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
foreach (const KService::Ptr appservice, servicegroup->serviceEntries(KServiceGroup::NoOptions)) {
|
|
|
|
if (appservice->noDisplay()) {
|
|
|
|
kDebug() << "hidden entry" << appservice->name();
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
result++;
|
2024-04-12 03:33:58 +03:00
|
|
|
}
|
2024-04-15 00:48:47 +03:00
|
|
|
return result;
|
|
|
|
}
|
2024-04-12 03:33:58 +03:00
|
|
|
|
2024-04-15 00:48:47 +03:00
|
|
|
void LauncherApplications::addGroup(KServiceGroup::Ptr servicegroup)
|
|
|
|
{
|
2024-04-12 03:33:58 +03:00
|
|
|
const QSizeF iconsize = kIconSize();
|
2024-04-15 00:48:47 +03:00
|
|
|
foreach (const KServiceGroup::Ptr subgroup, servicegroup->groupEntries(KServiceGroup::NoOptions)) {
|
|
|
|
if (serviceCount(subgroup) > 0) {
|
2024-04-15 05:23:22 +03:00
|
|
|
LauncherWidget* launcherwidget = new LauncherWidget(m_launchersswidget);
|
|
|
|
launcherwidget->setup(
|
|
|
|
iconsize, kGenericIcon(subgroup->icon()), subgroup->caption(), subgroup->comment()
|
2024-04-15 00:48:47 +03:00
|
|
|
);
|
2024-04-15 05:23:22 +03:00
|
|
|
launcherwidget->setData(subgroup->relPath());
|
|
|
|
m_launcherwidgets.append(launcherwidget);
|
|
|
|
m_launcherslayout->addItem(launcherwidget);
|
2024-04-15 00:48:47 +03:00
|
|
|
connect(
|
2024-04-15 05:23:22 +03:00
|
|
|
launcherwidget, SIGNAL(activated()),
|
2024-04-15 00:48:47 +03:00
|
|
|
this, SLOT(slotGroupActivated())
|
2024-04-12 03:33:58 +03:00
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
2024-04-15 00:48:47 +03:00
|
|
|
foreach (const KService::Ptr appservice, servicegroup->serviceEntries(KServiceGroup::NoOptions)) {
|
|
|
|
if (appservice->noDisplay()) {
|
|
|
|
kDebug() << "hidden entry" << appservice->name();
|
2024-04-12 03:33:58 +03:00
|
|
|
continue;
|
|
|
|
}
|
2024-04-15 17:54:25 +03:00
|
|
|
const QString entrypath = appservice->entryPath();
|
2024-04-15 05:23:22 +03:00
|
|
|
LauncherWidget* launcherwidget = new LauncherWidget(m_launchersswidget);
|
|
|
|
launcherwidget->setup(
|
|
|
|
iconsize, kGenericIcon(appservice->icon()), appservice->name(), appservice->comment()
|
2024-04-12 03:33:58 +03:00
|
|
|
);
|
2024-04-15 17:54:25 +03:00
|
|
|
launcherwidget->setData(entrypath);
|
2024-04-15 05:23:22 +03:00
|
|
|
m_launcherwidgets.append(launcherwidget);
|
|
|
|
m_launcherslayout->addItem(launcherwidget);
|
2024-04-15 00:48:47 +03:00
|
|
|
connect(
|
2024-04-15 05:23:22 +03:00
|
|
|
launcherwidget, SIGNAL(activated()),
|
2024-04-15 00:48:47 +03:00
|
|
|
this, SLOT(slotAppActivated())
|
|
|
|
);
|
|
|
|
}
|
2024-04-15 01:20:45 +03:00
|
|
|
const QString serviceid = servicegroup->relPath();
|
|
|
|
if (serviceid.isEmpty() || serviceid == QLatin1String("/")) {
|
|
|
|
// hide the navigator when the root group is empty
|
2024-04-15 05:23:22 +03:00
|
|
|
m_launchernavigator->setVisible(m_launcherwidgets.size() > 0);
|
2024-04-15 01:20:45 +03:00
|
|
|
}
|
2024-04-15 00:48:47 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void LauncherApplications::slotNavigate(const QString &id)
|
|
|
|
{
|
|
|
|
if (id == m_id) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_id = id;
|
|
|
|
// delayed because this is connected to widgets that will be destroyed
|
|
|
|
QTimer::singleShot(100, this, SLOT(slotDelayedNavigate()));
|
|
|
|
}
|
|
|
|
|
|
|
|
void LauncherApplications::slotDelayedNavigate()
|
|
|
|
{
|
|
|
|
QMutexLocker locker(&m_mutex);
|
2024-04-15 05:23:22 +03:00
|
|
|
foreach (LauncherWidget* launcherwidget, m_launcherwidgets) {
|
|
|
|
m_layout->removeItem(launcherwidget);
|
2024-04-15 00:48:47 +03:00
|
|
|
}
|
2024-04-15 05:23:22 +03:00
|
|
|
qDeleteAll(m_launcherwidgets);
|
|
|
|
m_launcherwidgets.clear();
|
2024-04-15 00:48:47 +03:00
|
|
|
|
|
|
|
m_launchernavigator->reset();
|
|
|
|
|
2024-04-15 05:23:22 +03:00
|
|
|
m_launchersswidget->adjustSize();
|
2024-04-15 00:48:47 +03:00
|
|
|
adjustSize();
|
|
|
|
|
|
|
|
// qDebug() << Q_FUNC_INFO << m_id;
|
|
|
|
KServiceGroup::Ptr servicegroup = KServiceGroup::group(m_id);
|
|
|
|
if (!servicegroup.isNull() && servicegroup->isValid()) {
|
|
|
|
KServiceGroup::Ptr rootgroup = KServiceGroup::root();
|
|
|
|
if (!rootgroup.isNull() && rootgroup->isValid()) {
|
|
|
|
m_launchernavigator->addNavigation(rootgroup->relPath(), rootgroup->caption());
|
|
|
|
} else {
|
|
|
|
kWarning() << "root group is not valid";
|
|
|
|
}
|
|
|
|
|
|
|
|
QString groupid;
|
|
|
|
foreach (const QString &subname, m_id.split(QLatin1Char('/'), QString::SkipEmptyParts)) {
|
|
|
|
groupid.append(subname);
|
|
|
|
groupid.append(QLatin1Char('/'));
|
|
|
|
KServiceGroup::Ptr subgroup = KServiceGroup::group(groupid);
|
|
|
|
if (subgroup.isNull() || !subgroup->isValid()) {
|
|
|
|
kWarning() << "invalid subgroup" << subname;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
m_launchernavigator->addNavigation(groupid, subgroup->caption());
|
|
|
|
}
|
|
|
|
addGroup(servicegroup);
|
|
|
|
} else {
|
|
|
|
kWarning() << "invalid group" << m_id;
|
2024-04-12 03:33:58 +03:00
|
|
|
}
|
2024-04-15 16:14:29 +03:00
|
|
|
m_launchernavigator->finish();
|
2024-04-15 17:54:25 +03:00
|
|
|
|
|
|
|
locker.unlock();
|
|
|
|
slotCheckBookmarks();
|
2024-04-12 03:33:58 +03:00
|
|
|
}
|
|
|
|
|
2024-04-15 00:48:47 +03:00
|
|
|
void LauncherApplications::slotGroupActivated()
|
|
|
|
{
|
2024-04-15 05:23:22 +03:00
|
|
|
LauncherWidget* launcherwidget = qobject_cast<LauncherWidget*>(sender());
|
|
|
|
slotNavigate(launcherwidget->data());
|
2024-04-15 00:48:47 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void LauncherApplications::slotAppActivated()
|
|
|
|
{
|
2024-04-15 05:23:22 +03:00
|
|
|
LauncherWidget* launcherwidget = qobject_cast<LauncherWidget*>(sender());
|
|
|
|
kRunService(launcherwidget->data(), m_launcherapplet);
|
2024-04-15 00:48:47 +03:00
|
|
|
}
|
2024-04-12 03:33:58 +03:00
|
|
|
|
2024-04-15 17:54:25 +03:00
|
|
|
void LauncherApplications::slotCheckBookmarks()
|
|
|
|
{
|
2024-04-17 21:58:23 +03:00
|
|
|
QStringList bookmarkurls;
|
2024-04-15 17:54:25 +03:00
|
|
|
KBookmarkGroup bookmarkgroup = m_bookmarkmanager->root();
|
2024-04-17 21:58:23 +03:00
|
|
|
KBookmark bookmark = bookmarkgroup.first();
|
|
|
|
bool isinfavorites = false;
|
|
|
|
while (!bookmark.isNull()) {
|
|
|
|
bookmarkurls.append(bookmark.url().url());
|
|
|
|
bookmark = bookmarkgroup.next(bookmark);
|
|
|
|
}
|
|
|
|
|
|
|
|
QMutexLocker locker(&m_mutex);
|
2024-04-15 17:54:25 +03:00
|
|
|
foreach (LauncherWidget* launcherwidget, m_launcherwidgets) {
|
|
|
|
const QString launcherdata = launcherwidget->data();
|
2024-04-17 21:58:23 +03:00
|
|
|
const bool isinfavorites = bookmarkurls.contains(launcherdata);
|
2024-04-15 17:54:25 +03:00
|
|
|
// qDebug() << Q_FUNC_INFO << launcherdata << isinfavorites;
|
|
|
|
// there is only one action, it is known which one is that
|
|
|
|
launcherwidget->removeAction(0);
|
|
|
|
if (!isinfavorites) {
|
|
|
|
KService::Ptr service = KService::serviceByDesktopPath(launcherdata);
|
|
|
|
if (!service.isNull() && service->isValid()) {
|
|
|
|
QAction* favoriteaction = new QAction(launcherwidget);
|
|
|
|
favoriteaction->setIcon(KIcon(s_favoriteicon));
|
|
|
|
favoriteaction->setToolTip(i18n("Add to Favorites"));
|
|
|
|
favoriteaction->setProperty("_k_id", launcherdata);
|
|
|
|
launcherwidget->addAction(favoriteaction);
|
|
|
|
connect(
|
|
|
|
favoriteaction, SIGNAL(triggered()),
|
|
|
|
this, SLOT(slotTriggered())
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void LauncherApplications::slotTriggered()
|
|
|
|
{
|
|
|
|
QAction* favoriteaction = qobject_cast<QAction*>(sender());
|
|
|
|
const QString favoriteid = favoriteaction->property("_k_id").toString();
|
|
|
|
KService::Ptr service = KService::serviceByDesktopPath(favoriteid);
|
|
|
|
if (!service.isNull()) {
|
|
|
|
KBookmarkGroup bookmarkgroup = m_bookmarkmanager->root();
|
|
|
|
bookmarkgroup.addBookmark(service->desktopEntryName(), KUrl(service->entryPath()), service->icon());
|
|
|
|
m_bookmarkmanager->emitChanged(bookmarkgroup);
|
|
|
|
favoriteaction->setVisible(false);
|
|
|
|
} else {
|
|
|
|
kWarning() << "invalid favorite serivce" << favoriteid;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-04-15 01:08:52 +03:00
|
|
|
|
2024-04-12 03:33:58 +03:00
|
|
|
class LauncherRecent : public QGraphicsWidget
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
public:
|
2024-04-13 15:35:55 +03:00
|
|
|
LauncherRecent(QGraphicsWidget *parent, LauncherApplet *launcherapplet);
|
2024-04-12 03:33:58 +03:00
|
|
|
|
|
|
|
private Q_SLOTS:
|
|
|
|
void slotUpdateLayout();
|
|
|
|
void slotActivated();
|
|
|
|
|
|
|
|
private:
|
|
|
|
QMutex m_mutex;
|
2024-04-13 15:35:55 +03:00
|
|
|
LauncherApplet* m_launcherapplet;
|
2024-04-12 03:33:58 +03:00
|
|
|
QGraphicsLinearLayout* m_layout;
|
2024-04-15 05:23:22 +03:00
|
|
|
QList<LauncherWidget*> m_launcherwidgets;
|
2024-04-12 03:33:58 +03:00
|
|
|
KDirWatch* m_dirwatch;
|
|
|
|
};
|
|
|
|
|
2024-04-13 15:35:55 +03:00
|
|
|
LauncherRecent::LauncherRecent(QGraphicsWidget *parent, LauncherApplet *launcherapplet)
|
2024-04-12 03:33:58 +03:00
|
|
|
: QGraphicsWidget(parent),
|
2024-04-13 15:35:55 +03:00
|
|
|
m_launcherapplet(launcherapplet),
|
2024-04-12 03:33:58 +03:00
|
|
|
m_layout(nullptr),
|
|
|
|
m_dirwatch(nullptr)
|
|
|
|
{
|
|
|
|
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
|
|
|
m_layout = new QGraphicsLinearLayout(Qt::Vertical, this);
|
|
|
|
setLayout(m_layout);
|
|
|
|
|
|
|
|
m_dirwatch = new KDirWatch(this);
|
|
|
|
m_dirwatch->addDir(KRecentDocument::recentDocumentDirectory());
|
|
|
|
slotUpdateLayout();
|
|
|
|
connect(
|
|
|
|
m_dirwatch, SIGNAL(dirty(QString)),
|
|
|
|
this, SLOT(slotUpdateLayout())
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
void LauncherRecent::slotUpdateLayout()
|
|
|
|
{
|
|
|
|
QMutexLocker locker(&m_mutex);
|
2024-04-15 05:23:22 +03:00
|
|
|
foreach (LauncherWidget* launcherwidget, m_launcherwidgets) {
|
|
|
|
m_layout->removeItem(launcherwidget);
|
2024-04-12 03:33:58 +03:00
|
|
|
}
|
2024-04-15 05:23:22 +03:00
|
|
|
qDeleteAll(m_launcherwidgets);
|
|
|
|
m_launcherwidgets.clear();
|
2024-04-12 03:33:58 +03:00
|
|
|
|
|
|
|
adjustSize();
|
|
|
|
|
|
|
|
const QSizeF iconsize = kIconSize();
|
|
|
|
foreach (const QString &recent, KRecentDocument::recentDocuments()) {
|
|
|
|
KDesktopFile recentfile(recent);
|
|
|
|
// qDebug() << Q_FUNC_INFO << recentfile.readName() << recentfile.readComment();
|
2024-04-15 05:23:22 +03:00
|
|
|
LauncherWidget* launcherwidget = new LauncherWidget(this);
|
|
|
|
launcherwidget->setup(
|
|
|
|
iconsize, kRecentIcon(recentfile.readIcon()), recentfile.readName(), recentfile.readComment()
|
2024-04-12 03:33:58 +03:00
|
|
|
);
|
2024-04-15 05:23:22 +03:00
|
|
|
launcherwidget->setData(recentfile.readUrl());
|
2024-04-16 21:00:37 +03:00
|
|
|
launcherwidget->disableAnimations();
|
2024-04-15 05:23:22 +03:00
|
|
|
m_launcherwidgets.append(launcherwidget);
|
|
|
|
m_layout->addItem(launcherwidget);
|
2024-04-12 03:33:58 +03:00
|
|
|
connect(
|
2024-04-15 05:23:22 +03:00
|
|
|
launcherwidget, SIGNAL(activated()),
|
2024-04-12 03:33:58 +03:00
|
|
|
this, SLOT(slotActivated())
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void LauncherRecent::slotActivated()
|
|
|
|
{
|
2024-04-15 05:23:22 +03:00
|
|
|
LauncherWidget* launcherwidget = qobject_cast<LauncherWidget*>(sender());
|
|
|
|
kRunUrl(launcherwidget->data(), m_launcherapplet);
|
2024-04-12 03:33:58 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
class LauncherLeave : public QGraphicsWidget
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
public:
|
|
|
|
LauncherLeave(QGraphicsWidget *parent);
|
|
|
|
|
|
|
|
private Q_SLOTS:
|
|
|
|
void slotUpdateLayout();
|
|
|
|
void slotActivated();
|
2024-04-14 10:46:53 +03:00
|
|
|
void slotTimeout();
|
2024-04-12 03:33:58 +03:00
|
|
|
|
|
|
|
private:
|
|
|
|
QMutex m_mutex;
|
|
|
|
QGraphicsLinearLayout* m_layout;
|
2024-04-15 05:23:22 +03:00
|
|
|
QList<LauncherWidget*> m_launcherwidgets;
|
2024-04-12 03:33:58 +03:00
|
|
|
Plasma::Separator* m_systemseparator;
|
2024-04-14 10:46:53 +03:00
|
|
|
QTimer* m_timer;
|
|
|
|
bool m_canlock;
|
|
|
|
bool m_canswitch;
|
|
|
|
bool m_canreboot;
|
|
|
|
bool m_canshutdown;
|
2024-04-15 17:58:18 +03:00
|
|
|
KDisplayManager m_displaymanager;
|
2024-04-12 03:33:58 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
LauncherLeave::LauncherLeave(QGraphicsWidget *parent)
|
|
|
|
: QGraphicsWidget(parent),
|
2024-04-14 10:46:53 +03:00
|
|
|
m_systemseparator(nullptr),
|
|
|
|
m_timer(nullptr),
|
|
|
|
m_canlock(false),
|
|
|
|
m_canswitch(false),
|
|
|
|
m_canreboot(false),
|
|
|
|
m_canshutdown(false)
|
2024-04-12 03:33:58 +03:00
|
|
|
{
|
|
|
|
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
|
|
|
m_layout = new QGraphicsLinearLayout(Qt::Vertical, this);
|
|
|
|
setLayout(m_layout);
|
|
|
|
|
2024-04-14 10:46:53 +03:00
|
|
|
m_timer = new QTimer(this);
|
2024-04-17 00:04:35 +03:00
|
|
|
m_timer->setInterval(s_polltimeout);
|
2024-04-14 10:46:53 +03:00
|
|
|
|
|
|
|
slotTimeout();
|
2024-04-12 03:33:58 +03:00
|
|
|
slotUpdateLayout();
|
|
|
|
connect(
|
|
|
|
Solid::PowerManagement::notifier(), SIGNAL(supportedSleepStatesChanged()),
|
|
|
|
this, SLOT(slotUpdateLayout())
|
|
|
|
);
|
2024-04-14 10:46:53 +03:00
|
|
|
connect(
|
|
|
|
m_timer, SIGNAL(timeout()),
|
|
|
|
this, SLOT(slotTimeout())
|
|
|
|
);
|
|
|
|
m_timer->start();
|
2024-04-12 03:33:58 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void LauncherLeave::slotUpdateLayout()
|
|
|
|
{
|
|
|
|
QMutexLocker locker(&m_mutex);
|
2024-04-15 05:23:22 +03:00
|
|
|
foreach (LauncherWidget* launcherwidget, m_launcherwidgets) {
|
|
|
|
m_layout->removeItem(launcherwidget);
|
2024-04-12 03:33:58 +03:00
|
|
|
}
|
2024-04-15 05:23:22 +03:00
|
|
|
qDeleteAll(m_launcherwidgets);
|
|
|
|
m_launcherwidgets.clear();
|
2024-04-12 03:33:58 +03:00
|
|
|
|
|
|
|
if (m_systemseparator) {
|
|
|
|
m_layout->removeItem(m_systemseparator);
|
|
|
|
delete m_systemseparator;
|
|
|
|
m_systemseparator = nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
adjustSize();
|
|
|
|
|
|
|
|
const QSizeF iconsize = kIconSize();
|
|
|
|
bool hassessionicon = false;
|
2024-04-14 10:46:53 +03:00
|
|
|
if (m_canlock) {
|
2024-04-15 05:23:22 +03:00
|
|
|
LauncherWidget* launcherwidget = new LauncherWidget(this);
|
|
|
|
launcherwidget->setup(
|
|
|
|
iconsize, KIcon("system-lock-screen"), i18n("Lock"), i18n("Lock screen")
|
2024-04-12 03:33:58 +03:00
|
|
|
);
|
2024-04-15 05:23:22 +03:00
|
|
|
launcherwidget->setData("lock");
|
2024-04-16 21:00:37 +03:00
|
|
|
launcherwidget->disableAnimations();
|
2024-04-15 05:23:22 +03:00
|
|
|
m_launcherwidgets.append(launcherwidget);
|
|
|
|
m_layout->addItem(launcherwidget);
|
2024-04-12 03:33:58 +03:00
|
|
|
connect(
|
2024-04-15 05:23:22 +03:00
|
|
|
launcherwidget, SIGNAL(activated()),
|
2024-04-12 03:33:58 +03:00
|
|
|
this, SLOT(slotActivated())
|
|
|
|
);
|
|
|
|
hassessionicon = true;
|
|
|
|
}
|
2024-04-14 10:46:53 +03:00
|
|
|
if (m_canswitch) {
|
2024-04-15 05:23:22 +03:00
|
|
|
LauncherWidget* launcherwidget = new LauncherWidget(this);
|
|
|
|
launcherwidget->setup(
|
|
|
|
iconsize, KIcon("system-switch-user"), i18n("Switch user"), i18n("Start a parallel session as a different user")
|
2024-04-12 03:33:58 +03:00
|
|
|
);
|
2024-04-15 05:23:22 +03:00
|
|
|
launcherwidget->setData("switch");
|
2024-04-16 21:00:37 +03:00
|
|
|
launcherwidget->disableAnimations();
|
2024-04-15 05:23:22 +03:00
|
|
|
m_launcherwidgets.append(launcherwidget);
|
|
|
|
m_layout->addItem(launcherwidget);
|
2024-04-12 03:33:58 +03:00
|
|
|
connect(
|
2024-04-15 05:23:22 +03:00
|
|
|
launcherwidget, SIGNAL(activated()),
|
2024-04-12 03:33:58 +03:00
|
|
|
this, SLOT(slotActivated())
|
|
|
|
);
|
|
|
|
hassessionicon = true;
|
|
|
|
}
|
|
|
|
if (hassessionicon) {
|
|
|
|
m_systemseparator = new Plasma::Separator(this);
|
|
|
|
m_systemseparator->setOrientation(Qt::Horizontal);
|
|
|
|
m_layout->addItem(m_systemseparator);
|
|
|
|
}
|
|
|
|
|
|
|
|
const QSet<Solid::PowerManagement::SleepState> sleepsates = Solid::PowerManagement::supportedSleepStates();
|
|
|
|
if (sleepsates.contains(Solid::PowerManagement::SuspendState)) {
|
2024-04-15 05:23:22 +03:00
|
|
|
LauncherWidget* launcherwidget = new LauncherWidget(this);
|
|
|
|
launcherwidget->setup(
|
|
|
|
iconsize, KIcon("system-suspend"), i18n("Sleep"), i18n("Suspend to RAM")
|
2024-04-12 03:33:58 +03:00
|
|
|
);
|
2024-04-15 05:23:22 +03:00
|
|
|
launcherwidget->setData("suspendram");
|
2024-04-16 21:00:37 +03:00
|
|
|
launcherwidget->disableAnimations();
|
2024-04-15 05:23:22 +03:00
|
|
|
m_launcherwidgets.append(launcherwidget);
|
|
|
|
m_layout->addItem(launcherwidget);
|
2024-04-12 03:33:58 +03:00
|
|
|
connect(
|
2024-04-15 05:23:22 +03:00
|
|
|
launcherwidget, SIGNAL(activated()),
|
2024-04-12 03:33:58 +03:00
|
|
|
this, SLOT(slotActivated())
|
|
|
|
);
|
|
|
|
}
|
|
|
|
if (sleepsates.contains(Solid::PowerManagement::HibernateState)) {
|
2024-04-15 05:23:22 +03:00
|
|
|
LauncherWidget* launcherwidget = new LauncherWidget(this);
|
|
|
|
launcherwidget->setup(
|
|
|
|
iconsize, KIcon("system-suspend-hibernate"), i18n("Hibernate"), i18n("Suspend to disk")
|
2024-04-12 03:33:58 +03:00
|
|
|
);
|
2024-04-15 05:23:22 +03:00
|
|
|
launcherwidget->setData("suspenddisk");
|
2024-04-16 21:00:37 +03:00
|
|
|
launcherwidget->disableAnimations();
|
2024-04-15 05:23:22 +03:00
|
|
|
m_launcherwidgets.append(launcherwidget);
|
|
|
|
m_layout->addItem(launcherwidget);
|
2024-04-12 03:33:58 +03:00
|
|
|
connect(
|
2024-04-15 05:23:22 +03:00
|
|
|
launcherwidget, SIGNAL(activated()),
|
2024-04-12 03:33:58 +03:00
|
|
|
this, SLOT(slotActivated())
|
|
|
|
);
|
|
|
|
}
|
|
|
|
if (sleepsates.contains(Solid::PowerManagement::HybridSuspendState)) {
|
2024-04-15 05:23:22 +03:00
|
|
|
LauncherWidget* launcherwidget = new LauncherWidget(this);
|
|
|
|
launcherwidget->setup(
|
|
|
|
iconsize, KIcon("system-suspend"), i18n("Hybrid Suspend"), i18n("Hybrid Suspend")
|
2024-04-12 03:33:58 +03:00
|
|
|
);
|
2024-04-15 05:23:22 +03:00
|
|
|
launcherwidget->setData("suspendhybrid");
|
2024-04-16 21:00:37 +03:00
|
|
|
launcherwidget->disableAnimations();
|
2024-04-15 05:23:22 +03:00
|
|
|
m_launcherwidgets.append(launcherwidget);
|
|
|
|
m_layout->addItem(launcherwidget);
|
2024-04-12 03:33:58 +03:00
|
|
|
connect(
|
2024-04-15 05:23:22 +03:00
|
|
|
launcherwidget, SIGNAL(activated()),
|
2024-04-12 03:33:58 +03:00
|
|
|
this, SLOT(slotActivated())
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2024-04-14 10:46:53 +03:00
|
|
|
if (m_canreboot) {
|
2024-04-15 05:23:22 +03:00
|
|
|
LauncherWidget* launcherwidget = new LauncherWidget(this);
|
|
|
|
launcherwidget->setup(
|
|
|
|
iconsize, KIcon("system-reboot"), i18nc("Restart computer", "Restart"), i18n("Restart computer")
|
2024-04-12 03:33:58 +03:00
|
|
|
);
|
2024-04-15 05:23:22 +03:00
|
|
|
launcherwidget->setData("restart");
|
2024-04-16 21:00:37 +03:00
|
|
|
launcherwidget->disableAnimations();
|
2024-04-15 05:23:22 +03:00
|
|
|
m_launcherwidgets.append(launcherwidget);
|
|
|
|
m_layout->addItem(launcherwidget);
|
2024-04-12 03:33:58 +03:00
|
|
|
connect(
|
2024-04-15 05:23:22 +03:00
|
|
|
launcherwidget, SIGNAL(activated()),
|
2024-04-12 03:33:58 +03:00
|
|
|
this, SLOT(slotActivated())
|
|
|
|
);
|
|
|
|
}
|
2024-04-14 10:46:53 +03:00
|
|
|
if (m_canshutdown) {
|
2024-04-15 05:23:22 +03:00
|
|
|
LauncherWidget* launcherwidget = new LauncherWidget(this);
|
|
|
|
launcherwidget->setup(
|
|
|
|
iconsize, KIcon("system-shutdown"), i18n("Shut down"), i18n("Turn off computer")
|
2024-04-12 03:33:58 +03:00
|
|
|
);
|
2024-04-15 05:23:22 +03:00
|
|
|
launcherwidget->setData("shutdown");
|
2024-04-16 21:00:37 +03:00
|
|
|
launcherwidget->disableAnimations();
|
2024-04-15 05:23:22 +03:00
|
|
|
m_launcherwidgets.append(launcherwidget);
|
|
|
|
m_layout->addItem(launcherwidget);
|
2024-04-12 03:33:58 +03:00
|
|
|
connect(
|
2024-04-15 05:23:22 +03:00
|
|
|
launcherwidget, SIGNAL(activated()),
|
2024-04-12 03:33:58 +03:00
|
|
|
this, SLOT(slotActivated())
|
|
|
|
);
|
|
|
|
}
|
2024-04-15 05:23:22 +03:00
|
|
|
LauncherWidget* launcherwidget = new LauncherWidget(this);
|
|
|
|
launcherwidget->setup(
|
|
|
|
iconsize, KIcon("system-log-out"), i18n("Log out"), i18n("End session")
|
2024-04-12 03:33:58 +03:00
|
|
|
);
|
2024-04-15 05:23:22 +03:00
|
|
|
launcherwidget->setData("logout");
|
2024-04-16 21:00:37 +03:00
|
|
|
launcherwidget->disableAnimations();
|
2024-04-15 05:23:22 +03:00
|
|
|
m_launcherwidgets.append(launcherwidget);
|
|
|
|
m_layout->addItem(launcherwidget);
|
2024-04-12 03:33:58 +03:00
|
|
|
connect(
|
2024-04-15 05:23:22 +03:00
|
|
|
launcherwidget, SIGNAL(activated()),
|
2024-04-12 03:33:58 +03:00
|
|
|
this, SLOT(slotActivated())
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
void LauncherLeave::slotActivated()
|
|
|
|
{
|
2024-04-15 05:23:22 +03:00
|
|
|
LauncherWidget* launcherwidget = qobject_cast<LauncherWidget*>(sender());
|
|
|
|
const QString launcherwidgetdata = launcherwidget->data();
|
|
|
|
if (launcherwidgetdata == QLatin1String("lock")) {
|
2024-04-12 03:33:58 +03:00
|
|
|
kLockScreen();
|
2024-04-15 05:23:22 +03:00
|
|
|
} else if (launcherwidgetdata == QLatin1String("switch")) {
|
2024-04-12 03:33:58 +03:00
|
|
|
kLockScreen();
|
2024-04-15 17:58:18 +03:00
|
|
|
m_displaymanager.newSession();
|
2024-04-15 05:23:22 +03:00
|
|
|
} else if (launcherwidgetdata == QLatin1String("suspendram")) {
|
2024-04-12 03:33:58 +03:00
|
|
|
Solid::PowerManagement::requestSleep(Solid::PowerManagement::SuspendState);
|
2024-04-15 05:23:22 +03:00
|
|
|
} else if (launcherwidgetdata == QLatin1String("suspenddisk")) {
|
2024-04-12 03:33:58 +03:00
|
|
|
Solid::PowerManagement::requestSleep(Solid::PowerManagement::HibernateState);
|
2024-04-15 05:23:22 +03:00
|
|
|
} else if (launcherwidgetdata == QLatin1String("suspendhybrid")) {
|
2024-04-12 03:33:58 +03:00
|
|
|
Solid::PowerManagement::requestSleep(Solid::PowerManagement::HybridSuspendState);
|
2024-04-15 05:23:22 +03:00
|
|
|
} else if (launcherwidgetdata == QLatin1String("restart")) {
|
2024-04-12 03:33:58 +03:00
|
|
|
KWorkSpace::requestShutDown(KWorkSpace::ShutdownConfirmDefault, KWorkSpace::ShutdownTypeReboot);
|
2024-04-15 05:23:22 +03:00
|
|
|
} else if (launcherwidgetdata == QLatin1String("shutdown")) {
|
2024-04-12 03:33:58 +03:00
|
|
|
KWorkSpace::requestShutDown(KWorkSpace::ShutdownConfirmDefault, KWorkSpace::ShutdownTypeHalt);
|
2024-04-15 05:23:22 +03:00
|
|
|
} else if (launcherwidgetdata == QLatin1String("logout")) {
|
2024-04-12 03:33:58 +03:00
|
|
|
KWorkSpace::requestShutDown(KWorkSpace::ShutdownConfirmDefault, KWorkSpace::ShutdownTypeNone);
|
|
|
|
} else {
|
|
|
|
Q_ASSERT(false);
|
2024-04-15 05:23:22 +03:00
|
|
|
kWarning() << "invalid url" << launcherwidgetdata;
|
2024-04-12 03:33:58 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-04-14 10:46:53 +03:00
|
|
|
void LauncherLeave::slotTimeout()
|
|
|
|
{
|
|
|
|
const bool oldcanlock = m_canlock;
|
|
|
|
const bool oldcanswitch = m_canswitch;
|
|
|
|
const bool oldcanreboot = m_canreboot;
|
|
|
|
const bool oldcanshutdown = m_canshutdown;
|
|
|
|
m_canlock = KDBusConnectionPool::isServiceRegistered("org.freedesktop.ScreenSaver", QDBusConnection::sessionBus());
|
2024-04-15 17:58:18 +03:00
|
|
|
m_canswitch = m_displaymanager.isSwitchable();
|
2024-04-14 10:46:53 +03:00
|
|
|
m_canreboot = KWorkSpace::canShutDown(KWorkSpace::ShutdownConfirmDefault, KWorkSpace::ShutdownTypeReboot);
|
|
|
|
m_canshutdown = KWorkSpace::canShutDown(KWorkSpace::ShutdownConfirmDefault, KWorkSpace::ShutdownTypeHalt);
|
|
|
|
if (oldcanlock != m_canlock || oldcanswitch != m_canswitch ||
|
|
|
|
oldcanreboot != m_canreboot || oldcanshutdown != m_canshutdown) {
|
|
|
|
slotUpdateLayout();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-04-12 03:33:58 +03:00
|
|
|
|
|
|
|
class LauncherAppletWidget : public QGraphicsWidget
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
public:
|
|
|
|
LauncherAppletWidget(LauncherApplet* auncherapplet);
|
2024-04-17 00:04:35 +03:00
|
|
|
~LauncherAppletWidget();
|
2024-04-12 03:33:58 +03:00
|
|
|
|
2024-04-14 10:34:13 +03:00
|
|
|
void resetSearch();
|
2024-04-14 11:58:56 +03:00
|
|
|
void setAllowedRunners(const QStringList &runners);
|
2024-04-14 10:34:13 +03:00
|
|
|
|
2024-04-12 03:33:58 +03:00
|
|
|
private Q_SLOTS:
|
|
|
|
void slotSearch(const QString &text);
|
2024-04-17 00:04:35 +03:00
|
|
|
void slotUserTimeout();
|
|
|
|
void slotSearchTimeout();
|
2024-04-12 03:33:58 +03:00
|
|
|
|
|
|
|
private:
|
|
|
|
LauncherApplet* m_launcherapplet;
|
2024-04-12 18:45:31 +03:00
|
|
|
QGraphicsLinearLayout* m_layout;
|
|
|
|
QGraphicsLinearLayout* m_toplayout;
|
2024-04-12 03:33:58 +03:00
|
|
|
Plasma::IconWidget* m_iconwidget;
|
|
|
|
Plasma::Label* m_label;
|
|
|
|
Plasma::LineEdit* m_lineedit;
|
|
|
|
Plasma::TabBar* m_tabbar;
|
|
|
|
Plasma::ScrollWidget* m_favoritesscrollwidget;
|
|
|
|
LauncherFavorites* m_favoriteswidget;
|
|
|
|
LauncherApplications* m_applicationswidget;
|
|
|
|
Plasma::ScrollWidget* m_recentscrollwidget;
|
|
|
|
LauncherRecent* m_recentwidget;
|
|
|
|
Plasma::ScrollWidget* m_leavecrollwidget;
|
|
|
|
LauncherLeave* m_leavewidget;
|
|
|
|
Plasma::ScrollWidget* m_searchscrollwidget;
|
|
|
|
LauncherSearch* m_searchwidget;
|
2024-04-17 00:04:35 +03:00
|
|
|
KUser* m_user;
|
|
|
|
QTimer* m_usertimer;
|
|
|
|
QTimer* m_searchtimer;
|
2024-04-12 03:33:58 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
LauncherAppletWidget::LauncherAppletWidget(LauncherApplet* auncherapplet)
|
|
|
|
: QGraphicsWidget(auncherapplet),
|
|
|
|
m_launcherapplet(auncherapplet),
|
|
|
|
m_layout(nullptr),
|
2024-04-12 18:45:31 +03:00
|
|
|
m_toplayout(nullptr),
|
2024-04-12 03:33:58 +03:00
|
|
|
m_iconwidget(nullptr),
|
|
|
|
m_label(nullptr),
|
|
|
|
m_lineedit(nullptr),
|
|
|
|
m_tabbar(nullptr),
|
|
|
|
m_favoritesscrollwidget(nullptr),
|
|
|
|
m_favoriteswidget(nullptr),
|
|
|
|
m_applicationswidget(nullptr),
|
|
|
|
m_recentscrollwidget(nullptr),
|
|
|
|
m_recentwidget(nullptr),
|
|
|
|
m_leavecrollwidget(nullptr),
|
|
|
|
m_leavewidget(nullptr),
|
|
|
|
m_searchscrollwidget(nullptr),
|
|
|
|
m_searchwidget(nullptr),
|
2024-04-17 00:04:35 +03:00
|
|
|
m_user(nullptr),
|
|
|
|
m_usertimer(nullptr),
|
|
|
|
m_searchtimer(nullptr)
|
2024-04-12 03:33:58 +03:00
|
|
|
{
|
2024-04-12 18:45:31 +03:00
|
|
|
m_layout = new QGraphicsLinearLayout(this);
|
|
|
|
m_layout->setOrientation(Qt::Vertical);
|
|
|
|
m_toplayout = new QGraphicsLinearLayout(m_layout);
|
|
|
|
m_toplayout->setOrientation(Qt::Horizontal);
|
|
|
|
m_toplayout->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
|
|
|
|
m_layout->addItem(m_toplayout);
|
2024-04-12 03:33:58 +03:00
|
|
|
|
2024-04-17 00:04:35 +03:00
|
|
|
m_user = new KUser(KUser::UseEffectiveUID);
|
|
|
|
|
2024-04-12 03:33:58 +03:00
|
|
|
m_iconwidget = new Plasma::IconWidget(this);
|
|
|
|
m_iconwidget->setAcceptHoverEvents(false);
|
|
|
|
m_iconwidget->setAcceptedMouseButtons(Qt::NoButton);
|
2024-04-17 00:04:35 +03:00
|
|
|
m_iconwidget->setIcon(s_usericon);
|
2024-04-12 18:45:31 +03:00
|
|
|
m_toplayout->addItem(m_iconwidget);
|
2024-04-12 03:33:58 +03:00
|
|
|
|
|
|
|
m_label = new Plasma::Label(this);
|
|
|
|
m_label->setWordWrap(false);
|
2024-04-12 18:45:31 +03:00
|
|
|
m_toplayout->addItem(m_label);
|
2024-04-12 19:34:50 +03:00
|
|
|
m_toplayout->setAlignment(m_label, Qt::AlignCenter);
|
2024-04-12 03:33:58 +03:00
|
|
|
|
|
|
|
m_lineedit = new Plasma::LineEdit(this);
|
|
|
|
m_lineedit->setClickMessage(i18n("Search"));
|
2024-04-12 19:34:50 +03:00
|
|
|
m_lineedit->setClearButtonShown(true);
|
2024-04-12 18:45:31 +03:00
|
|
|
m_toplayout->addItem(m_lineedit);
|
|
|
|
m_toplayout->setAlignment(m_lineedit, Qt::AlignCenter);
|
2024-04-12 03:33:58 +03:00
|
|
|
setFocusProxy(m_lineedit);
|
|
|
|
|
|
|
|
m_tabbar = new Plasma::TabBar(this);
|
2024-04-12 17:11:13 +03:00
|
|
|
m_favoritesscrollwidget = kMakeScrollWidget(m_tabbar);
|
2024-04-12 03:33:58 +03:00
|
|
|
m_favoritesscrollwidget->setMinimumSize(s_minimumsize);
|
2024-04-13 15:35:55 +03:00
|
|
|
m_favoriteswidget = new LauncherFavorites(m_favoritesscrollwidget, m_launcherapplet);
|
2024-04-12 03:33:58 +03:00
|
|
|
m_favoritesscrollwidget->setWidget(m_favoriteswidget);
|
2024-04-12 17:38:43 +03:00
|
|
|
m_tabbar->addTab(KIcon(s_favoriteicon), i18n("Favorites"), m_favoritesscrollwidget);
|
2024-04-15 01:49:10 +03:00
|
|
|
m_applicationswidget = new LauncherApplications(m_tabbar, m_launcherapplet);
|
|
|
|
m_applicationswidget->setMinimumSize(s_minimumsize);
|
|
|
|
m_tabbar->addTab(KIcon(s_genericicon), i18n("Applications"), m_applicationswidget);
|
2024-04-12 17:11:13 +03:00
|
|
|
m_recentscrollwidget = kMakeScrollWidget(m_tabbar);
|
2024-04-12 03:33:58 +03:00
|
|
|
m_recentscrollwidget->setMinimumSize(s_minimumsize);
|
2024-04-13 15:35:55 +03:00
|
|
|
m_recentwidget = new LauncherRecent(m_recentscrollwidget, m_launcherapplet);
|
2024-04-12 03:33:58 +03:00
|
|
|
m_recentscrollwidget->setWidget(m_recentwidget);
|
2024-04-12 17:38:43 +03:00
|
|
|
m_tabbar->addTab(KIcon(s_recenticon), i18n("Recently Used"), m_recentscrollwidget);
|
2024-04-12 17:11:13 +03:00
|
|
|
m_leavecrollwidget = kMakeScrollWidget(m_tabbar);
|
2024-04-12 03:33:58 +03:00
|
|
|
m_leavecrollwidget->setMinimumSize(s_minimumsize);
|
|
|
|
m_leavewidget = new LauncherLeave(m_leavecrollwidget);
|
|
|
|
m_leavecrollwidget->setWidget(m_leavewidget);
|
|
|
|
m_tabbar->addTab(KIcon("system-shutdown"), i18n("Leave"), m_leavecrollwidget);
|
2024-04-12 18:45:31 +03:00
|
|
|
m_layout->addItem(m_tabbar);
|
|
|
|
// squeeze the icon
|
|
|
|
m_layout->setStretchFactor(m_tabbar, 100);
|
2024-04-12 03:33:58 +03:00
|
|
|
|
2024-04-12 17:11:13 +03:00
|
|
|
m_searchscrollwidget = kMakeScrollWidget(this);
|
2024-04-12 03:33:58 +03:00
|
|
|
m_searchscrollwidget->setMinimumSize(s_minimumsize);
|
|
|
|
m_searchscrollwidget->setVisible(false);
|
2024-04-14 10:34:13 +03:00
|
|
|
m_searchwidget = new LauncherSearch(m_searchscrollwidget, m_launcherapplet);
|
2024-04-12 03:33:58 +03:00
|
|
|
m_searchscrollwidget->setWidget(m_searchwidget);
|
2024-04-12 18:45:31 +03:00
|
|
|
m_layout->addItem(m_searchscrollwidget);
|
2024-04-12 03:33:58 +03:00
|
|
|
connect(
|
|
|
|
m_lineedit, SIGNAL(textChanged(QString)),
|
|
|
|
this, SLOT(slotSearch(QString))
|
|
|
|
);
|
|
|
|
|
2024-04-17 00:04:35 +03:00
|
|
|
m_usertimer = new QTimer(this);
|
|
|
|
m_usertimer->setInterval(s_polltimeout);
|
2024-04-12 03:33:58 +03:00
|
|
|
connect(
|
2024-04-17 00:04:35 +03:00
|
|
|
m_usertimer, SIGNAL(timeout()),
|
|
|
|
this, SLOT(slotUserTimeout())
|
|
|
|
);
|
|
|
|
slotUserTimeout();
|
|
|
|
m_usertimer->start();
|
|
|
|
|
|
|
|
m_searchtimer = new QTimer(this);
|
|
|
|
m_searchtimer->setSingleShot(true);
|
|
|
|
m_searchtimer->setInterval(s_searchdelay);
|
|
|
|
connect(
|
|
|
|
m_searchtimer, SIGNAL(timeout()),
|
|
|
|
this, SLOT(slotSearchTimeout())
|
2024-04-12 03:33:58 +03:00
|
|
|
);
|
|
|
|
|
|
|
|
setLayout(m_layout);
|
|
|
|
}
|
|
|
|
|
2024-04-17 00:04:35 +03:00
|
|
|
LauncherAppletWidget::~LauncherAppletWidget()
|
|
|
|
{
|
|
|
|
delete m_user;
|
|
|
|
}
|
|
|
|
|
2024-04-14 10:34:13 +03:00
|
|
|
void LauncherAppletWidget::resetSearch()
|
|
|
|
{
|
|
|
|
m_lineedit->setText(QString());
|
|
|
|
}
|
|
|
|
|
2024-04-14 11:58:56 +03:00
|
|
|
void LauncherAppletWidget::setAllowedRunners(const QStringList &runners)
|
|
|
|
{
|
|
|
|
m_searchwidget->setAllowedRunners(runners);
|
|
|
|
}
|
|
|
|
|
2024-04-12 03:33:58 +03:00
|
|
|
void LauncherAppletWidget::slotSearch(const QString &text)
|
|
|
|
{
|
|
|
|
const QString query = text.trimmed();
|
|
|
|
if (query.isEmpty()) {
|
2024-04-17 00:04:35 +03:00
|
|
|
m_searchtimer->stop();
|
2024-04-12 03:33:58 +03:00
|
|
|
m_searchwidget->finish();
|
|
|
|
m_searchscrollwidget->setVisible(false);
|
|
|
|
m_tabbar->setVisible(true);
|
|
|
|
return;
|
|
|
|
}
|
2024-04-17 00:04:35 +03:00
|
|
|
if (!m_searchtimer->isActive()) {
|
2024-04-12 19:17:25 +03:00
|
|
|
m_searchwidget->prepare();
|
|
|
|
}
|
2024-04-17 00:04:35 +03:00
|
|
|
m_searchtimer->start();
|
|
|
|
}
|
|
|
|
|
|
|
|
void LauncherAppletWidget::slotUserTimeout()
|
|
|
|
{
|
|
|
|
const QString hostname = QHostInfo::localHostName();
|
|
|
|
QString usericon = m_user->faceIconPath();
|
|
|
|
if (usericon.isEmpty()) {
|
|
|
|
usericon = s_usericon;
|
|
|
|
}
|
2024-04-17 00:20:43 +03:00
|
|
|
// NOTE: the only way to force reload of the icon is to create an icon from pixmap created from
|
|
|
|
// image because QPixmap caches internally (the path may be the same but the data not)
|
|
|
|
m_iconwidget->setIcon(QIcon(QPixmap::fromImage(QImage(usericon))));
|
2024-04-17 00:04:35 +03:00
|
|
|
|
|
|
|
QString usertext;
|
|
|
|
QString fullusername = m_user->property(KUser::FullName);
|
|
|
|
if (fullusername.isEmpty()) {
|
|
|
|
usertext = i18nc("login name, hostname", "User <b>%1</b> on <b>%2</b>", m_user->loginName(), hostname);
|
|
|
|
} else {
|
|
|
|
usertext = i18nc("full name, login name, hostname", "<b>%1 (%2)</b> on <b>%3</b>", fullusername, m_user->loginName(), hostname);
|
|
|
|
}
|
|
|
|
m_label->setText(usertext);
|
2024-04-17 00:20:43 +03:00
|
|
|
|
|
|
|
// qDebug() << Q_FUNC_INFO << usericon << usertext;
|
2024-04-12 03:33:58 +03:00
|
|
|
}
|
|
|
|
|
2024-04-17 00:04:35 +03:00
|
|
|
void LauncherAppletWidget::slotSearchTimeout()
|
2024-04-12 03:33:58 +03:00
|
|
|
{
|
|
|
|
m_searchwidget->query(m_lineedit->text());
|
|
|
|
m_tabbar->setVisible(false);
|
|
|
|
m_searchscrollwidget->setVisible(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
LauncherApplet::LauncherApplet(QObject *parent, const QVariantList &args)
|
|
|
|
: Plasma::PopupApplet(parent, args),
|
2024-04-12 19:29:16 +03:00
|
|
|
m_launcherwidget(nullptr),
|
2024-04-15 17:54:25 +03:00
|
|
|
m_bookmarkmanager(nullptr),
|
2024-04-14 11:58:56 +03:00
|
|
|
m_editmenuaction(nullptr),
|
|
|
|
m_selector(nullptr),
|
|
|
|
m_shareconfig(nullptr)
|
2024-04-12 03:33:58 +03:00
|
|
|
{
|
|
|
|
KGlobal::locale()->insertCatalog("plasma_applet_launcher");
|
|
|
|
setPopupIcon(s_defaultpopupicon);
|
|
|
|
setAspectRatioMode(Plasma::IgnoreAspectRatio);
|
2024-04-14 11:58:56 +03:00
|
|
|
setHasConfigurationInterface(true);
|
2024-04-12 03:33:58 +03:00
|
|
|
|
2024-04-15 17:54:25 +03:00
|
|
|
const QString bookmarfile = KStandardDirs::locateLocal("data", "plasma/bookmarks.xml");
|
|
|
|
m_bookmarkmanager = KBookmarkManager::managerForFile(bookmarfile, "launcher");
|
|
|
|
// m_bookmarkmanager->slotEditBookmarks();
|
|
|
|
|
2024-04-12 03:33:58 +03:00
|
|
|
m_launcherwidget = new LauncherAppletWidget(this);
|
2024-04-13 16:03:57 +03:00
|
|
|
setFocusProxy(m_launcherwidget);
|
2024-04-12 03:33:58 +03:00
|
|
|
}
|
|
|
|
|
2024-04-12 19:29:16 +03:00
|
|
|
void LauncherApplet::init()
|
|
|
|
{
|
|
|
|
setGlobalShortcut(KShortcut(Qt::ALT+Qt::Key_F2));
|
2024-04-14 11:58:56 +03:00
|
|
|
m_shareconfig = KSharedConfig::openConfig(globalConfig().config()->name());
|
|
|
|
m_configgroup = m_shareconfig->group("Plugins");
|
|
|
|
m_launcherwidget->setAllowedRunners(kAllowedRunners(m_configgroup));
|
2024-04-12 19:29:16 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
QGraphicsWidget* LauncherApplet::graphicsWidget()
|
2024-04-12 03:33:58 +03:00
|
|
|
{
|
|
|
|
return m_launcherwidget;
|
|
|
|
}
|
|
|
|
|
2024-04-12 19:29:16 +03:00
|
|
|
QList<QAction*> LauncherApplet::contextualActions()
|
|
|
|
{
|
|
|
|
QList<QAction*> result;
|
|
|
|
const KService::Ptr service = KService::serviceByStorageId("kmenuedit");
|
|
|
|
if (!service.isNull()) {
|
|
|
|
if (!m_editmenuaction) {
|
|
|
|
m_editmenuaction = new QAction(this);
|
|
|
|
m_editmenuaction->setText(i18n("Edit Applications..."));
|
|
|
|
connect(
|
|
|
|
m_editmenuaction, SIGNAL(triggered()),
|
|
|
|
this, SLOT(slotEditMenu())
|
|
|
|
);
|
|
|
|
}
|
|
|
|
result.append(m_editmenuaction);
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2024-04-14 11:58:56 +03:00
|
|
|
void LauncherApplet::createConfigurationInterface(KConfigDialog *parent)
|
|
|
|
{
|
|
|
|
QWidget *widget = new QWidget();
|
|
|
|
m_selector = new KPluginSelector(widget);
|
|
|
|
m_selector->addPlugins(
|
|
|
|
Plasma::RunnerManager::listRunnerInfo(),
|
|
|
|
KPluginSelector::ReadConfigFile,
|
|
|
|
i18n("Available Plugins"), QString(),
|
|
|
|
m_shareconfig
|
|
|
|
);
|
|
|
|
connect(m_selector, SIGNAL(changed(bool)), parent, SLOT(settingsModified()));
|
|
|
|
parent->addPage(m_selector, i18n("Runners"), "preferences-plugin");
|
|
|
|
|
|
|
|
connect(parent, SIGNAL(applyClicked()), this, SLOT(slotConfigAccepted()));
|
|
|
|
connect(parent, SIGNAL(okClicked()), this, SLOT(slotConfigAccepted()));
|
|
|
|
}
|
|
|
|
|
2024-04-14 10:34:13 +03:00
|
|
|
void LauncherApplet::resetState()
|
|
|
|
{
|
|
|
|
hidePopup();
|
|
|
|
m_launcherwidget->resetSearch();
|
|
|
|
}
|
|
|
|
|
2024-04-15 17:54:25 +03:00
|
|
|
KBookmarkManager* LauncherApplet::bookmarkManager() const
|
|
|
|
{
|
|
|
|
return m_bookmarkmanager;
|
|
|
|
}
|
|
|
|
|
2024-04-12 19:29:16 +03:00
|
|
|
void LauncherApplet::slotEditMenu()
|
|
|
|
{
|
2024-04-13 15:48:06 +03:00
|
|
|
if (KToolInvocation::kdeinitExec("kmenuedit") == 0) {
|
|
|
|
hidePopup();
|
|
|
|
} else {
|
|
|
|
showMessage(KIcon("dialog-error"), i18n("Failed to launch menu editor"), Plasma::MessageButton::ButtonOk);
|
|
|
|
}
|
2024-04-12 19:29:16 +03:00
|
|
|
}
|
|
|
|
|
2024-04-14 11:58:56 +03:00
|
|
|
void LauncherApplet::slotConfigAccepted()
|
|
|
|
{
|
|
|
|
Q_ASSERT(m_selector != nullptr);
|
|
|
|
Q_ASSERT(m_shareconfig != nullptr);
|
|
|
|
m_selector->save();
|
|
|
|
m_configgroup.sync();
|
|
|
|
m_shareconfig->sync();
|
|
|
|
m_launcherwidget->setAllowedRunners(kAllowedRunners(m_configgroup));
|
|
|
|
m_launcherwidget->resetSearch();
|
|
|
|
emit configNeedsSaving();
|
|
|
|
}
|
|
|
|
|
2024-04-12 03:33:58 +03:00
|
|
|
#include "launcher.moc"
|
|
|
|
#include "moc_launcher.cpp"
|