kdeplasma-addons: remove icontasks applet

there shall be only one (official) applet for that task

Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
Ivailo Monev 2023-09-27 21:56:54 +03:00
parent e55350d4d5
commit 2f61410d65
43 changed files with 0 additions and 11449 deletions

View file

@ -26,5 +26,4 @@ add_subdirectory(systemloadviewer)
if(KDE4WORKSPACE_FOUND)
add_subdirectory(binary-clock)
add_subdirectory(fuzzy-clock)
add_subdirectory(icontasks)
endif()

View file

@ -1,52 +0,0 @@
set(tasks_SRCS
windowtaskitem.cpp
tasks.cpp
taskitemlayout.cpp
abstracttaskitem.cpp
taskgroupitem.cpp
applauncheritem.cpp
jobmanager.cpp
mediabuttons.cpp
dbusstatus.cpp
recentdocuments.cpp
tooltips/tooltipcontent.cpp
tooltips/tooltip.cpp
tooltips/tooltipmanager.cpp
tooltips/windowpreview.cpp
appearanceconfig.ui
behaviourconfig.ui
)
qt4_add_dbus_interface(tasks_SRCS org.mpris.MediaPlayer2.Player.xml playerv2interface)
set_source_files_properties(org.freedesktop.MediaPlayer.player.xml PROPERTIES INCLUDE "dbusstatus.h")
qt4_add_dbus_interface(tasks_SRCS org.freedesktop.MediaPlayer.player.xml playerv1interface)
kde4_add_plugin(plasma_applet_icontasks ${tasks_SRCS})
target_link_libraries(plasma_applet_icontasks
KDE4::kdeui
KDE4::plasma
KDE4::kio
KDE4Workspace::taskmanager
${X11_X11_LIB}
)
include_directories(${CMAKE_BINARY_DIR})
install(
TARGETS plasma_applet_icontasks
DESTINATION ${KDE4_PLUGIN_INSTALL_DIR}
)
install(
FILES plasma-applet-icontasks.desktop
DESTINATION ${KDE4_SERVICES_INSTALL_DIR}
)
install(
FILES badge.svgz launcherseparator.svgz progress.svgz indicators.svgz dropindicators.svgz
DESTINATION ${KDE4_DATA_INSTALL_DIR}/desktoptheme/default/icontasks/
)
install(
FILES mediabuttonsrc
DESTINATION ${KDE4_DATA_INSTALL_DIR}/kdeplasma-addons
)

View file

@ -1,3 +0,0 @@
#! /usr/bin/env bash
$EXTRACTRC *.ui >> rc.cpp
$XGETTEXT */*.cpp *.cpp -o $podir/plasma_applet_icontasks.pot

View file

@ -1,106 +0,0 @@
KDE Plasma Tasks Applet
=======================
This is a desktop applet for KDE Plasma which provides a view
of the user's running graphical tasks and allows them to
switch between these tasks.
It is intended as a replacement for the taskbar found in
KDE 3.
Goals
=====
This section describes the main goals of the tasks applet from the user's
perspective:
- Provide a clear, attractive visual depiction of the user's running graphical tasks
- Allow the user to navigate between tasks quickly
- Allow the user to group related tasks so that they can be operated on
as one*
1. Task representation
The information currently available from which a task representation can be
constructed:
- Window title
- A (typically small) pixmap
- The 'window class' of a window which can in some cases be used
to look up an appropriate icon for that application.
- Notifications about changes to a window's state (eg. raised,
lowered, wants attention)
This information is fairly limited. In order to provide more interesting
and useful representations in future, additional information will be
required.
- A reliable source for a scalable icon for the task
- Information about the documents associated with a task
- Information about the people associated with a task
2. Navigation between tasks
The tasks applet should try to make it as easy as possible
for the user to perform a 'context switch' between the different
tasks they are performing.
On a basic level, this means that:
- The user must be able to identify the task from a small
representation
- Easily activate a task's representation which causes the
corresponding window to be raised and placed at the top
of the screen.
Note: One of the flaws of KDE 3's Kicker is that task
representations are placed in a 2-task high grid
at one edge of the screen. This means that only half
of the task representations touch the screen edge and as a result
only half of them benefit from the 'infinite size' of a screen
edge with respect to activating it with the mouse.
In the KDE 3.5.x series there is a bug in Kicker where the
colour of the text for a minimized task is grey, against what
is usually a grey/silverish panel background. This makes the
text difficult to read.
Navigation between tasks usually occurs for two reasons:
A) The user decides to switch to a different task of their own
volition.
Example: Greg has been writing a business letter to a client,
he decides he wishes to take a break for twenty minutes
during which he intends to listen to music and read
the latest news online.
He therefore wishes to switch away from the word document
and email related to that letter to his music player and
feed reader.
B) An external interruption
Example: Paul is watching the latest episode of a TV drama online when
he is alerted by his messaging client that a friend he wants
to talk to has come online. Paul then wishes to switch
away from the TV episode he is watching and start a conversation
with his friend.
3. Grouping
This is intended to be the main area of innovation in the KDE Plasma
'taskbar' versus that found in KDE 3, Gnome, Windows, and Mac OS X.
Some of these windows are likely to be related to the same logical
activity from the user's point of view. For example, a paper which
the user is writing and the various research material used to
write that paper.
The idea is to allow the user to easily group these related tasks
so that he can treat them as one. That is, bringing all of them
to the front, closing all of them or layout out the windows within
a group so that they are all visible on screen at the same time
and can be worked with together.

File diff suppressed because it is too large Load diff

View file

@ -1,291 +0,0 @@
/***************************************************************************
* Copyright (C) 2007 by Robert Knight <robertknight@gmail.com> *
* Copyright (C) 2008 by Alexis Ménard <darktears31@gmail.com> *
* Copyright (C) 2008 by Marco Martin <notmart@gmail.com> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* 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 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 . *
***************************************************************************/
#ifndef ABSTRACTTASKITEM_H
#define ABSTRACTTASKITEM_H
// KDE
#include <KColorScheme>
#include <KUrl>
// Own
#include "taskmanager/taskgroup.h"
// Katie
#include <QElapsedTimer>
#include <QIcon>
#include <QGraphicsSceneDragDropEvent>
#include <QGraphicsWidget>
#include <QPropertyAnimation>
#include <QTextOption>
#include <QTextLayout>
#include <QString>
#include <QAction>
// Plasma
#include <Plasma/Animator>
class Tasks;
class TaskGroupItem;
class LayoutWidget;
/**
* A baseclass for a task
*/
class AbstractTaskItem : public QGraphicsWidget
{
Q_OBJECT
Q_PROPERTY(QPointF animationPos READ animationPos WRITE setAnimationPos)
Q_PROPERTY(qreal backgroundFadeAlpha READ backgroundFadeAlpha WRITE setBackgroundFadeAlpha)
public:
enum InfoSource {
IS_None,
IS_Job
};
enum Cache {
Cache_Bgnd = 0x01,
Cache_Scale = 0x02,
Cache_All = Cache_Bgnd | Cache_Scale
};
static void clearCaches(int cache = Cache_All);
/** Constructs a new representation for an abstract task. */
AbstractTaskItem(QGraphicsWidget *parent, Tasks *applet);
/** Destruct the representation for an abstract task. */
virtual ~AbstractTaskItem();
/** The text changed for this task item. */
void textChanged();
/** Sets the icon for this task item. */
void setIcon(const QIcon &icon);
/**
* This enum describes the generic flags which are currently
* set by the task.
*/
enum TaskFlag {
/**
* This flag is set by the task to indicate that it wants
* the user's attention.
*/
TaskWantsAttention = 1,
/**
* Indicates that the task's window has the focus
*/
TaskHasFocus = 2,
/**
* Indicates that the task is iconified
*/
TaskIsMinimized = 4
};
Q_DECLARE_FLAGS(TaskFlags, TaskFlag)
/** Sets the task flags for this item. */
void setTaskFlags(TaskFlags flags);
/** Returns the task's current flags. */
TaskFlags taskFlags() const;
/** Returns current text for this task. */
virtual QString text() const;
/** Returns the current icon for this task. */
QIcon icon() const;
virtual void close() = 0;
/** Tells the window manager the minimized task's geometry. */
virtual void publishIconGeometry() const;
virtual void publishIconGeometry(const QRect &rect) const;
QRect iconGeometry() const; // helper for above
/** Overridden from LayoutItem */
void setGeometry(const QRectF& geometry);
/** Convenience Functions to get information about Grouping */
/** Only true if the task is not only member of rootGroup */
bool isGrouped() const;
bool isGroupMember(const TaskGroupItem *group) const;
TaskGroupItem *parentGroup() const;
virtual bool isWindowItem() const = 0;
virtual bool isActive() const = 0;
virtual void setAdditionalMimeData(QMimeData* mimeData) = 0;
void setLayoutWidget(LayoutWidget* widget);
TaskManager::AbstractGroupableItem * abstractItem();
/** Returns the preferred size calculated on base of the fontsize and the iconsize*/
QSize basicPreferredSize() const;
void setPreferredOffscreenSize();
void setPreferredOnscreenSize();
//TODO: to be removed when we have proper animated layouts
QPointF animationPos() const;
void setAnimationPos(const QPointF &pos);
virtual QGraphicsWidget *busyWidget() const {
return 0L;
}
bool isStartupWithTask() const;
bool isToolTipVisible() const;
virtual void showContextMenu(const QPoint &, bool) { }
virtual QString appName() const = 0;
virtual KUrl launcherUrl() const = 0;
virtual QString windowClass() const = 0;
void updateProgress(int v, InfoSource source = IS_Job);
virtual int pid() const {
return 0;
}
virtual void toCurrentDesktop() { }
QString mediaButtonKey();
Q_SIGNALS:
void activated(AbstractTaskItem *);
void destroyed(AbstractTaskItem *);
public Q_SLOTS:
virtual void activate() = 0;
void toolTipAboutToShow();
void toolTipHidden();
void mediaButtonPressed(int b);
void windowPreviewActivated(WId id, Qt::MouseButtons buttons, Qt::KeyboardModifiers, const QPoint &pos);
void controlWindow(WId id, Qt::MouseButtons buttons);
protected:
void middleClick();
void dragEnterEvent(QGraphicsSceneDragDropEvent *event);
void dragMoveEvent(QGraphicsSceneDragDropEvent *event);
void dragLeaveEvent(QGraphicsSceneDragDropEvent *event);
// reimplemented
void focusInEvent(QFocusEvent *event);
void focusOutEvent(QFocusEvent *event);
void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
void mousePressEvent(QGraphicsSceneMouseEvent *event);
void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
void timerEvent(QTimerEvent *event);
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
void drawProgress(QPainter *painter, const QRectF &rect);
void drawBadge(QPainter *painter, const QRectF &rect, const QString &badge);
void drawIndicators(QPainter *painter, const QRectF &rect);
void drawColoredBackground(QPainter *painter, const QStyleOptionGraphicsItem *option);
void drawShine(QPainter *painter, const QStyleOptionGraphicsItem *option);
/** Draws the background for the task item. */
virtual void drawBackground(QPainter *painter, const QStyleOptionGraphicsItem *option);
/** Draws the icon and text which represent the task item. */
virtual void drawTask(QPainter *painter, const QStyleOptionGraphicsItem *option, bool showText);
virtual void updateTask(::TaskManager::TaskChanges changes) = 0; // pure virtual function
virtual void updateToolTip() = 0; // pure virtual function
void updateToolTipMediaState();
void clearToolTip();
void stopWindowHoverEffect();
bool shouldIgnoreDragEvent(QGraphicsSceneDragDropEvent *event);
QList<QAction *> getAppMenu();
void registerWithHelpers();
void unregisterFromHelpers();
protected Q_SLOTS:
/** Event compression **/
void queueUpdate();
qreal backgroundFadeAlpha() const;
void setBackgroundFadeAlpha(qreal progress);
void syncActiveRect();
void checkSettings();
void clearAbstractItem();
protected:
// area of item occupied by task's icon
QRectF iconRect(const QRectF &bounds, bool showText = false);
QSize iconSize(const QRectF &bounds) const;
// area of item occupied by task's text
QRectF textRect(const QRectF &bounds);
// start an animation to chnge the task background
void fadeBackground(const QString &newBackground, int duration);
// text color, use this because it could be animated
QColor textColor() const;
void resizeBackground(const QSize &size);
void resizeEvent(QGraphicsSceneResizeEvent *event);
TaskManager::AbstractGroupableItem * m_abstractItem;
LayoutWidget *m_layoutWidget;
Tasks *m_applet;
TaskFlags m_flags;
// distance (in pixels) between a task's icon and its text
static const int IconTextSpacing = 4;
static const int TaskItemHorizontalMargin = 4;
static const int TaskItemVerticalMargin = 4;
//TODO: remove when we have animated layouts
QPropertyAnimation *m_layoutAnimation;
QPropertyAnimation *m_backgroundFadeAnim;
qreal m_alpha;
QString m_oldBackgroundPrefix;
QString m_backgroundPrefix;
private:
QRectF m_activeRect;
QElapsedTimer m_lastGeometryUpdate;
QElapsedTimer m_lastUpdate;
QSize m_lastIconSize;
int m_activateTimerId;
int m_updateGeometryTimerId;
int m_updateTimerId;
int m_hoverEffectTimerId;
int m_attentionTimerId;
int m_attentionTicks;
int m_mediaStateTimerId;
WId m_lastViewId;
bool m_layoutAnimationLock : 1;
bool m_firstGeometryUpdate : 1;
mutable QIcon m_icon;
InfoSource m_progressSource;
int m_lastProgress;
int m_currentProgress;
QPointF m_oldDragPos;
};
#endif

View file

@ -1,260 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>appearanceconfig</class>
<widget class="QWidget" name="appearanceconfig">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>480</width>
<height>283</height>
</rect>
</property>
<layout class="QFormLayout" name="formLayout">
<property name="margin">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="style_label">
<property name="text">
<string>Style:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="style"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="rotate_label">
<property name="text">
<string>Rotate vertical frames:</string>
</property>
<property name="buddy">
<cstring>rotate</cstring>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="rotate">
<property name="toolTip">
<string>&lt;p&gt;Controls whether the frames drawn around taskbar entries should be rotated 90-degrees counter-clockwise when the taskbar is in a vertical panel.&lt;/p&gt;</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="toolTips_label">
<property name="text">
<string>Tooltips:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>toolTips</cstring>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="toolTips"/>
</item>
<item row="3" column="0">
<widget class="QLabel" name="previewSize_label">
<property name="text">
<string>Window preview size:</string>
</property>
<property name="buddy">
<cstring>previewSize</cstring>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="KIntSpinBox" name="previewSize">
<property name="toolTip">
<string>&lt;p&gt;Controls the width of window previews with tooltips.&lt;/p&gt;</string>
</property>
<property name="suffix">
<string>px</string>
</property>
<property name="prefix">
<string/>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="launcherIcons_label">
<property name="text">
<string>Always use launcher icons:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>launcherIcons</cstring>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QCheckBox" name="launcherIcons">
<property name="toolTip">
<string>&lt;p&gt;Enabling this item forces the icon for a running application to be the same as that used for the launcher. This resolves some oddities where the launcher icon is different from the application icon - as happens with LibreOffice.&lt;/p&gt;</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="iconScale_label">
<property name="text">
<string>Scale icons to:</string>
</property>
<property name="buddy">
<cstring>iconScale</cstring>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="KIntSpinBox" name="iconScale">
<property name="toolTip">
<string>&lt;p&gt;Controls the scaling of the taskbar icon. When set to &amp;quot;Automatic&amp;quot;, the taskbar will attempt to determine the optimal size.&lt;/p&gt;</string>
</property>
<property name="suffix">
<string>%</string>
</property>
<property name="value">
<number>10</number>
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QLabel" name="spacing_label">
<property name="text">
<string>Spacing:</string>
</property>
<property name="buddy">
<cstring>spacing</cstring>
</property>
</widget>
</item>
<item row="7" column="1">
<widget class="KIntSpinBox" name="spacing">
<property name="toolTip">
<string>&lt;p&gt;Set the amount of extra spacing between items.&lt;/p&gt;</string>
</property>
<property name="suffix">
<string>px</string>
</property>
<property name="prefix">
<string/>
</property>
<property name="value">
<number>0</number>
</property>
</widget>
</item>
<item row="8" column="0">
<widget class="QLabel" name="maxRows_label">
<property name="text">
<string>Maximum rows:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>maxRows</cstring>
</property>
</widget>
</item>
<item row="8" column="1">
<widget class="KIntSpinBox" name="maxRows">
<property name="toolTip">
<string>&lt;p&gt;Controls the maximum number of rows (for a horizontal taskbar), or columns (for a vertical taskbar), that will be used.&lt;/p&gt;</string>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="value">
<number>2</number>
</property>
</widget>
</item>
<item row="9" column="0">
<widget class="QLabel" name="sortingStrategy_label">
<property name="text">
<string>Sorting:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>sortingStrategy</cstring>
</property>
</widget>
</item>
<item row="9" column="1">
<widget class="QComboBox" name="sortingStrategy">
<property name="minimumSize">
<size>
<width>200</width>
<height>0</height>
</size>
</property>
</widget>
</item>
<item row="10" column="0">
<widget class="QLabel" name="showSeparator_label">
<property name="text">
<string>Separator:</string>
</property>
<property name="buddy">
<cstring>showSeparator</cstring>
</property>
</widget>
</item>
<item row="10" column="1">
<widget class="QComboBox" name="showSeparator">
<property name="toolTip">
<string>&lt;p&gt;When enabled, and there is only 1 row/column, then a separator will be drawn between the launchers/tasks-with-launchers and non-launcher tasks.&lt;/p&gt;</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="highlightWindows_label">
<property name="text">
<string>Highlight windows:</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QCheckBox" name="highlightWindows">
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>KIntSpinBox</class>
<extends>QSpinBox</extends>
<header>knuminput.h</header>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>style</tabstop>
<tabstop>rotate</tabstop>
<tabstop>toolTips</tabstop>
<tabstop>previewSize</tabstop>
<tabstop>launcherIcons</tabstop>
<tabstop>iconScale</tabstop>
<tabstop>spacing</tabstop>
<tabstop>maxRows</tabstop>
<tabstop>sortingStrategy</tabstop>
<tabstop>showSeparator</tabstop>
</tabstops>
<connections/>
</ui>

View file

@ -1,149 +0,0 @@
/***************************************************************************
* Copyright (C) 2010 by Anton Kreuzkamp <akreuzkamp@web.de> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* 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 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 . *
***************************************************************************/
// Own
#include "applauncheritem.h"
#include "taskgroupitem.h"
#include "jobmanager.h"
#include "mediabuttons.h"
#include "taskmanager/taskactions.h"
#include "taskmanager/groupmanager.h"
// Qt
#include <QtGui/qgraphicssceneevent.h>
#include <QGraphicsView>
// KDE
#include <KIconEffect>
#include "tooltips/tooltipmanager.h"
#include <Plasma/Corona>
#include <Plasma/Containment>
#include <Plasma/PaintUtils>
QString AppLauncherItem::mimetype()
{
return "taskmanager:/launcher";
}
AppLauncherItem::AppLauncherItem(QGraphicsWidget* parent, Tasks* applet, TaskManager::LauncherItem* launcher)
: AbstractTaskItem(parent, applet)
{
m_launcher = launcher;
m_abstractItem = launcher;
registerWithHelpers();
}
AppLauncherItem::~AppLauncherItem()
{
close(false);
}
void AppLauncherItem::close()
{
close(true);
}
void AppLauncherItem::close(bool hide)
{
unregisterFromHelpers();
if (hide) {
setVisible(false);
}
}
QString AppLauncherItem::windowClass() const
{
return m_applet->groupManager().launcherWmClass(launcherUrl());
}
void AppLauncherItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
if ((event->button() == Qt::LeftButton || (event->button() == Qt::MiddleButton && Tasks::MC_NewInstance == m_applet->middleClick())) &&
boundingRect().contains(event->pos())) {
m_launcher->launch();
}
}
void AppLauncherItem::contextMenuEvent(QGraphicsSceneContextMenuEvent *e)
{
if (!m_launcher) {
QGraphicsWidget::contextMenuEvent(e);
return;
}
QList <QAction*> actionList;
QAction *configAction = m_applet->action("configure");
if (configAction && configAction->isEnabled()) {
actionList.append(configAction);
}
TaskManager::BasicMenu *menu = new TaskManager::BasicMenu(0, m_launcher, &m_applet->groupManager(), actionList, getAppMenu());
menu->adjustSize();
if (m_applet->formFactor() != Plasma::Vertical) {
menu->setMinimumWidth(size().width());
}
Q_ASSERT(m_applet->containment());
Q_ASSERT(m_applet->containment()->corona());
stopWindowHoverEffect();
menu->exec(m_applet->containment()->corona()->popupPosition(this, menu->size()));
menu->deleteLater();
}
void AppLauncherItem::updateToolTip()
{
IconTasks::ToolTipContent data(m_launcher->name(), m_launcher->genericName(), m_launcher->icon());
data.setInstantPopup(m_applet->instantToolTip());
QString key = mediaButtonKey();
if (!key.isEmpty()) {
data.setPlayState(MediaButtons::self()->playbackStatus(key));
data.setClickable(true);
}
IconTasks::ToolTipManager::self()->setContent(this, data);
}
void AppLauncherItem::keyPressEvent(QKeyEvent *event)
{
if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) {
m_launcher->launch();
} else {
QGraphicsWidget::keyPressEvent(event);
}
}
void AppLauncherItem::setAdditionalMimeData(QMimeData* mimeData)
{
if (m_launcher) {
m_launcher->addMimeData(mimeData);
// Add our own mimetype, so that AbstractTaskItem knows to ignore drag envets of this type,
// then taskgroup will receive the event, and launchers can be re-ordered!!!
QByteArray data;
mimeData->setData(mimetype(), data);
}
}
#include "moc_applauncheritem.cpp"

View file

@ -1,83 +0,0 @@
/***************************************************************************
* Copyright (C) 2010 by Anton Kreuzkamp <akreuzkamp@web.de> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* 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 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 . *
***************************************************************************/
#ifndef APPLAUNCHERITEM_H
#define APPLAUNCHERITEM_H
#include "abstracttaskitem.h"
// Own
#include "taskmanager/taskmanager.h"
#include "taskmanager/launcheritem.h"
/**
* A launcheritem to quickly launch applications.
*/
class AppLauncherItem : public AbstractTaskItem
{
Q_OBJECT
public:
/** Constructs a new representation for a launcher. */
AppLauncherItem(QGraphicsWidget *parent, Tasks *applet, TaskManager::LauncherItem *launcher);
~AppLauncherItem();
TaskManager::LauncherItem* launcher() {
return m_launcher;
}
virtual bool isWindowItem() const {
return false;
}
virtual bool isActive() const {
return false;
}
virtual void setAdditionalMimeData(QMimeData* mimeData);
virtual void close();
virtual void updateTask(TaskManager::TaskChanges) {}
static QString mimetype();
QString appName() const {
return m_launcher->name();
}
KUrl launcherUrl() const {
return m_launcher->launcherUrl();
}
QString windowClass() const;
private:
void close(bool hide);
public slots:
virtual void activate() {}
protected:
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
void keyPressEvent(QKeyEvent *event);
void contextMenuEvent(QGraphicsSceneContextMenuEvent *event);
void updateToolTip();
private:
TaskManager::LauncherItem *m_launcher;
};
#endif

View file

@ -1,207 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>behaviourconfig</class>
<widget class="QWidget" name="behaviourconfig">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>341</width>
<height>274</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="margin">
<number>0</number>
</property>
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>General</string>
</property>
<layout class="QFormLayout" name="formLayout_2">
<item row="0" column="0">
<widget class="QLabel" name="showProgress_label">
<property name="text">
<string>Show job progress on task icon:</string>
</property>
<property name="buddy">
<cstring>showProgress</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="showProgress">
<property name="toolTip">
<string>&lt;p&gt;When enabled, a progressbar will be drawn over the applications icons to represent its overall job progress.&lt;/p&gt;</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="mediaButtons_label">
<property name="text">
<string>Show control buttons on media player tooltips:</string>
</property>
<property name="buddy">
<cstring>mediaButtons</cstring>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="mediaButtons">
<property name="toolTip">
<string>&lt;p&gt;When enabled - previous, play/pause, and next buttons will be shown in the tooltips for media players.&lt;/p&gt;</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="recentDocuments_label">
<property name="text">
<string>Show recent documents:</string>
</property>
<property name="buddy">
<cstring>recentDocuments</cstring>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QCheckBox" name="recentDocuments">
<property name="toolTip">
<string>&lt;p&gt;Toggles support for listing an application's recent documents in its popup menu.&lt;/p&gt;</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="groupClick_label">
<property name="text">
<string>Group click action:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>groupClick</cstring>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QComboBox" name="groupClick">
<property name="toolTip">
<string>&lt;p&gt;Configures what should occur when a task group is clicked.&lt;/p&gt;</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="middleClick_label">
<property name="text">
<string>Middle-click action:</string>
</property>
<property name="buddy">
<cstring>middleClick</cstring>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QComboBox" name="middleClick"/>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>Filters</string>
</property>
<layout class="QFormLayout" name="formLayout">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::ExpandingFieldsGrow</enum>
</property>
<item row="0" column="0">
<widget class="QLabel" name="showOnlyCurrentScreen_label">
<property name="text">
<string>Only show tasks from the current screen:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>showOnlyCurrentScreen</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="showOnlyCurrentScreen">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="showOnlyCurrentDesktop_label">
<property name="text">
<string>Only show tasks from the current desktop:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>showOnlyCurrentDesktop</cstring>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="showOnlyCurrentDesktop">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="showOnlyCurrentActivity_label">
<property name="text">
<string>Only show tasks from the current activity:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>showOnlyCurrentActivity</cstring>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QCheckBox" name="showOnlyCurrentActivity">
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>2</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<connections/>
</ui>

View file

@ -1,46 +0,0 @@
/*
* Icon Task Manager
*
* Copyright 2011 Craig Drummond <craig@kde.org>
*
* ----
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* 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 General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "dbusstatus.h"
QDBusArgument& operator<< (QDBusArgument& arg, const DBusStatus& status)
{
arg.beginStructure();
arg << status.play;
arg << status.random;
arg << status.repeat;
arg << status.repeat_playlist;
arg.endStructure();
return arg;
}
const QDBusArgument& operator>> (const QDBusArgument& arg, DBusStatus& status)
{
arg.beginStructure();
arg >> status.play;
arg >> status.random;
arg >> status.repeat;
arg >> status.repeat_playlist;
arg.endStructure();
return arg;
}

View file

@ -1,47 +0,0 @@
/*
* Icon Task Manager
*
* Copyright 2011 Craig Drummond <craig@kde.org>
*
* ----
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* 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 General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef __DBUS_STATUS_H__
#define __DBUS_STATUS_H__
#include <QtCore/QObject>
#include <QtDBus/QDBusArgument>
struct DBusStatus { // From Amarok.
int play; // Playing = 0, Paused = 1, Stopped = 2
int random; // Linearly = 0, Randomly = 1
int repeat; // Go_To_Next = 0, Repeat_Current = 1
int repeat_playlist; // Stop_When_Finished = 0, Never_Give_Up_Playing = 1, Never_Let_You_Down = 42
enum MprisPlayState {
Mpris_Playing = 0,
Mpris_Paused = 1,
Mpris_Stopped = 2,
};
};
Q_DECLARE_METATYPE(DBusStatus)
QDBusArgument& operator <<(QDBusArgument& arg, const DBusStatus& status);
const QDBusArgument& operator >>(const QDBusArgument& arg, DBusStatus& status);
#endif

View file

@ -1,197 +0,0 @@
/*
* Icon Task Manager
*
* Copyright 2011 Craig Drummond <craig@kde.org>
*
* ----
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* 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 General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "jobmanager.h"
#include "abstracttaskitem.h"
#include "tasks.h"
#include <KGlobal>
#include <Plasma/DataEngineManager>
K_GLOBAL_STATIC(JobManager, jobMgr)
static const char *constEngineName = "applicationjobs";
JobManager * JobManager::self()
{
return jobMgr;
}
JobManager::JobManager()
: m_engine(0)
{
}
JobManager::~JobManager()
{
}
void JobManager::setEnabled(bool enabled)
{
if ((m_engine && !enabled) || (enabled && !m_engine)) {
if (enabled) {
m_engine = Plasma::DataEngineManager::self()->loadEngine(constEngineName);
if (!m_engine->isValid()) {
Plasma::DataEngineManager::self()->unloadEngine(constEngineName);
m_engine = 0;
return;
}
connect(m_engine, SIGNAL(sourceAdded(const QString)), this, SLOT(addJob(const QString)));
connect(m_engine, SIGNAL(sourceRemoved(const QString)), this, SLOT(removeJob(const QString)));
m_engine->connectAllSources(this);
} else if (m_engine) {
disconnect(m_engine, SIGNAL(sourceAdded(const QString)), this, SLOT(addJob(const QString)));
disconnect(m_engine, SIGNAL(sourceRemoved(const QString)), this, SLOT(removeJob(const QString)));
QMap<QString, QSet<QString> >::Iterator it(m_appJobs.begin()),
end(m_appJobs.end());
for (; it != end; ++it) {
foreach (const QString & job, *it) {
m_engine->disconnectSource(job, this);
}
}
Plasma::DataEngineManager::self()->unloadEngine(constEngineName);
m_appJobs.clear();
m_jobs.clear();
m_engine = 0;
}
}
}
void JobManager::registerTask(AbstractTaskItem *task)
{
QString appName(task->appName());
if (!appName.isEmpty()) {
m_tasks[appName].append(task);
if (m_appJobs.contains(appName)) {
task->updateProgress(appProgress(appName));
}
}
}
void JobManager::unregisterTask(AbstractTaskItem *task)
{
// Remove each reference to task...
QMap<QString, QList<AbstractTaskItem *> >::Iterator it(m_tasks.begin()),
end(m_tasks.end());
QStringList emptied;
for (; it != end; ++it) {
if ((*it).contains(task)) {
(*it).removeAll(task);
if (0 == (*it).count()) {
emptied.append(it.key());
}
}
}
foreach (const QString & app, emptied) {
m_tasks.remove(app);
}
}
void JobManager::addJob(const QString &job)
{
m_engine->connectSource(job, this);
}
void JobManager::dataUpdated(const QString &job, const Plasma::DataEngine::Data &data)
{
QString appName = data["appName"].toString();
if (appName.isEmpty()) {
return;
}
int percentage = data.contains("percentage") ? data["percentage"].toInt() : -1;
if (m_appJobs.contains(appName)) {
m_appJobs[appName].insert(job);
}
m_jobs[job] = percentage;
update(appName);
}
void JobManager::removeJob(const QString &job)
{
m_jobs.remove(job);
QMap<QString, QSet<QString> >::Iterator it(m_appJobs.begin()),
end(m_appJobs.end());
QStringList updated,
emptied;
for (; it != end; ++it) {
if ((*it).contains(job)) {
(*it).remove(job);
if (0 == (*it).count()) {
emptied.append(it.key());
} else {
updated.append(it.key());
}
}
}
foreach (const QString & app, emptied) {
m_appJobs.remove(app);
update(app);
}
foreach (const QString & app, updated) {
update(app);
}
}
int JobManager::appProgress(const QString &app)
{
int numJobs = 0,
total = 0;
foreach (const QString & job, m_appJobs[app]) {
int p = m_jobs[job];
if (-1 != p) {
numJobs++;
total += p;
}
}
return 0 == numJobs ? -1 : total / numJobs;
}
void JobManager::update(const QString &app)
{
if (m_tasks.contains(app)) {
int p = appProgress(app);
foreach (AbstractTaskItem * item, m_tasks[app]) {
item->updateProgress(p);
}
}
}
#include "moc_jobmanager.cpp"

View file

@ -1,72 +0,0 @@
#ifndef _JOB_MANAGER_H__
#define _JOB_MANAGER_H__
/*
* Icon Task Manager
*
* Copyright 2011 Craig Drummond <craig@kde.org>
*
* ----
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* 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 General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include <QtCore/QObject>
#include <QtCore/QMap>
#include <QtCore/QString>
#include <QtCore/QSet>
#include <Plasma/DataEngine>
class AbstractTaskItem;
class JobManager : public QObject
{
Q_OBJECT
public:
static JobManager * self();
JobManager();
~JobManager();
void setEnabled(bool enabled);
bool isEnabled() const {
return 0 != m_engine;
}
void registerTask(AbstractTaskItem *task);
void unregisterTask(AbstractTaskItem *task);
private Q_SLOTS:
void addJob(const QString &job);
void dataUpdated(const QString &job, const Plasma::DataEngine::Data &data);
void removeJob(const QString &job);
private:
int appProgress(const QString &app);
void update(const QString &app);
private:
Plasma::DataEngine *m_engine;
QMap<QString, QSet<QString> > m_appJobs; // Map from appName to list of job names
QMap<QString, int> m_jobs; // Map from job name to job percentage
QMap<QString, QList<AbstractTaskItem *> > m_tasks;
};
#endif

View file

@ -1,364 +0,0 @@
/*
* Icon Task Manager
*
* Copyright 2011 Craig Drummond <craig@kde.org>
*
* ----
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* 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 General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "mediabuttons.h"
#include "dbusstatus.h"
#include "playerv1interface.h"
#include "playerv2interface.h"
#include <KConfig>
#include <KConfigGroup>
#include <KGlobal>
#include <KStandardDirs>
#include <KSycoca>
#include <KService>
#include <KServiceTypeTrader>
#include <QtDBus/QDBusServiceWatcher>
#include <QtDBus/QDBusConnection>
#include <QtDBus/QDBusConnectionInterface>
#include <QDebug>
K_GLOBAL_STATIC(MediaButtons, mediaBtns)
static const QString constV2Prefix = QLatin1String("org.mpris.MediaPlayer2.");
static const QString constV1Prefix = QLatin1String("org.mpris.");
static QString playbackStatus(OrgFreedesktopMediaPlayerInterface *iface)
{
DBusStatus status = iface->GetStatus();
switch (status.play) {
case DBusStatus::Mpris_Playing: return "Playing";
case DBusStatus::Mpris_Paused: return "Paused";
case DBusStatus::Mpris_Stopped: return "Stopped";
}
return QString();
}
MediaButtons::Interface::~Interface()
{
if (v1) {
delete v1;
}
if (v2) {
delete v2;
}
}
void MediaButtons::Interface::next()
{
if (v2) {
v2->Next();
} else if (v1) {
v1->Next();
}
}
void MediaButtons::Interface::previous()
{
if (v2) {
v2->Previous();
} else if (v1) {
v1->Prev();
}
}
void MediaButtons::Interface::playPause()
{
if (v2) {
v2->PlayPause();
} else if (v1) {
if ("Playing" ==::playbackStatus(v1)) {
v1->Pause();
} else {
v1->Play();
}
}
}
QString MediaButtons::Interface::playbackStatus()
{
if (v2) {
return v2->playbackStatus();
} else if (v1) {
return ::playbackStatus(v1);
}
return QString();
}
QString MediaButtons::Interface::service()
{
if (v2) {
return v2->service();
} else if (v1) {
return v1->service();
}
return QString();
}
MediaButtons * MediaButtons::self()
{
return mediaBtns;
}
MediaButtons::MediaButtons()
: m_watcher(0)
, m_enabled(false)
{
qDBusRegisterMetaType<DBusStatus>();
}
void MediaButtons::setEnabled(bool en)
{
if (en != m_enabled) {
m_enabled = en;
if (m_enabled) {
m_watcher = new QDBusServiceWatcher(this);
m_watcher->setConnection(QDBusConnection::sessionBus());
m_watcher->setWatchMode(QDBusServiceWatcher::WatchForOwnerChange);
connect(m_watcher, SIGNAL(serviceOwnerChanged(QString, QString, QString)), this, SLOT(serviceOwnerChanged(QString, QString, QString)));
readConfig();
} else if (m_watcher) {
disconnect(m_watcher, SIGNAL(serviceOwnerChanged(QString, QString, QString)), this, SLOT(serviceOwnerChanged(QString, QString, QString)));
foreach (Interface * iface, m_interfaces.values()) {
delete iface;
}
m_interfaces.clear();
delete m_watcher;
}
}
}
void MediaButtons::serviceOwnerChanged(const QString &name, const QString &oldOwner, const QString &newOwner)
{
bool isV2 = name.startsWith(constV2Prefix);
QString n = QString(name).remove(isV2 ? constV2Prefix : constV1Prefix).toLower();
QMap<QString, Interface *>::iterator it(m_interfaces.find(n)),
end(m_interfaces.end());
if (newOwner.isEmpty()) {
if (it != end) {
if ((*it)->isV2() == isV2) {
delete(*it);
m_interfaces.erase(it);
}
}
} else if (oldOwner.isEmpty()) {
if (isV2) {
OrgMprisMediaPlayer2PlayerInterface *iface = new OrgMprisMediaPlayer2PlayerInterface(name, "/org/mpris/MediaPlayer2", QDBusConnection::sessionBus(), this);
if (iface->canControl()) {
if (it != end) {
delete(*it);
m_interfaces.erase(it);
}
m_interfaces.insert(n, new Interface(iface));
} else {
delete iface;
}
} else if (it == end || !(*it)->isV2()) {
OrgFreedesktopMediaPlayerInterface *iface = new OrgFreedesktopMediaPlayerInterface(name, "/Player", QDBusConnection::sessionBus(), this);
if (it != end) {
delete(*it);
m_interfaces.erase(it);
}
m_interfaces.insert(n, new Interface(iface));
}
}
}
void MediaButtons::next(const QString &name, int pid)
{
if (m_enabled) {
Interface *iface = getInterface(name, pid);
if (iface) {
iface->next();
}
}
}
void MediaButtons::previous(const QString &name, int pid)
{
if (m_enabled) {
Interface *iface = getInterface(name, pid);
if (iface) {
iface->previous();
}
}
}
void MediaButtons::playPause(const QString &name, int pid)
{
if (m_enabled) {
Interface *iface = getInterface(name, pid);
if (iface) {
iface->playPause();
}
}
}
QString MediaButtons::playbackStatus(const QString &name, int pid)
{
if (m_enabled) {
Interface *iface = getInterface(name, pid);
if (iface) {
return iface->playbackStatus();
}
}
return QString();
}
void MediaButtons::readConfig()
{
m_aliases.clear();
m_ignore.clear();
QStringList files(KGlobal::dirs()->findAllResources("data", "kdeplasma-addons/mediabuttonsrc"));
foreach (const QString &file, files) {
KConfig cfg(file);
KConfigGroup ag(&cfg, "Aliases");
KConfigGroup gen(&cfg, "General");
m_ignore += gen.readEntry("Ignore", QStringList()).toSet();
foreach (const QString &key, ag.keyList()) {
foreach (const QString &alias, ag.readEntry(key, QStringList())) {
m_aliases[alias.toLower()] = key.toLower();
}
}
}
}
bool MediaButtons::isMediaApp(const QString &desktopEntry)
{
if (!m_enabled) {
return false;
}
QString name = desktopEntry;
if (m_aliases.contains(name)) {
name = m_aliases[name];
}
if (m_ignore.contains(name)) {
return false;
}
MediaButtons::Interface *i = getV2Interface(name);
// qDebug() << Q_FUNC_INFO << desktopEntry << i;
if (i) {
return true;
}
i = getV1Interface(name);
// qDebug() << Q_FUNC_INFO << desktopEntry << i;
if (i) {
return true;
}
return false;
}
MediaButtons::Interface * MediaButtons::getInterface(const QString &name, int pid)
{
QStringList names;
if (m_aliases.contains(name)) {
QString alias = m_aliases[name];
names << alias << alias + "." + QString::number(pid) << alias + "-" + QString::number(pid);
}
names << name << name + "." + QString::number(pid) << name + "-" + QString::number(pid);
foreach (const QString &n, names) {
if (m_interfaces.contains(n)) {
return m_interfaces[n];
}
}
foreach (const QString &n, names) {
MediaButtons::Interface *i = getV2Interface(n);
if (i) {
return i;
}
}
foreach (const QString &n, names) {
MediaButtons::Interface *i = getV1Interface(n);
if (i) {
return i;
}
}
return nullptr;
}
MediaButtons::Interface * MediaButtons::getV2Interface(const QString &name)
{
QDBusReply<bool> reply = QDBusConnection::sessionBus().interface()->isServiceRegistered(constV2Prefix + name);
if (reply.isValid() && reply.value()) {
serviceOwnerChanged(constV2Prefix + name, QString(), QLatin1String("X"));
if (m_interfaces.contains(name)) {
m_watcher->addWatchedService(constV2Prefix + name);
return m_interfaces[name];
}
}
QDBusReply<QStringList> registeredReply = QDBusConnection::sessionBus().interface()->registeredServiceNames();
if (!registeredReply.isValid()) {
return nullptr;
}
foreach (const QString &value, registeredReply.value()) {
if (value.startsWith(constV2Prefix + name + QLatin1Char('.'))) {
serviceOwnerChanged(value, QString(), QLatin1String("X"));
// qDebug() << Q_FUNC_INFO << value << m_interfaces;
QString unsuffixedName = value.mid(constV2Prefix.size(), value.size() - constV2Prefix.size());
if (m_interfaces.contains(unsuffixedName)) {
m_watcher->addWatchedService(value);
return m_interfaces[unsuffixedName];
}
}
}
return nullptr;
}
MediaButtons::Interface * MediaButtons::getV1Interface(const QString &name)
{
QDBusReply<bool> reply = QDBusConnection::sessionBus().interface()->isServiceRegistered(constV1Prefix + name);
if (reply.isValid() && reply.value()) {
serviceOwnerChanged(constV1Prefix + name, QString(), QLatin1String("X"));
if (m_interfaces.contains(name)) {
m_watcher->addWatchedService(constV1Prefix + name);
return m_interfaces[name];
}
}
return 0;
}
#include "moc_mediabuttons.cpp"

View file

@ -1,95 +0,0 @@
/*
* Icon Task Manager
*
* Copyright 2011 Craig Drummond <craig@kde.org>
*
* ----
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* 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 General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef __MEDIABUTTONS_H__
#define __MEDIABUTTONS_H__
#include <QtCore/QObject>
#include <QtCore/QMap>
#include <QSet>
#include <QDBusServiceWatcher>
class OrgMprisMediaPlayer2PlayerInterface;
class OrgFreedesktopMediaPlayerInterface;
class MediaButtons : public QObject
{
Q_OBJECT
public:
class Interface
{
public:
Interface(OrgFreedesktopMediaPlayerInterface *o) : v1(o), v2(0) { }
Interface(OrgMprisMediaPlayer2PlayerInterface *t) : v1(0), v2(t) { }
~Interface();
bool isV1() const {
return 0 != v1;
}
bool isV2() const {
return 0 != v2;
}
void next();
void previous();
void playPause();
QString playbackStatus();
QString service();
private:
OrgFreedesktopMediaPlayerInterface *v1;
OrgMprisMediaPlayer2PlayerInterface *v2;
};
static MediaButtons * self();
MediaButtons();
void setEnabled(bool en);
bool isEnabled() const {
return m_enabled;
}
bool isMediaApp(const QString &desktopEntry);
void next(const QString &name, int pid = 0);
void previous(const QString &name, int pid = 0);
void playPause(const QString &name, int pid = 0);
QString playbackStatus(const QString &name, int pid = 0);
private Q_SLOTS:
void serviceOwnerChanged(const QString &name, const QString &oldOwner, const QString &newOwner);
private:
void readConfig();
Interface * getInterface(const QString &name, int pid);
Interface * getV2Interface(const QString &name);
Interface * getV1Interface(const QString &name);
private:
QDBusServiceWatcher *m_watcher;
QMap<QString, Interface *> m_interfaces;
QMap<QString, QString> m_aliases;
QSet<QString> m_ignore;
bool m_enabled;
};
#endif

View file

@ -1,6 +0,0 @@
[General]
Ignore=kmix,k3b,ghb,xbmc,flashplayer,audex,kmediafactory,kdenlive,avidemux-qt4,mkvinfo,mkvmergegui,guvcview,pavucontrol,avidemux-qt,devede,kid3
[Aliases]
amarok=amarok_containers
mpd=qmpdclient,sonata,quimup,qtmpc
dragonplayer=Dragon

View file

@ -1,72 +0,0 @@
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
<interface name="org.freedesktop.MediaPlayer">
<method name="Pause">
</method>
<method name="Stop">
</method>
<method name="Play">
</method>
<method name="Prev">
</method>
<method name="Next">
</method>
<method name="Repeat">
<arg type="b" direction="in"/>
</method>
<method name="GetStatus">
<arg type="(iiii)" direction="out"/>
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="DBusStatus"/>
</method>
<method name="VolumeSet">
<arg type="i" direction="in"/>
</method>
<method name="VolumeGet">
<arg type="i" direction="out"/>
</method>
<method name="PositionSet">
<arg type="i" direction="in"/>
</method>
<method name="PositionGet">
<arg type="i" direction="out"/>
</method>
<method name="GetMetadata">
<arg type="a{sv}" direction="out"/>
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="QVariantMap"/>
</method>
<method name="GetCaps">
<arg type="i" direction="out" />
</method>
<signal name="TrackChange">
<arg type="a{sv}"/>
<annotation name="org.qtproject.QtDBus.QtTypeName.In0" value="QVariantMap"/>
</signal>
<signal name="StatusChange">
<arg type="(iiii)"/>
<annotation name="org.qtproject.QtDBus.QtTypeName.In0" value="DBusStatus"/>
</signal>
<signal name="CapsChange">
<arg type="i" />
</signal>
</interface>
</node>

View file

@ -1,43 +0,0 @@
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
<interface name='org.mpris.MediaPlayer2.Player'>
<method name='Next'/>
<method name='Previous'/>
<method name='Pause'/>
<method name='PlayPause'/>
<method name='Stop'/>
<method name='Play'/>
<method name='Seek'>
<arg direction='in' name='Offset' type='x'/>
</method>
<method name='SetPosition'>
<arg direction='in' name='TrackId' type='o'/>
<arg direction='in' name='Position' type='x'/>
</method>
<method name='OpenUri'>
<arg direction='in' name='Uri' type='s'/>
</method>
<signal name='Seeked'>
<arg name='Position' type='x'/>
</signal>
<property name='PlaybackStatus' type='s' access='read'/>
<property name='LoopStatus' type='s' access='readwrite'/>
<property name='Rate' type='d' access='readwrite'/>
<property name='Shuffle' type='b' access='readwrite'/>
<property name='Metadata' type='a{sv}' access='read'>
<annotation name="org.qtproject.QtDBus.QtTypeName" value="QVariantMap"/>
</property>
<property name='Volume' type='d' access='readwrite'/>
<property name='Position' type='x' access='read'/>
<property name='MinimumRate' type='d' access='read'/>
<property name='MaximumRate' type='d' access='read'/>
<property name='CanGoNext' type='b' access='read'/>
<property name='CanGoPrevious' type='b' access='read'/>
<property name='CanPlay' type='b' access='read'/>
<property name='CanPause' type='b' access='read'/>
<property name='CanSeek' type='b' access='read'/>
<property name='CanControl' type='b' access='read'/>
</interface>
</node>

View file

@ -1,104 +0,0 @@
[Desktop Entry]
Name=Icon-Only Task Manager
Name[bs]=Icon-Only upravljač zadacima
Name[ca]=Gestor de tasques de només icones
Name[ca@valencia]=Gestor de tasques de només icones
Name[cs]=Ikonový správce úloh
Name[da]=Opgavelinje kun med ikoner
Name[de]=Symbol-Fensterleiste
Name[el]=Διαχειριστής εργασιών με εικονίδια μόνο
Name[en_GB]=Icon-Only Task Manager
Name[es]=Gestor de tareas de solo iconos
Name[et]=Ainult ikoonidega tegumihaldur
Name[fi]=Kuvaketehtävienhallinta
Name[fr]=Gestionnaire de tâches à icônes
Name[gl]=Xestor de tarefas baseado en iconas
Name[hu]=Ikonos feladatkezelő
Name[it]=Gestore attività con sole icone
Name[kk]=Тек таңбашалы тапсырмалар менеджері
Name[km]=
Name[ko]=
Name[lt]=Tik ženkliukų užduočių tvarkytuvė
Name[lv]=Tikai ikonu uzdevumu pārvaldnieks
Name[mr]=-ि
Name[nb]=Oppgavebehandler med bare ikoner
Name[nds]="Bloots-Lüttbild"-Opgavenpleger
Name[nl]=Takenbeheer met alleen pictogrammen
Name[pa]=
Name[pl]=Menadżer zadań tylko z ikonami
Name[pt]=Gestor de Tarefas com Ícones
Name[pt_BR]=Gerenciador de tarefas com ícones
Name[ro]=Gestionar de sarcini bazat pe pictograme
Name[ru]=Панель задач (только значки)
Name[sk]=Správca úloh len s ikonami
Name[sl]=Upravljalnik opravil s samimi ikonami
Name[sr]=менаџер задатака само са иконама
Name[sr@ijekavian]=менаџер задатака само са иконама
Name[sr@ijekavianlatin]=menadžer zadataka samo sa ikonama
Name[sr@latin]=menadžer zadataka samo sa ikonama
Name[sv]=Aktivitetshanterare med bara ikoner
Name[tr]=Sadece-Simge Görev Yöneticisi
Name[uk]=Керування задачами за допомогою піктограм
Name[x-test]=xxIcon-Only Task Managerxx
Name[zh_CN]=
Name[zh_TW]=
Comment=Switch between running applications
Comment[ar]=بدِّل بين التطبيقات المفتوحة
Comment[bs]=Prebacujte između programa u radu
Comment[ca]=Commuta entre aplicacions en execució
Comment[ca@valencia]=Commuta entre aplicacions en execució
Comment[cs]=Přepnout mezi běžícími aplikacemi
Comment[da]=Skift mellem kørende programmer
Comment[de]=Zwischen laufenden Programmen wechseln
Comment[el]=Εναλλαγή μεταξύ των εκτελούμενων εφαρμογών
Comment[en_GB]=Switch between running applications
Comment[es]=Cambiar entre las aplicaciones en ejecución
Comment[et]=Lülitumine töötavate rakenduste vahel
Comment[fi]=Vaihda avoinna olevien ohjelmien välillä
Comment[fr]=Basculer entre les applications démarrées
Comment[ga]=Athraigh idir feidhmchláir atá ag rith
Comment[gl]=Manexe os aplicativos que teña abertos.
Comment[hu]=Váltás a futó alkalmazások között
Comment[it]=Passa da un'applicazione in esecuzione all'altra
Comment[kk]=Жегілген қолданбаларды ақтару
Comment[km]=
Comment[ko]=
Comment[lt]=Persijungti tarp veikiančių programų
Comment[lv]=Pārslēgties starp darbojošām programmām
Comment[mr]=
Comment[nb]=Bytt mellom kjørende programmer
Comment[nds]=Twischen lopen Programmen wesseln
Comment[nl]=Schakel tussen draaiende programma's
Comment[nn]=Byt mellom program som køyrer
Comment[pa]=
Comment[pl]=Przełącz pomiędzy działającymi programami
Comment[pt]=Mudar de aplicações em execução
Comment[pt_BR]=Alterna entre os aplicativos em execução
Comment[ro]=Comută printre aplicațiile ce rulează
Comment[ru]=Переключение между запущенными приложениями
Comment[sk]=Prepínať medzi bežiacimi aplikáciami
Comment[sl]=Preklapljajte med zagnanimi programi
Comment[sr]=Пребацивање између покренутих програма
Comment[sr@ijekavian]=Пребацивање између покренутих програма
Comment[sr@ijekavianlatin]=Prebacivanje između pokrenutih programa
Comment[sr@latin]=Prebacivanje između pokrenutih programa
Comment[sv]=Byt mellan program som kör
Comment[tr]=Çalışan uygulamalar arasında geçiş yap
Comment[ug]=ئىجرا بولۇۋاتقان پروگراممىلارنى ئالماشتۇر
Comment[uk]=Перемкніть запущені програми
Comment[x-test]=xxSwitch between running applicationsxx
Comment[zh_CN]=
Comment[zh_TW]=
Icon=preferences-desktop-icons
Type=Service
X-KDE-ServiceTypes=Plasma/Applet
X-KDE-Library=plasma_applet_icontasks
X-KDE-PluginInfo-Author=Craig Drummond
X-KDE-PluginInfo-Email=craig@kde.org
X-KDE-PluginInfo-Name=icontasks
X-KDE-PluginInfo-Version=1.0
X-KDE-PluginInfo-Category=Windows and Tasks
X-KDE-PluginInfo-Depends=
X-KDE-PluginInfo-License=GPL v2+
X-KDE-PluginInfo-EnabledByDefault=false

View file

@ -1,542 +0,0 @@
/*
* Icon Task Manager
*
* Copyright 2011 Craig Drummond <craig@kde.org>
*
* ----
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* 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 General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "recentdocuments.h"
#include <KRecentDocument>
#include <KDirWatch>
#include <KGlobal>
#include <KDesktopFile>
#include <KConfigGroup>
#include <KIcon>
#include <KRun>
#include <KStandardDirs>
#include <KSycoca>
#include <KDebug>
#include <KServiceTypeTrader>
#include <KService>
#include <KMimeType>
#include <QtXml/qdom.h>
#include <QtCore/QDir>
#include <QtCore/QFile>
#include <QtCore/QDateTime>
K_GLOBAL_STATIC(RecentDocuments, recentDocs)
static QLatin1String constXbel("recently-used.xbel");
static QList<QAction *>::ConstIterator findUrl(const QList<QAction *> &list, const QString &url)
{
QList<QAction *>::ConstIterator it(list.constBegin()),
end(list.constEnd());
for (; it != end; ++it) {
if ((*it)->property("url") == url) {
break;
}
}
return it;
}
static bool hasUrl(const QList<QAction *> &list, const QString &url)
{
return list.end() != findUrl(list, url);
}
static QString dirSyntax(const QString &d)
{
if (!d.isEmpty()) {
QString ds(d);
ds.replace("//", "/");
int slashPos(ds.lastIndexOf('/'));
if (slashPos != (((int)ds.length()) - 1))
ds.append('/');
return ds;
}
return d;
}
RecentDocuments * RecentDocuments::self()
{
return recentDocs;
}
RecentDocuments::RecentDocuments()
: m_enabled(false)
, m_watcher(0)
, m_menu(0)
{
}
RecentDocuments::~RecentDocuments()
{
if (m_menu) {
m_menu->deleteLater();
}
}
void RecentDocuments::setEnabled(bool enabled)
{
if (m_enabled != enabled) {
if (enabled) {
if (m_files.isEmpty()) {
m_files << File(File::Xbel, dirSyntax(KGlobal::dirs()->localxdgdatadir()) + constXbel)
<< File(File::Xbel, dirSyntax(QDir::homePath()) + "." + constXbel)
<< File(File::Office, dirSyntax(QDir::homePath()) + ".recently-used");
}
m_watcher = new KDirWatch(this);
m_watcher->addDir(KRecentDocument::recentDocumentDirectory());
foreach (File f, m_files) {
m_watcher->addFile(f.path);
}
connect(m_watcher, SIGNAL(dirty(QString)), this, SLOT(readCurrentDocs()));
connect(KSycoca::self(), SIGNAL(databaseChanged(QStringList)), this, SLOT(sycocaChanged(const QStringList &)));
readCurrentDocs();
} else if (m_enabled) {
disconnect(m_watcher, SIGNAL(dirty(QString)), this, SLOT(readCurrentDocs()));
disconnect(KSycoca::self(), SIGNAL(databaseChanged(QStringList)), this, SLOT(sycocaChanged(const QStringList &)));
delete m_watcher;
m_watcher = 0;
QMap<QString, QList<QAction *> >::Iterator it(m_docs.begin()),
end(m_docs.end());
for (; it != end; ++it) {
foreach (const QAction * act, *it) {
delete act;
}
}
m_docs.clear();
m_apps.clear();
}
m_enabled = enabled;
}
}
QList<QAction *> RecentDocuments::get(const QString &app)
{
if (m_enabled) {
load();
if (m_docs.contains(app)) {
if (m_docs[app].count() > 1) {
if (!m_menu) {
m_menu = new TaskManager::ToolTipMenu(0, i18n("Recent Documents"));
}
QList<QAction *> old=m_menu->actions();
foreach (QAction * act, old) {
m_menu->removeAction(act);
}
foreach (QAction * act, m_docs[app]) {
m_menu->addAction(act);
}
QList<QAction *> acts;
acts.append(m_menu->menuAction());
return acts;
}
return m_docs[app];
}
}
return QList<QAction *>();
}
void RecentDocuments::added(const QString &path)
{
if (KDesktopFile::isDesktopFile(path)) {
removed(path); // Remove first!
KDesktopFile df(path);
KConfigGroup de(&df, "Desktop Entry");
QString url = de.readEntry("URL", QString());
QString name = KUrl(url).fileName();
QString app = de.readEntry("X-KDE-LastOpenedWith", QString());
if (!name.isEmpty() && !app.isEmpty() && !url.isEmpty() && !hasUrl(m_docs[app], url)) {
QString icon = de.readEntry("Icon", QString());
QAction *act = icon.isEmpty() ? new QAction(name, this) : new QAction(KIcon(icon), name, this);
act->setToolTip(KUrl(url).prettyUrl());
act->setProperty("timestamp", (qulonglong)0);
act->setProperty("path", path);
act->setProperty("url", url);
connect(act, SIGNAL(triggered()), SLOT(loadDoc()));
m_docs[app].append(act);
}
} else {
QList<File>::Iterator it(m_files.begin()),
end(m_files.end());
for (; it != end; ++it) {
if ((*it).path == path) {
(*it).dirty = true;
break;
}
}
}
}
void RecentDocuments::removed(const QString &path)
{
if (path.endsWith(".desktop")) {
QMap<QString, QList<QAction *> >::Iterator it(m_docs.begin()),
end(m_docs.end());
for (; it != end; ++it) {
foreach (QAction * act, *it) {
if (act->property("path").toString() == path) {
disconnect(act, SIGNAL(triggered()), this, SLOT(loadDoc()));
delete act;
(*it).removeAll(act);
if ((*it).isEmpty()) {
m_docs.erase(it);
}
return;
}
}
}
} else {
QList<File>::Iterator it(m_files.begin()),
end(m_files.end());
for (; it != end; ++it) {
if ((*it).path == path) {
(*it).dirty = true;
break;
}
}
}
}
void RecentDocuments::sycocaChanged(const QStringList &types)
{
if (types.contains("apps") || types.contains("xdgdata-apps")) {
m_apps.clear();
QList<File>::Iterator it(m_files.begin()),
end(m_files.end());
for (; it != end; ++it) {
if (File::Xbel == (*it).type) {
(*it).dirty = true;
}
}
}
}
void RecentDocuments::loadDoc()
{
QObject *s = sender();
if (s && qobject_cast<QAction *>(s)) {
QAction *item = static_cast<QAction *>(s);
QString path = item->property("path").toString();
if (path.isEmpty()) {
QString exec = item->property("exec").toString();
KUrl url = KUrl(item->property("url").toString());
if (url.isValid() && !exec.isEmpty()) {
KRun::run(exec, KUrl::List() << url, 0, QString(), QString(), "0");
}
} else {
new KRun(KUrl(path), 0);
}
}
}
void RecentDocuments::readCurrentDocs()
{
const QStringList documents = KRecentDocument::recentDocuments();
foreach (const QString & document, documents) {
added(document);
}
}
void RecentDocuments::load()
{
qulonglong now = (qulonglong)QDateTime::currentMSecsSinceEpoch();
QList<File>::Iterator it(m_files.begin()),
end(m_files.end());
for (; it != end; ++it) {
if ((*it).dirty) {
if (File::Xbel == (*it).type) {
loadXbel((*it).path, now);
} else if (File::Office == (*it).type) {
loadOffice((*it).path, now);
}
(*it).dirty = false;
}
}
}
static QString convertMimeType(const QString &mimeType, const KUrl &url)
{
return mimeType == "text/plain" && url.fileName().endsWith(".csv")
? QLatin1String("text/csv") : mimeType;
}
RecentDocuments::App RecentDocuments::officeAppForMimeType(const QString &mimeType)
{
if (m_apps.contains(mimeType)) {
return m_apps[mimeType];
} else {
KService::List services = KServiceTypeTrader::self()->query("Application",
QString("exist Exec and (exist ServiceTypes) and ('libreoffice' ~ Exec) and ('%1' in ServiceTypes)").arg(mimeType));
if (!services.empty()) {
QString desktopFile = services[0]->entryPath();
KDesktopFile df(desktopFile);
KConfigGroup grp(&df, "Desktop Entry");
QString exec = grp.readEntry("Exec", QString());
if (!exec.isEmpty()) {
App app(KUrl::fromPath(desktopFile).fileName().remove(".desktop"), exec);
m_apps.insert(mimeType, app);
return app;
}
}
}
return App();
}
RecentDocuments::App RecentDocuments::appForExec(const QString &execString)
{
if (m_apps.contains(execString)) {
return m_apps[execString];
} else {
KService::List services = KServiceTypeTrader::self()->query("Application",
QString("exist Exec and ('%1' =~ Exec)").arg(execString));
if (services.empty()) {
QString execApp = execString;
int space = execApp.indexOf(' ');
if (-1 != space) {
execApp = execApp.left(space);
}
services = KServiceTypeTrader::self()->query("Application",
QString("exist TryExec and ('%1' =~ TryExec)").arg(execApp));
}
if (!services.empty()) {
QString desktopFile = services[0]->entryPath();
KDesktopFile df(desktopFile);
KConfigGroup grp(&df, "Desktop Entry");
QString exec = grp.readEntry("Exec", QString());
if (!exec.isEmpty()) {
App app(KUrl::fromPath(desktopFile).fileName().remove(".desktop"), exec);
m_apps.insert(execString, app);
return app;
}
}
}
return App();
}
void RecentDocuments::loadXbel(const QString &path, qulonglong now)
{
QDomDocument doc("xbel");
QFile f(path);
if (f.open(QIODevice::ReadOnly) && doc.setContent(&f)) {
QDomElement root = doc.documentElement();
if ("xbel" == root.tagName() && root.hasAttribute("version") && "1.0" == root.attribute("version")) {
QDomElement bookmark = root.firstChildElement("bookmark");
while (!bookmark.isNull()) {
if (bookmark.hasAttribute("href")) {
QDomElement info = bookmark.firstChildElement("info");
if (!info.isNull()) {
QDomElement metadata = info.firstChildElement("metadata");
if (!metadata.isNull() && metadata.hasAttribute("owner") && "http://freedesktop.org" == metadata.attribute("owner")) {
QDomElement applications = metadata.firstChildElement("bookmark:applications");
if (!applications.isNull()) {
QDomElement application = applications.firstChildElement("bookmark:application");
if (!application.isNull() && application.hasAttribute("exec")) {
KUrl url = bookmark.attribute("href");
if (url.isValid() && (!url.isLocalFile() || QFile::exists(url.toLocalFile()))) {
QString exec = application.attribute("exec");
QDomElement mimeType = metadata.firstChildElement("mime:mime-type");
QString mType;
KMimeType::Ptr mime;
if (!mimeType.isNull() && mimeType.hasAttribute("type")) {
mType = convertMimeType(mimeType.attribute("type"), url);
mime = KMimeType::mimeType(mType);
}
exec.remove('\'');
App app = mime && QLatin1String("soffice %u")==exec
? officeAppForMimeType(mType)
: appForExec(exec);
if (!app.name.isEmpty()) {
QString name = KUrl(url).fileName();
if (!name.isEmpty()) {
bool found = false;
if (!m_docs[app.name].isEmpty()) {
QList<QAction *>::ConstIterator it = findUrl(m_docs[app.name], url.url());
if (it != m_docs[app.name].constEnd()) {
found = true;
if ((*it)->property("timestamp").toULongLong() > 0) {
(*it)->setProperty("timestamp", now);
}
}
}
if (!found) {
QAction *act = mime
? new QAction(KIcon(mime->iconName()), name, this)
: new QAction(name, this);
act->setToolTip(KUrl(url).prettyUrl());
act->setProperty("timestamp", now);
act->setProperty("url", url.url());
act->setProperty("exec", app.exec);
act->setProperty("type", (int)File::Xbel);
connect(act, SIGNAL(triggered()), SLOT(loadDoc()));
m_docs[app.name].append(act);
}
}
}
}
}
}
}
}
}
bookmark = bookmark.nextSiblingElement("bookmark");
}
}
}
removeOld(now, File::Xbel);
}
void RecentDocuments::loadOffice(const QString &path, qulonglong now)
{
QDomDocument doc("RecentFiles");
QFile f(path);
if (f.open(QIODevice::ReadOnly) && doc.setContent(&f)) {
QDomElement root = doc.documentElement();
if ("RecentFiles" == root.tagName()) {
QDomElement recentItem = root.firstChildElement("RecentItem");
while (!recentItem.isNull()) {
QDomElement groups = recentItem.firstChildElement("Groups");
if (!groups.isNull()) {
QDomElement group = groups.firstChildElement("Group");
bool ok = false;
while (!group.isNull()) {
if (group.text() == "openoffice.org") {
ok = true;
break;
}
group = group.nextSiblingElement("Group");
}
if (ok) {
QDomElement uri = recentItem.firstChildElement("URI");
QDomElement mimeType = recentItem.firstChildElement("Mime-Type");
if (!uri.isNull() && !mimeType.isNull()) {
KUrl url(uri.text());
if (url.isValid() && (!url.isLocalFile() || QFile::exists(url.toLocalFile()))) {
QString mType = convertMimeType(mimeType.text(), url);
App app = officeAppForMimeType(mType);
if (!app.name.isEmpty() && !app.exec.isEmpty()) {
QString name = KUrl(url).fileName();
if (!name.isEmpty()) {
bool found = false;
if (!m_docs[app.name].isEmpty()) {
QList<QAction *>::ConstIterator it = findUrl(m_docs[app.name], url.url());
if (it != m_docs[app.name].constEnd()) {
found = true;
if ((*it)->property("timestamp").toULongLong() > 0) {
(*it)->setProperty("timestamp", now);
}
}
}
if (!found) {
KMimeType::Ptr mime = KMimeType::mimeType(mType);
QAction *act = mime
? new QAction(KIcon(mime->iconName()), name, this)
: new QAction(name, this);
act->setToolTip(KUrl(url).prettyUrl());
act->setProperty("local", false);
act->setProperty("timestamp", now);
act->setProperty("url", url.url());
act->setProperty("exec", app.exec);
act->setProperty("type", (int)File::Office);
connect(act, SIGNAL(triggered()), SLOT(loadDoc()));
m_docs[app.name].append(act);
}
}
}
}
}
}
}
recentItem = recentItem.nextSiblingElement("RecentItem");
}
}
}
removeOld(now, File::Office);
}
void RecentDocuments::removeOld(qulonglong now, File::Type type)
{
QMap<QString, QList<QAction *> >::Iterator it(m_docs.begin()),
end(m_docs.end());
while (it != end) {
QList<QAction *> old;
foreach (QAction * act, (*it)) {
qulonglong t = act->property("timestamp").toULongLong();
if (type==act->property("type").toInt() && t > 0 && t < now) {
old.append(act);
}
}
foreach (QAction * act, old) {
act->deleteLater();
(*it).removeAll(act);
}
if ((*it).isEmpty()) {
QMap<QString, QList<QAction *> >::Iterator cur = it;
it++;
m_docs.erase(cur);
} else {
it++;
}
}
}
#include "moc_recentdocuments.cpp"

View file

@ -1,95 +0,0 @@
#ifndef __RECENT_DOCUMENTS__
#define __RECENT_DOCUMENTS__
/*
* Icon Task Manager
*
* Copyright 2011 Craig Drummond <craig@kde.org>
*
* ----
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* 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 General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include <QtCore/QObject>
#include <QtCore/QMap>
#include <QtCore/QList>
#include <QtGui/QAction>
#include "taskmanager/taskactions.h"
class KDirWatch;
class RecentDocuments : public QObject
{
Q_OBJECT
struct File {
enum Type {
Xbel,
Office
};
File(Type t, const QString &p) : type(t), path(p), dirty(true) { }
Type type;
QString path;
bool dirty;
};
struct App {
App(const QString &n = QString(), const QString &e = QString()) : name(n), exec(e) { }
QString name;
QString exec;
};
public:
static RecentDocuments * self();
RecentDocuments();
~RecentDocuments();
void setEnabled(bool enabled);
bool isEnabled() const {
return m_enabled;
}
QList<QAction *> get(const QString &app);
private Q_SLOTS:
void added(const QString& path);
void removed(const QString& path);
void sycocaChanged(const QStringList &types);
void loadDoc();
void readCurrentDocs();
private:
void load();
App officeAppForMimeType(const QString &mimeType);
App appForExec(const QString &execString);
void loadXbel(const QString &path, qulonglong now);
void loadOffice(const QString &path, qulonglong now);
void removeOld(qulonglong now, File::Type type);
private:
bool m_enabled;
QMap<QString, QList<QAction *> > m_docs;
QMap<QString, App> m_apps;
KDirWatch *m_watcher;
QList<File> m_files;
TaskManager::ToolTipMenu *m_menu;
};
#endif

File diff suppressed because it is too large Load diff

View file

@ -1,209 +0,0 @@
/***************************************************************************
* Copyright (C) 2007 by Robert Knight <robertknight@gmail.com> *
* Copyright (C) 2008 by Alexis Ménard <darktears31@gmail.com> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* 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 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 . *
***************************************************************************/
#ifndef TASKGROUPITEM_H
#define TASKGROUPITEM_H
#include "abstracttaskitem.h"
#include "windowtaskitem.h"
// Own
#include "taskmanager/taskmanager.h"
#include "tasks.h"
#include <QMap>
#include <QHash>
using TaskManager::TaskGroup;
using TaskManager::GroupPtr;
using TaskManager::TaskItem;
using TaskManager::AbstractGroupableItem;
class TaskItemLayout;
class DropIndicator;
#include <QGraphicsLinearLayout>
namespace Plasma
{
class Dialog;
}
typedef QMap<int, AbstractTaskItem*> Order;
/**
* A task item for a TaskGroup. It can be displayed collapsed as single item or expanded as group.
*/
class TaskGroupItem : public AbstractTaskItem
{
Q_OBJECT
public:
/** Constructs a new representation for a taskgroup. */
TaskGroupItem(QGraphicsWidget *parent, Tasks *applet);
virtual ~TaskGroupItem();
/** Sets the group represented by this task. */
void setGroup(TaskManager::GroupPtr);
/** Returns the group represented by this task. */
TaskManager::GroupPtr group() const;
virtual void close();
QHash<AbstractGroupableItem *, AbstractTaskItem*> members() const;
int count() const;
AbstractTaskItem * activeSubTask();
virtual bool isWindowItem() const;
virtual bool isActive() const;
bool windowPreviewOpen() const;
QString appName() const;
KUrl launcherUrl() const;
QString windowClass() const;
bool collapsed() const;
virtual void toCurrentDesktop();
/** Returns Direct Member group if the passed item is in a subgroup */
AbstractTaskItem *directMember(AbstractTaskItem *);
/** Maximum number of Rows the group will have */
int maxRows();
void setMaxRows(int);
TaskItemLayout *tasksLayout();
int indexOf(AbstractTaskItem *task, bool descendGroups = true);
int optimumCapacity();
AbstractTaskItem* abstractTaskItem(AbstractGroupableItem *);
void setAdditionalMimeData(QMimeData* mimeData);
void publishIconGeometry() const;
void publishIconGeometry(const QRect &rect) const;
QWidget *popupDialog() const;
AbstractTaskItem *taskItemForWId(WId id);
AbstractTaskItem *matchingItem(TaskManager::AbstractGroupableItem *from);
private:
void close(bool hide);
signals:
/** Emitted when a window is selected for activation, minimization, iconification */
void groupSelected(TaskGroupItem *);
void sizeHintChanged(Qt::SizeHint);
/** informs the parent group about changes */
void changed();
public slots:
virtual void activate();
/** Reload all tasks */
void reload();
void expand();
void collapse();
void updatePreferredSize();
void clearGroup();
bool isRootGroup() const;
public slots:
void updateActive(AbstractTaskItem *);
void relayoutItems();
protected:
void activateOrIconify();
void contextMenuEvent(QGraphicsSceneContextMenuEvent *event);
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
void dragEnterEvent(QGraphicsSceneDragDropEvent *event);
void dragLeaveEvent(QGraphicsSceneDragDropEvent *event);
void dragMoveEvent(QGraphicsSceneDragDropEvent *event);
void dropEvent(QGraphicsSceneDragDropEvent *event);
bool focusNextPrevChild(bool next);
void handleDroppedId(WId id, AbstractTaskItem *targetTask, QGraphicsSceneDragDropEvent *event);
void mousePressEvent(QGraphicsSceneMouseEvent *event);
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
void resizeEvent(QGraphicsSceneResizeEvent *event);
void updateToolTip();
protected slots:
virtual void wheelEvent(QGraphicsSceneWheelEvent *event);
private Q_SLOTS:
void checkUpdates();
void constraintsChanged(Plasma::Constraints);
void handleActiveWindowChanged(WId id);
void updateTask(::TaskManager::TaskChanges changes);
/** Stay informed about changes in group */
void itemAdded(AbstractGroupableItem *);
void itemRemoved(AbstractGroupableItem *);
/** Update to new position*/
void itemPositionChanged(AbstractGroupableItem *);
void popupMenu();
/** force a relayout of all items */
void popupVisibilityChanged(bool visible);
private:
AbstractTaskItem* createAbstractItem(AbstractGroupableItem * groupableItem);
TaskGroupItem* createNewGroup(QList <AbstractTaskItem *> members);
WindowTaskItem * createWindowTask(TaskManager::TaskItem* task);
TaskGroupItem * createTaskGroup(GroupPtr);
WindowTaskItem *createStartingTask(TaskManager::TaskItem* task);
void removeItem(AbstractTaskItem *item);
void layoutTaskItem(AbstractTaskItem* item, const QPointF &pos);
void setSplitIndex(int position);
QIcon m_icon;
int totalSubTasks();
bool focusSubTask(bool next, bool activate);
AbstractTaskItem * selectSubTask(int index);
QWeakPointer<TaskGroup> m_group;
QHash<AbstractGroupableItem *, AbstractTaskItem*> m_groupMembers;
TaskItemLayout *m_tasksLayout;
QTimer *m_popupMenuTimer;
QHash<int, Order> m_taskOrder;
int m_lastActivated;
int m_activeTaskIndex;
int m_maximumRows;
QGraphicsWidget *m_offscreenWidget;
QGraphicsLinearLayout *m_offscreenLayout;
bool m_collapsed;
QGraphicsLinearLayout *m_mainLayout;
Plasma::Dialog *m_popupDialog;
QTimer *m_updateTimer;
TaskManager::TaskChanges m_changes;
DropIndicator *m_dropIndicator;
};
#endif

View file

@ -1,635 +0,0 @@
/***************************************************************************
* Copyright (C) 2008 by Christian Mollekopf chrigi_1@fastmail.fm *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* 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 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 "taskitemlayout.h"
//Taskmanager
#include "taskmanager/taskmanager.h"
#include "taskmanager/abstractgroupableitem.h"
#include "taskmanager/groupmanager.h"
// Qt
#include <QGraphicsScene>
#include <QGraphicsGridLayout>
// KDE
#include <KDebug>
#include <math.h>
#include "windowtaskitem.h"
#include "taskgroupitem.h"
class LauncherSeparator : public QGraphicsWidget
{
public:
LauncherSeparator(QGraphicsItem *parent = 0, Qt::WindowFlags wFlags = 0)
: QGraphicsWidget(parent, wFlags) {
m_svg = new Plasma::Svg();
m_svg->setImagePath("icontasks/launcherseparator");
m_svg->setContainsMultipleImages(true);
setOrientation(Qt::Horizontal);
}
~LauncherSeparator() {
delete m_svg;
}
void setOrientation(Qt::Orientation orientation) {
m_orientation = orientation;
if (m_orientation == Qt::Vertical) {
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
} else {
setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
}
}
Qt::Orientation orientation() {
return m_orientation;
}
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) {
Q_UNUSED(option);
Q_UNUSED(widget);
if (m_svg) {
if (m_orientation == Qt::Horizontal) {
m_svg->paint(painter, boundingRect(), "horizontal-separator");
} else {
m_svg->paint(painter, boundingRect(), "vertical-separator");
}
}
}
QSizeF sizeHint(Qt::SizeHint which, const QSizeF & constraint) const {
QSizeF hint = QGraphicsWidget::sizeHint(which, constraint);
if (m_orientation == Qt::Horizontal) {
hint.setWidth(m_svg->elementSize("horizontal-separator").width());
} else {
hint.setHeight(m_svg->elementSize("vertical-separator").height());
}
return hint;
}
private:
Plasma::Svg *m_svg;
Qt::Orientation m_orientation;
};
TaskItemLayout::TaskItemLayout(TaskGroupItem *parent, Tasks *applet)
: QGraphicsGridLayout(0),
m_groupItem(parent),
m_rowSize(1),
m_maxRows(1),
m_forceRows(false),
m_applet(applet),
m_layoutOrientation(Qt::Horizontal),
m_separator(parent->isRootGroup() ? new LauncherSeparator(parent) : 0L)
{
setContentsMargins(0, 0, 0, 0);
setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding));
setMaximumSize(INT_MAX, INT_MAX);
//kDebug();
foreach (AbstractTaskItem * item, m_groupItem->members()) {
addTaskItem(item);
}
if (parent->isRootGroup()) {
connect(&m_applet->groupManager(), SIGNAL(launchersChanged()), SLOT(layoutItems()));
}
}
TaskItemLayout::~TaskItemLayout()
{
}
void TaskItemLayout::setOrientation(Plasma::FormFactor orientation)
{
Qt::Orientation oldOrientation = m_layoutOrientation;
if (orientation == Plasma::Vertical) {
m_layoutOrientation = Qt::Vertical;
} else {
m_layoutOrientation = Qt::Horizontal;
}
if (m_separator) {
m_separator->setOrientation(m_layoutOrientation);
}
if (m_layoutOrientation != oldOrientation) {
layoutItems();
}
}
bool TaskItemLayout::separatorVisible() const
{
return m_separator && m_separator->isVisible();
}
void TaskItemLayout::addTaskItem(AbstractTaskItem * item)
{
//kDebug();
if (!item) {
return;
}
if (item->isStartupWithTask()) {
return;
}
if (m_itemPositions.contains(item)) {
//kDebug() << "already in this layout";
return;
}
if (m_groupItem->scene() && !item->scene()) {
//kDebug() << "layout widget got scene"<<m_groupItem->scene()<< "add item to scene" <<item->scene();
m_groupItem->scene()->addItem(item);
//kDebug() << "itemScene" << item->scene();
}
if (!insert(m_groupItem->indexOf(item, false), item)) {
return;
}
item->show();
//kDebug() << "end";
}
void TaskItemLayout::removeTaskItem(AbstractTaskItem *item)
{
if (!remove(item)) {
return;
}
//kDebug();
if (m_groupItem->scene()) {
//kDebug() << "got scene";
m_groupItem->scene()->removeItem(item);
} else {
kDebug() << "No Scene available";
}
//kDebug() << "done";
}
bool TaskItemLayout::insert(int index, AbstractTaskItem *item)
{
//kDebug() << item->text() << index;
if (!item) {
kDebug() << "error";
return false;
}
int listIndex;
for (listIndex = 0; listIndex < m_itemPositions.size(); listIndex++) {
if (index <= m_groupItem->indexOf(m_itemPositions.at(listIndex), false)) {
break;
}
}
if (m_itemPositions.removeAll(item) == 0) {
connect(item, SIGNAL(destroyed(AbstractTaskItem*)), this, SLOT(remove(AbstractTaskItem*)));
}
m_itemPositions.insert(listIndex, item);
layoutItems();
return true;
}
bool TaskItemLayout::remove(AbstractTaskItem* item)
{
if (!item) {
kDebug() << "null Item";
layoutItems();
return false;
}
disconnect(item, 0, this, 0);
m_itemPositions.removeAll(item);
layoutItems();
return true;
}
/** size including expanded groups*/
int TaskItemLayout::size()
{
int groupSize = 0;
foreach (AbstractTaskItem * item, m_groupItem->members()) {
if (!item->abstractItem()) {
// this item is a startup task or the task no longer exists
kDebug() << "Error, invalid item in groupMembers";
continue;
}
if (item->abstractItem()->itemType() == TaskManager::GroupItemType) {
TaskGroupItem *group = qobject_cast<TaskGroupItem*>(item);
if (!group->collapsed()) {
TaskItemLayout *layout = qobject_cast<TaskItemLayout*>(group->tasksLayout());
if (!layout) {
kDebug() << "Error group has no layout";
continue;
}
// increase number of items since expanded groups occupy several spaces
groupSize += layout->size();
continue;
}
}
++groupSize;
}
//kDebug() << "group size" << groupSize;
return groupSize;
}
//return maximum colums set by the user unless the setting is to high and the items would get unusable
int TaskItemLayout::maximumRows()
{
int maxRows;
if (m_itemPositions.isEmpty()) {
return 1;
}
if (m_forceRows) {
return m_maxRows;
}
// in this case rows are columns, columns are rows...
//TODO basicPreferredSize isn't the optimal source here because it changes because of margins probably
QSizeF itemSize = m_itemPositions.first()->basicPreferredSize();
if (m_layoutOrientation == Qt::Vertical) {
maxRows = qMin(qMax(1, int(m_groupItem->geometry().width() / itemSize.width())), m_maxRows);
} else {
maxRows = qMin(qMax(1, int(m_groupItem->geometry().height() / itemSize.height())), m_maxRows);
}
//kDebug() << "maximum rows: " << maxRows << m_maxRows << m_groupItem->geometry().height() << itemSize.height();
return maxRows;
}
//returns a reasonable amount of columns
int TaskItemLayout::preferredColumns()
{
if (m_forceRows) {
m_rowSize = 1;
} else {
if (m_itemPositions.isEmpty()) {
return 1;
}
//TODO basicPreferredSize isn't the optimal source here because it changes because of margins probably
QSizeF itemSize = m_itemPositions.first()->basicPreferredSize();
//kDebug() << itemSize.width() << m_groupItem->geometry().width();
if (m_layoutOrientation == Qt::Vertical) {
m_rowSize = qMax(1, int(m_groupItem->geometry().height() / itemSize.height()));
} else {
//Launchers doesn't need the same space as task- and groupitems on horizontal Layouts so the size needs to be adjusted
qreal horizontalSpace = m_groupItem->geometry().width();
m_rowSize = qMax(1, int(horizontalSpace / itemSize.width()));
}
}
//kDebug() << "preferred columns: " << qMax(1, m_rowSize);
return qMax(1, m_rowSize);
}
// <columns,rows>
QPair<int, int> TaskItemLayout::gridLayoutSize()
{
int groupSize = size();
//the basic settings
int columns = preferredColumns();
int maxRows = maximumRows();
//check for adjustments on columns because there isnt room enough yet for all of the items
while (ceil(static_cast<float>(groupSize) / static_cast<float>(columns)) > maxRows) {
columns++; // more rows needed than allowed so we add some columns instead
}
//kDebug() << "groupWidth" << columns << maxRows << m_maxRows;
int rows;
if (m_forceRows) {
rows = maxRows;
} else {
rows = ceil(static_cast<float>(groupSize) / static_cast<float>(columns)); //actually needed rows
}
return QPair<int, int>(columns, rows);
}
void TaskItemLayout::layoutItems()
{
//kDebug();
QPair<int, int> grid = gridLayoutSize();
int columns = qMax(grid.first, 1);
//FIXME: resetting column preferred sizesthey shouldn't be taken into account for inexistent ones but they are, probably upstream issue
for (int i = 0; i < columnCount(); ++i) {
setColumnMaximumWidth(i, 0);
setColumnPreferredWidth(i, 0);
}
for (int i = 0; i < rowCount(); ++i) {
setRowMaximumHeight(i, 0);
setRowPreferredHeight(i, 0);
}
//clearLayout
if (m_separator) {
m_separator->setVisible(false);
}
while (count()) {
removeAt(0);
}
QRectF groupRect(m_groupItem->boundingRect());
qreal cellSize(qMin(m_applet->launcherIcons() || !m_applet->autoIconScaling() ? qreal(272) : qreal(80), qMin(groupRect.width(), groupRect.height())));
QSizeF maximumCellSize(cellSize, cellSize);
setHorizontalSpacing(m_applet->spacing());
setVerticalSpacing(m_applet->spacing());
//go through all items of this layoutwidget and populate the layout with items
int numberOfItems = 0;
foreach (AbstractTaskItem * item, m_itemPositions) {
int row;
int col;
if (m_layoutOrientation == Qt::Vertical) {
row = numberOfItems % columns;
col = numberOfItems / columns;
} else {
row = numberOfItems / columns;
col = numberOfItems % columns;
}
if (m_separator && 1 == m_maxRows && Tasks::Sep_Never != m_applet->showSeparator() &&
TaskManager::GroupManager::ManualSorting == m_applet->groupManager().sortingStrategy() &&
m_applet->groupManager().launcherCount() && numberOfItems >= m_applet->groupManager().launcherCount() &&
!m_separator->isVisible()) {
// If a group associated with a launcher is split, then there will be more entries than launchers!
// So, we need to check if this item is associated with a launcher...
if (!(item->abstractItem() && m_applet->groupManager().isItemAssociatedWithLauncher(item->abstractItem()))) {
addItem(m_separator, row, col, 1, 1);
m_separator->setVisible(true);
numberOfItems++;
if (m_layoutOrientation == Qt::Vertical) {
row = numberOfItems % columns;
col = numberOfItems / columns;
} else {
row = numberOfItems / columns;
col = numberOfItems % columns;
}
}
}
//not good if we don't recreate the layout every time
//m_layout->setColumnPreferredWidth(col, columnWidth);//Somehow this line is absolutely crucial
//m_layout->setRowPreferredHeight(row, rowHeight);//Somehow this line is absolutely crucial
//FIXME: this is a glorious hack
if (maximumCellSize.isValid()) {
if (m_layoutOrientation == Qt::Vertical) {
setRowMaximumHeight(row, maximumCellSize.height());
setColumnMaximumWidth(col, QWIDGETSIZE_MAX);
} else {
setColumnMaximumWidth(col, maximumCellSize.width());
setRowMaximumHeight(row, QWIDGETSIZE_MAX);
}
setRowPreferredHeight(row, maximumCellSize.height());
setColumnPreferredWidth(col, maximumCellSize.width());
}
if (item->abstractItem() &&
item->abstractItem()->itemType() == TaskManager::GroupItemType) {
TaskGroupItem *group = static_cast<TaskGroupItem*>(item);
if (group->collapsed()) {
// group->unsplitGroup();
addItem(item, row, col, 1, 1);
numberOfItems++;
} else {
TaskItemLayout *layout = group->tasksLayout();
if (!layout) {
kDebug() << "group has no valid layout";
continue;
}
int groupRowWidth = m_layoutOrientation == Qt::Vertical ? layout->numberOfRows() : layout->numberOfColumns();
if ((columns - col) < groupRowWidth) {
//we need to split the group
int splitIndex = columns - col;//number of items in group that are on this row
if (m_layoutOrientation == Qt::Vertical) {
addItem(item, row, col, splitIndex, 1);
} else {
addItem(item, row, col, 1, splitIndex);
}
} else {
if (m_layoutOrientation == Qt::Vertical) {
addItem(item, row, col, groupRowWidth, 1);
} else {
addItem(item, row, col, 1, groupRowWidth);
}
}
numberOfItems += groupRowWidth;
}
} else {
addItem(item, row, col, 1, 1);
numberOfItems++;
}
//kDebug() << "addItem at: " << row << col;
}
if (m_separator && 1 == m_maxRows && Tasks::Sep_Always == m_applet->showSeparator() && !m_separator->isVisible() &&
TaskManager::GroupManager::ManualSorting == m_applet->groupManager().sortingStrategy() &&
m_applet->groupManager().launcherCount()) {
if (m_layoutOrientation == Qt::Vertical) {
addItem(m_separator, numberOfItems % columns, numberOfItems / columns, 1, 1);
} else {
addItem(m_separator, numberOfItems / columns, numberOfItems % columns, 1, 1);
}
m_separator->setVisible(true);
}
updatePreferredSize();
//m_groupItem->setLayout(m_layout);
}
void TaskItemLayout::updatePreferredSize()
{
//kDebug() << "column count: " << m_layout->columnCount();
bool haveSep = m_separator && m_separator->isVisible();
if (count() > (haveSep ? 1 : 0)) {
bool vertical = m_layoutOrientation == Qt::Vertical;
QSizeF s = itemAt(0)->preferredSize();
QSizeF sepSize = m_separator && m_separator->isVisible()
? QSizeF(vertical
? 0 : m_separator->preferredSize().width(),
vertical
? m_separator->preferredSize().height() : 0)
: QSizeF(0, 0);
//kDebug() << s << columnCount();
setPreferredSize((s.width() * (columnCount() - (!vertical && haveSep ? 1 : 0))) + sepSize.width(),
(s.height() * (rowCount() - (vertical && haveSep ? 1 : 0))) + sepSize.height());
} else {
//Empty taskbar, arbitrary small value
kDebug() << "Empty layout!!!!!!!!!!!!!!!!!!";
if (m_layoutOrientation == Qt::Vertical) {
setPreferredSize(/*m_layout->preferredSize().width()*/10, 10); //since we recreate the layout we don't have the previous values
} else {
setPreferredSize(10, /*m_layout->preferredSize().height()*/10);
}
}
//kDebug() << "preferred size: " << m_layout->preferredSize();
m_groupItem->updatePreferredSize();
}
void TaskItemLayout::setMaximumRows(int rows)
{
if (rows != m_maxRows) {
m_maxRows = rows;
layoutItems();
}
}
void TaskItemLayout::setForceRows(bool forceRows)
{
m_forceRows = forceRows;
}
TaskItemLayout::Insert TaskItemLayout::insertionIndexAt(const QPointF &pos)
{
Insert insert;
int nRows = numberOfRows();
int nCols = numberOfColumns();
int row = nRows;
int col = nCols;
bool vertical = Qt::Vertical == m_layoutOrientation;
insert.index = -1;
//if pos is (-1,-1) insert at the end of the panel
if (pos.toPoint() == QPoint(-1, -1)) {
kDebug() << "Error";
return insert;
} else {
QRectF siblingGeometry;
int border = 1 + (m_applet->spacing() / 2.0);
//get correct row
for (int i = 0; i < nRows; i++) {
if (vertical) {
siblingGeometry = itemAt(0, i)->geometry();//set geometry of single item
if (pos.x() <= (siblingGeometry.right() + border)) {
row = i;
break;
}
} else {
siblingGeometry = itemAt(i, 0)->geometry();//set geometry of single item
if (pos.y() <= (siblingGeometry.bottom() + border)) {
row = i;
break;
}
}
}
//and column
for (int i = 0; i < nCols; i++) {
if (vertical) {
siblingGeometry = itemAt(i, 0)->geometry();//set geometry of single item
qreal vertMiddle = (siblingGeometry.top() + siblingGeometry.bottom()) / 2.0;
if (pos.y() < vertMiddle) {
col = i;
break;
}
} else if (itemAt(0, i)) {
siblingGeometry = itemAt(0, i)->geometry();//set geometry of single item
qreal horizMiddle = (siblingGeometry.left() + siblingGeometry.right()) / 2.0;
if (pos.x() < horizMiddle) {
col = i;
break;
}
}
}
}
insert.index = row * nCols + col;
// Calculate geometry - used for drop indicator...
if (nCols > 0 && nRows > 0) {
int rowAdjust = row >= nRows ? 1 : 0;
int colAdjust = col >= nCols ? 1 : 0;
QGraphicsLayoutItem *item = itemAt(vertical ? (col - colAdjust) : (row - rowAdjust), vertical ? (row - rowAdjust) : (col - colAdjust));
if (item) {
insert.geom = item->geometry();
if ((rowAdjust && vertical) || (colAdjust && !vertical)) {
insert.geom.adjust(insert.geom.width(), 0, insert.geom.width(), 0);
}
if ((rowAdjust && !vertical) || (colAdjust && vertical)) {
insert.geom.adjust(0, insert.geom.height(), 0, insert.geom.height());
}
}
}
if (separatorVisible() && insert.index > m_applet->groupManager().launcherCount()) {
insert.index--;
}
//kDebug() << "insert Index" << insertIndex;
return insert;
}
int TaskItemLayout::numberOfRows()
{
if (m_layoutOrientation == Qt::Vertical) {
return columnCount();
} else {
return rowCount();
}
}
int TaskItemLayout::numberOfColumns()
{
if (m_layoutOrientation == Qt::Vertical) {
return rowCount();
} else {
return columnCount();
}
}
#include "moc_taskitemlayout.cpp"

View file

@ -1,110 +0,0 @@
/***************************************************************************
* Copyright (C) 2008 by Christian Mollekopf chrigi_1@fastmail.fm *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* 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 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 . *
***************************************************************************/
#ifndef TASKITEMLAYOUT_H
#define TASKITEMLAYOUT_H
//Own
#include "tasks.h"
// Qt
#include <QGraphicsGridLayout>
#include <QList>
class TaskGroupItem;
class AbstractTaskItem;
class LauncherSeparator;
/**
* A Layout for the expanded group
*/
class TaskItemLayout : public QObject, public QGraphicsGridLayout
{
Q_OBJECT
public:
struct Insert {
int index;
QRectF geom;
};
TaskItemLayout(TaskGroupItem * parent, Tasks *applet);
~TaskItemLayout();
/** insert the item on the index in TaskGroupItem::getMemberList */
void addTaskItem(AbstractTaskItem*);
void removeTaskItem(AbstractTaskItem*);
/** insert the item on a specific index*/
bool insert(int index, AbstractTaskItem* item);
/** returns the insert index for a task drop on pos */
Insert insertionIndexAt(const QPointF &pos);
/** set the maximum number of rows */
void setMaximumRows(int);
/** force the layout to use maximumRows setting and fill rows before columns */
void setForceRows(bool);
/** the size including expanded groups*/
int size();
/** returns columnCount or rowCount depending on m_applet->formFactor() */
int numberOfRows();
/** returns columnCount or rowCount depending on m_applet->formFactor()*/
int numberOfColumns();
/** Returns the preferred number of rows based on the user settings but limited by calculation to honor AbstractGroupableItem::basicPreferredSize()*/
int maximumRows();
/** Returns the preferred number of columns calculated on base of AbstractGroupableItem::basicPreferredSize()*/
int preferredColumns();
/** Set the layout Orientation, normally set to formFactor of applet*/
void setOrientation(Plasma::FormFactor orientation);
bool separatorVisible() const;
public Q_SLOTS:
/** Populates the actual QGraphicsGridLayout with items*/
void layoutItems();
private:
void adjustStretch();
void updatePreferredSize();
private Q_SLOTS:
bool remove(AbstractTaskItem* item);
private:
TaskGroupItem *m_groupItem;
QList <AbstractTaskItem*> m_itemPositions;
/** Calculates the number of columns and rows for the layoutItems function and returns <columns/rows>*/
QPair<int, int> gridLayoutSize();
/** Limit before row is full, more columns are added if maxRows is exeeded*/
int m_rowSize;
/** How many rows should be used*/
int m_maxRows;
bool m_forceRows;
Tasks *m_applet;
Qt::Orientation m_layoutOrientation;
LauncherSeparator *m_separator;
};
#endif

View file

@ -1,755 +0,0 @@
/***************************************************************************
* Copyright (C) 2007 by Robert Knight <robertknight@gmail.com> *
* Copyright (C) 2008 by Alexis Ménard <darktears31@gmail.com> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* 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 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 "tooltips/tooltipmanager.h"
// Own
#include "tasks.h"
#include "windowtaskitem.h"
#include "taskgroupitem.h"
#include "jobmanager.h"
#include "mediabuttons.h"
#include "recentdocuments.h"
//Taskmanager
#include "taskmanager/groupmanager.h"
#include "taskmanager/taskgroup.h"
#include "taskmanager/taskitem.h"
// KDE
#include <KConfigDialog>
#include <KDebug>
#include <KStandardDirs>
// Qt
#include <QGraphicsScene>
#include <QGraphicsLinearLayout>
#include <QVariant>
#include <QBuffer>
#include <QIODevice>
#include <QFile>
// Plasma
#include <Plasma/Containment>
#include <Plasma/FrameSvg>
#include <Plasma/Theme>
#include <Plasma/WindowEffects>
static void setCurrentIndex(QComboBox *combo, int val)
{
for (int i = 0; i < combo->count(); ++i) {
if (combo->itemData(i).toInt() == val) {
combo->setCurrentIndex(i);
break;
}
}
}
class GroupManager : public TaskManager::GroupManager
{
public:
GroupManager(Plasma::Applet *applet)
: TaskManager::GroupManager(applet),
m_applet(applet) {
setGroupingStrategy(GroupManager::ProgramGrouping);
setSortingStrategy(GroupManager::ManualSorting);
setShowOnlyCurrentDesktop(true);
setShowOnlyCurrentScreen(false);
setShowOnlyMinimized(false);
setOnlyGroupWhenFull(false);
setSeparateLaunchers(false);
setForceGrouping(true);
readLauncherConfig();
}
protected:
KConfigGroup config() const {
return m_applet->config();
}
private:
Plasma::Applet *m_applet;
};
static const int constMinSpacing = 0;
static const int constMaxSpacing = 50;
static const int constMinIconScale = 49;
static const int constMaxIconScale = 100;
Tasks::Tasks(QObject* parent, const QVariantList &arguments)
: Plasma::Applet(parent, arguments),
m_toolTips(TT_Instant),
m_highlightWindows(false),
m_launcherIcons(false),
m_groupClick(GC_PresentWindows),
m_rotate(false),
m_style(Style_Plasma),
m_showSeparator(Sep_WhenNeeded),
m_middleClick(MC_NewInstance),
m_spacing(0),
m_iconScale(constMinIconScale), // constMinIconScale==automatic scaling!!!
m_taskItemBackground(0),
m_progressBar(0),
m_badgeBackground(0),
m_indicators(0),
m_leftMargin(0),
m_topMargin(0),
m_rightMargin(0),
m_bottomMargin(0),
m_offscreenLeftMargin(0),
m_offscreenTopMargin(0),
m_offscreenRightMargin(0),
m_offscreenBottomMargin(0),
m_rootGroupItem(0),
m_groupManager(0),
m_lockAct(0),
m_unlockAct(0),
m_refreshAct(0)
{
KGlobal::locale()->insertCatalog("icontasks");
setHasConfigurationInterface(true);
setAspectRatioMode(Plasma::IgnoreAspectRatio);
m_screenTimer.setSingleShot(true);
m_screenTimer.setInterval(300);
resize(500, 58);
setAcceptDrops(true);
}
Tasks::~Tasks()
{
JobManager::self()->setEnabled(false);
MediaButtons::self()->setEnabled(false);
RecentDocuments::self()->setEnabled(false);
delete m_rootGroupItem;
delete m_groupManager;
AbstractTaskItem::clearCaches();
}
void Tasks::init()
{
m_groupManager = new GroupManager(this);
Plasma::Containment* appletContainment = containment();
if (appletContainment) {
m_groupManager->setScreen(appletContainment->screen());
}
connect(m_groupManager, SIGNAL(reload()), this, SLOT(reload()));
connect(m_groupManager, SIGNAL(configChanged()), this, SIGNAL(configNeedsSaving()));
m_rootGroupItem = new TaskGroupItem(this, this);
m_rootGroupItem->expand();
m_rootGroupItem->setGroup(m_groupManager->rootGroup());
connect(m_rootGroupItem, SIGNAL(sizeHintChanged(Qt::SizeHint)), this, SLOT(changeSizeHint(Qt::SizeHint)));
setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding));
setMaximumSize(INT_MAX, INT_MAX);
layout = new QGraphicsLinearLayout(this);
layout->setContentsMargins(0, 0, 0, 0);
layout->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding));
layout->setMaximumSize(INT_MAX, INT_MAX);
layout->setOrientation(Qt::Vertical);
layout->addItem(m_rootGroupItem);
setLayout(layout);
configChanged();
if (containment()) {
IconTasks::ToolTipManager::self()->setCorona(containment()->corona());
}
}
void Tasks::configChanged()
{
KConfigGroup cg = config();
bool changed = false;
// only update these if they have actually changed, because they make the
// group manager reload its tasks list
const bool showOnlyCurrentDesktop = cg.readEntry("showOnlyCurrentDesktop", m_groupManager->showOnlyCurrentDesktop());
if (showOnlyCurrentDesktop != m_groupManager->showOnlyCurrentDesktop()) {
m_groupManager->setShowOnlyCurrentDesktop(showOnlyCurrentDesktop);
changed = true;
}
const bool showOnlyCurrentScreen = cg.readEntry("showOnlyCurrentScreen", m_groupManager->showOnlyCurrentScreen());
if (showOnlyCurrentScreen != m_groupManager->showOnlyCurrentScreen()) {
m_groupManager->setShowOnlyCurrentScreen(showOnlyCurrentScreen);
changed = true;
}
TaskManager::GroupManager::TaskSortingStrategy sortingStrategy =
static_cast<TaskManager::GroupManager::TaskSortingStrategy>(
cg.readEntry("sortingStrategy",
static_cast<int>(m_groupManager->sortingStrategy()))
);
if (sortingStrategy != m_groupManager->sortingStrategy()) {
m_groupManager->setSortingStrategy(sortingStrategy);
changed = true;
}
const int maxRows = cg.readEntry("maxRows", m_rootGroupItem->maxRows());
if (maxRows != m_rootGroupItem->maxRows()) {
m_rootGroupItem->setMaxRows(maxRows);
changed = true;
}
const bool launcherIcons = cg.readEntry("launcherIcons", m_launcherIcons);
if (launcherIcons != m_launcherIcons) {
m_launcherIcons = launcherIcons;
changed = true;
}
const GroupClick groupClick = static_cast<GroupClick>(cg.readEntry("groupClick", static_cast<int>(m_groupClick)));
if (groupClick != m_groupClick) {
m_groupClick = groupClick;
changed = true;
}
const bool rotate = cg.readEntry("rotate", m_rotate);
if (rotate != m_rotate) {
m_rotate = rotate;
changed = true;
}
const Style style = static_cast<Style>(cg.readEntry("style", static_cast<int>(m_style)));
if (style != m_style) {
m_style = style;
changed = true;
}
if (Style_IconTasksColored != style) {
AbstractTaskItem::clearCaches(AbstractTaskItem::Cache_Bgnd);
}
const bool showProgress = cg.readEntry("showProgress", true);
if (showProgress != JobManager::self()->isEnabled()) {
changed = true;
}
JobManager::self()->setEnabled(showProgress);
const bool mediaButtons = cg.readEntry("mediaButtons", true);
if (mediaButtons != MediaButtons::self()->isEnabled()) {
changed = true;
}
MediaButtons::self()->setEnabled(mediaButtons);
const bool recentDocuments = cg.readEntry("recentDocuments", true);
if (recentDocuments != RecentDocuments::self()->isEnabled()) {
changed = true;
}
RecentDocuments::self()->setEnabled(recentDocuments);
const SeparatorType showSeparator = TaskManager::GroupManager::ManualSorting == m_groupManager->sortingStrategy()
? static_cast<SeparatorType>(cg.readEntry("showSeparator", static_cast<int>(m_showSeparator)))
: Sep_Never;
if (showSeparator != m_showSeparator) {
m_showSeparator = showSeparator;
changed = true;
}
const MiddleClick middleClick = static_cast<MiddleClick>(cg.readEntry("middleClick", static_cast<int>(m_middleClick)));
if (middleClick != m_middleClick) {
m_middleClick = middleClick;
changed = true;
}
const int spacing = cg.readEntry("spacing", m_spacing);
if (spacing != m_spacing && spacing >= constMinSpacing && spacing <= constMaxSpacing) {
m_spacing = spacing;
changed = true;
m_rootGroupItem->relayoutItems();
}
const int iconScale = cg.readEntry("iconScale", m_iconScale);
if (iconScale != m_iconScale && iconScale >= constMinIconScale && iconScale <= constMaxIconScale) {
m_iconScale = iconScale;
changed = true;
}
if (autoIconScaling()) {
AbstractTaskItem::clearCaches(AbstractTaskItem::Cache_Scale);
}
const int toolTips = cg.readEntry("toolTips", (int)m_toolTips);
if (toolTips != (int)m_toolTips && toolTips >= TT_None && toolTips <= TT_Delayed) {
m_toolTips = (TT_Type)toolTips;
changed = true;
}
const bool highlightWindows = cg.readEntry("highlightWindows", false);
if (highlightWindows != m_highlightWindows) {
m_highlightWindows = highlightWindows;
changed = true;
}
const int previewSize = cg.readEntry("previewSize", IconTasks::ToolTipManager::self()->previewWidth());
if (previewSize != IconTasks::ToolTipManager::self()->previewWidth() &&
previewSize >= IconTasks::ToolTipManager::MIN_PREVIEW_SIZE &&
previewSize <= IconTasks::ToolTipManager::MAX_PREVIEW_SIZE) {
IconTasks::ToolTipManager::self()->setPreviewSize(previewSize);
}
// If we have not already read the launchers, then try now...
// ...this is mainly required for plasmoidviewer...
if (0 == m_groupManager->launcherCount()) {
m_groupManager->readLauncherConfig();
}
const bool launchersLocked = groupManager().launcherCount()
? cg.readEntry("launchersLocked", m_groupManager->launchersLocked())
: false;
if (launchersLocked!=m_groupManager->launchersLocked()) {
m_groupManager->setLaunchersLocked(launchersLocked);
changed = true;
}
if (changed) {
emit settingsChanged();
update();
}
}
void Tasks::reload()
{
TaskGroup *newGroup = m_groupManager->rootGroup();
if (newGroup != m_rootGroupItem->abstractItem()) {
m_rootGroupItem->setGroup(newGroup);
} else {
m_rootGroupItem->reload();
}
}
TaskManager::GroupManager &Tasks::groupManager() const
{
return *m_groupManager;
}
void Tasks::constraintsEvent(Plasma::Constraints constraints)
{
if (m_groupManager && constraints & Plasma::ScreenConstraint) {
Plasma::Containment* appletContainment = containment();
if (appletContainment) {
m_groupManager->setScreen(appletContainment->screen());
}
}
if (constraints & Plasma::LocationConstraint) {
QTimer::singleShot(500, this, SLOT(publishIconGeometry()));
}
setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding));
emit constraintsChanged(constraints);
}
void Tasks::publishIconGeometry()
{
foreach (AbstractTaskItem * item, m_rootGroupItem->members()) {
item->publishIconGeometry();
}
}
Plasma::FrameSvg* Tasks::itemBackground()
{
if (!m_taskItemBackground) {
m_taskItemBackground = new Plasma::FrameSvg(this);
m_taskItemBackground->setImagePath("widgets/tasks");
m_taskItemBackground->setCacheAllRenderedFrames(true);
}
return m_taskItemBackground;
}
Plasma::FrameSvg* Tasks::progressBar()
{
if (!m_progressBar) {
m_progressBar = new Plasma::FrameSvg(this);
m_progressBar->setImagePath("icontasks/progress");
m_progressBar->setCacheAllRenderedFrames(true);
}
return m_progressBar;
}
Plasma::FrameSvg* Tasks::badgeBackground()
{
if (!m_badgeBackground) {
m_badgeBackground = new Plasma::FrameSvg(this);
m_badgeBackground->setImagePath("icontasks/badge");
m_badgeBackground->setCacheAllRenderedFrames(true);
}
return m_badgeBackground;
}
Plasma::Svg* Tasks::indicators()
{
if (!m_indicators) {
m_indicators = new Plasma::Svg(this);
m_indicators->setImagePath("icontasks/indicators");
m_indicators->setContainsMultipleImages(true);
}
return m_indicators;
}
void Tasks::resizeItemBackground(const QSizeF &size)
{
if (!m_taskItemBackground) {
itemBackground();
}
if (m_taskItemBackground->frameSize() == size) {
return;
}
m_taskItemBackground->resizeFrame(size);
QString oldPrefix = m_taskItemBackground->prefix();
m_taskItemBackground->setElementPrefix("normal");
//get the margins now
m_taskItemBackground->getMargins(m_leftMargin, m_topMargin, m_rightMargin, m_bottomMargin);
// the offscreen margins are always whatever the svg naturally is
m_offscreenLeftMargin = m_leftMargin;
m_offscreenTopMargin = m_topMargin;
m_offscreenRightMargin = m_rightMargin;
m_offscreenBottomMargin = m_bottomMargin;
//if the task height is too little shrink the top and bottom margins
if (size.height() - m_topMargin - m_bottomMargin < KIconLoader::SizeSmall) {
m_topMargin = m_bottomMargin = qMax(1, int((size.height() - KIconLoader::SizeSmall) / 2));
}
m_taskItemBackground->setElementPrefix(oldPrefix);
}
void Tasks::resizeProgressBar(const QSizeF &size)
{
if (!m_progressBar) {
progressBar();
}
if (m_progressBar->frameSize() == size) {
return;
}
m_progressBar->resizeFrame(size);
}
void Tasks::resizeBadgeBackground(const QSizeF &size)
{
if (!m_badgeBackground) {
badgeBackground();
}
if (m_badgeBackground->frameSize() == size) {
return;
}
m_badgeBackground->resizeFrame(size);
}
QSizeF Tasks::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
{
if (m_rootGroupItem && which == Qt::PreferredSize) {
return m_rootGroupItem->preferredSize();
} else {
return Plasma::Applet::sizeHint(which, constraint);
}
}
void Tasks::changeSizeHint(Qt::SizeHint which)
{
emit sizeHintChanged(which);
}
void Tasks::updateShowSeparator()
{
bool enableShowSep = 1 == m_appUi.maxRows->value() &&
TaskManager::GroupManager::ManualSorting == m_appUi.sortingStrategy->itemData(m_appUi.sortingStrategy->currentIndex()).toInt();
m_appUi.showSeparator->setEnabled(enableShowSep);
m_appUi.showSeparator_label->setEnabled(enableShowSep);
if (!enableShowSep) {
setCurrentIndex(m_appUi.showSeparator, (int)Sep_Never);
}
}
void Tasks::toolTipsModified()
{
m_appUi.previewSize->setEnabled(TT_None != m_appUi.toolTips->itemData(m_appUi.toolTips->currentIndex()).toInt());
m_appUi.previewSize_label->setEnabled(TT_None != m_appUi.toolTips->itemData(m_appUi.toolTips->currentIndex()).toInt());
}
void Tasks::styleModified()
{
m_appUi.rotate->setEnabled(Style_Plasma == m_appUi.style->itemData(m_appUi.style->currentIndex()).toInt());
if (Style_Plasma != m_appUi.style->itemData(m_appUi.style->currentIndex()).toInt()) {
m_appUi.rotate->setChecked(false);
}
m_appUi.rotate_label->setEnabled(Style_Plasma == m_appUi.style->itemData(m_appUi.style->currentIndex()).toInt());
}
void Tasks::refresh()
{
QWidget *rw = new QWidget;
rw->show();
QTimer::singleShot(25, rw, SLOT(deleteLater()));
}
void Tasks::createConfigurationInterface(KConfigDialog *parent)
{
QWidget *appearance = new QWidget;
QWidget *behaviour = new QWidget;
m_appUi.setupUi(appearance);
m_behaviourUi.setupUi(behaviour);
connect(parent, SIGNAL(applyClicked()), this, SLOT(configAccepted()));
connect(parent, SIGNAL(okClicked()), this, SLOT(configAccepted()));
parent->addPage(appearance, i18n("Appearance"), "preferences-desktop-theme");
parent->addPage(behaviour, i18n("Behaviour"), "system-run");
m_appUi.toolTips->addItem(i18n("Do Not Show"), QVariant(TT_None));
m_appUi.toolTips->addItem(i18n("Show Immediately"), QVariant(TT_Instant));
m_appUi.toolTips->addItem(i18n("Show After Delay"), QVariant(TT_Delayed));
connect(m_appUi.toolTips, SIGNAL(currentIndexChanged(int)), parent, SLOT(settingsModified()));
connect(m_appUi.toolTips, SIGNAL(currentIndexChanged(int)), this, SLOT(toolTipsModified()));
setCurrentIndex(m_appUi.toolTips, (int)m_toolTips);
m_appUi.highlightWindows->setChecked(m_highlightWindows);
m_appUi.launcherIcons->setChecked(m_launcherIcons);
m_behaviourUi.groupClick->addItem(i18n("Minimize/Restore"), QVariant(GC_MinMax));
m_behaviourUi.groupClick->addItem(i18n("Present Windows Effect"), QVariant(GC_PresentWindows));
m_behaviourUi.groupClick->addItem(i18n("Show Popup Menu"), QVariant(GC_Popup));
setCurrentIndex(m_behaviourUi.groupClick, m_groupClick);
m_appUi.rotate->setChecked(m_rotate);
m_appUi.style->addItem(i18n("Use Workspace Theme"), QVariant(Style_Plasma));
m_appUi.style->addItem(i18n("Use Indicators"), QVariant(Style_IconTasks));
m_appUi.style->addItem(i18n("Use Indicators & Colored Background"), QVariant(Style_IconTasksColored));
m_appUi.style->setCurrentIndex((int)m_style);
m_appUi.showSeparator->addItem(i18n("Never Show"), QVariant(Sep_Never));
m_appUi.showSeparator->addItem(i18n("Show When Required"), QVariant(Sep_WhenNeeded));
m_appUi.showSeparator->addItem(i18n("Always Show"), QVariant(Sep_Always));
m_appUi.showSeparator->setCurrentIndex((int)m_showSeparator);
m_behaviourUi.middleClick->addItem(i18n("Start New Instance"), QVariant(MC_NewInstance));
m_behaviourUi.middleClick->addItem(i18n("Close Application"), QVariant(MC_Close));
m_behaviourUi.middleClick->addItem(i18n("Move To Current Desktop"), QVariant(MC_MoveToCurrentDesktop));
m_behaviourUi.middleClick->addItem(i18n("Nothing"), QVariant(MC_None));
m_behaviourUi.middleClick->setCurrentIndex((int)m_middleClick);
setCurrentIndex(m_behaviourUi.middleClick, (int)m_middleClick);
m_behaviourUi.showProgress->setChecked(JobManager::self()->isEnabled());
m_behaviourUi.mediaButtons->setChecked(MediaButtons::self()->isEnabled());
m_behaviourUi.recentDocuments->setChecked(RecentDocuments::self()->isEnabled());
m_appUi.spacing->setRange(constMinSpacing, constMaxSpacing);
m_appUi.spacing->setValue(m_spacing);
m_appUi.previewSize->setRange(IconTasks::ToolTipManager::MIN_PREVIEW_SIZE, IconTasks::ToolTipManager::MAX_PREVIEW_SIZE);
m_appUi.previewSize->setValue(IconTasks::ToolTipManager::self()->previewWidth());
m_appUi.previewSize->setSingleStep(50);
m_appUi.iconScale->setRange(constMinIconScale, constMaxIconScale);
m_appUi.iconScale->setSingleStep(5);
m_appUi.iconScale->setValue(m_iconScale);
m_appUi.iconScale->setSpecialValueText(i18n("Automatic"));
m_behaviourUi.showOnlyCurrentDesktop->setChecked(m_groupManager->showOnlyCurrentDesktop());
m_behaviourUi.showOnlyCurrentScreen->setChecked(m_groupManager->showOnlyCurrentScreen());
m_appUi.sortingStrategy->addItem(i18n("Manually"), QVariant(TaskManager::GroupManager::ManualSorting));
m_appUi.sortingStrategy->addItem(i18n("Alphabetically"), QVariant(TaskManager::GroupManager::AlphaSorting));
m_appUi.sortingStrategy->addItem(i18n("By Desktop"), QVariant(TaskManager::GroupManager::DesktopSorting));
setCurrentIndex(m_appUi.sortingStrategy, (int)m_groupManager->sortingStrategy());
m_appUi.maxRows->setValue(m_rootGroupItem->maxRows());
connect(m_appUi.toolTips, SIGNAL(currentIndexChanged(int)), parent, SLOT(settingsModified()));
connect(m_appUi.highlightWindows, SIGNAL(toggled(bool)), parent, SLOT(settingsModified()));
connect(m_appUi.launcherIcons, SIGNAL(toggled(bool)), parent, SLOT(settingsModified()));
connect(m_behaviourUi.groupClick, SIGNAL(currentIndexChanged(int)), parent, SLOT(settingsModified()));
connect(m_appUi.rotate, SIGNAL(toggled(bool)), parent, SLOT(settingsModified()));
connect(m_appUi.style, SIGNAL(currentIndexChanged(int)), this, SLOT(styleModified()));
connect(m_appUi.style, SIGNAL(currentIndexChanged(int)), parent, SLOT(settingsModified()));
connect(m_appUi.showSeparator, SIGNAL(currentIndexChanged(int)), parent, SLOT(settingsModified()));
connect(m_behaviourUi.middleClick, SIGNAL(currentIndexChanged(int)), parent, SLOT(settingsModified()));
connect(m_behaviourUi.showProgress, SIGNAL(toggled(bool)), parent, SLOT(settingsModified()));
connect(m_behaviourUi.mediaButtons, SIGNAL(toggled(bool)), parent, SLOT(settingsModified()));
connect(m_appUi.spacing, SIGNAL(valueChanged(int)), parent, SLOT(settingsModified()));
connect(m_appUi.previewSize, SIGNAL(valueChanged(int)), parent, SLOT(settingsModified()));
connect(m_appUi.iconScale, SIGNAL(valueChanged(int)), parent, SLOT(settingsModified()));
connect(m_appUi.maxRows, SIGNAL(valueChanged(int)), SLOT(updateShowSeparator()));
connect(m_appUi.maxRows, SIGNAL(valueChanged(int)), parent, SLOT(settingsModified()));
connect(m_appUi.sortingStrategy, SIGNAL(currentIndexChanged(int)), SLOT(updateShowSeparator()));
connect(m_behaviourUi.showOnlyCurrentScreen, SIGNAL(toggled(bool)), parent, SLOT(settingsModified()));
connect(m_behaviourUi.showOnlyCurrentDesktop, SIGNAL(toggled(bool)), parent, SLOT(settingsModified()));
m_appUi.launcherIcons_label->setToolTip(m_appUi.launcherIcons->toolTip());
m_behaviourUi.groupClick_label->setToolTip(m_behaviourUi.groupClick->toolTip());
m_appUi.rotate_label->setToolTip(m_appUi.rotate->toolTip());
m_appUi.style_label->setToolTip(m_appUi.style->toolTip());
m_appUi.maxRows_label->setToolTip(m_appUi.maxRows->toolTip());
m_appUi.spacing_label->setToolTip(m_appUi.spacing->toolTip());
m_appUi.previewSize_label->setToolTip(m_appUi.previewSize->toolTip());
m_appUi.iconScale_label->setToolTip(m_appUi.iconScale->toolTip());
m_appUi.showSeparator_label->setToolTip(m_appUi.showSeparator->toolTip());
m_behaviourUi.showProgress_label->setToolTip(m_behaviourUi.showProgress->toolTip());
m_behaviourUi.mediaButtons_label->setToolTip(m_behaviourUi.mediaButtons->toolTip());
m_behaviourUi.middleClick_label->setToolTip(m_behaviourUi.middleClick->toolTip());
updateShowSeparator();
toolTipsModified();
styleModified();
m_groupManager->createConfigurationInterface(parent);
parent->resize(640, 480);
}
void Tasks::configAccepted()
{
// just write the config here, and it will get applied in configChanged(),
// which is called after this when the config dialog is accepted
KConfigGroup cg = config();
cg.writeEntry("showOnlyCurrentDesktop", m_behaviourUi.showOnlyCurrentDesktop->isChecked());
cg.writeEntry("showOnlyCurrentScreen", m_behaviourUi.showOnlyCurrentScreen->isChecked());
cg.writeEntry("sortingStrategy", m_appUi.sortingStrategy->itemData(m_appUi.sortingStrategy->currentIndex()).toInt());
cg.writeEntry("maxRows", m_appUi.maxRows->value());
cg.writeEntry("launcherIcons", m_appUi.launcherIcons->checkState() == Qt::Checked);
cg.writeEntry("groupClick", m_behaviourUi.groupClick->itemData(m_behaviourUi.groupClick->currentIndex()).toInt());
cg.writeEntry("rotate", m_appUi.rotate->checkState() == Qt::Checked);
cg.writeEntry("style", m_appUi.style->itemData(m_appUi.style->currentIndex()).toInt());
cg.writeEntry("showSeparator", m_appUi.showSeparator->itemData(m_appUi.showSeparator->currentIndex()).toInt());
cg.writeEntry("middleClick", m_behaviourUi.middleClick->itemData(m_behaviourUi.middleClick->currentIndex()).toInt());
cg.writeEntry("showProgress", m_behaviourUi.showProgress->checkState() == Qt::Checked);
cg.writeEntry("mediaButtons", m_behaviourUi.mediaButtons->checkState() == Qt::Checked);
cg.writeEntry("recentDocuments", m_behaviourUi.recentDocuments->checkState() == Qt::Checked);
cg.writeEntry("spacing", m_appUi.spacing->value());
cg.writeEntry("previewSize", m_appUi.previewSize->value());
cg.writeEntry("iconScale", m_appUi.iconScale->value());
cg.writeEntry("toolTips", m_appUi.toolTips->itemData(m_appUi.toolTips->currentIndex()).toInt());
cg.writeEntry("highlightWindows", m_appUi.highlightWindows->checkState() == Qt::Checked);
emit configNeedsSaving();
}
bool Tasks::showToolTip() const
{
return TT_None != m_toolTips;
}
bool Tasks::instantToolTip() const
{
return TT_Instant == m_toolTips;
}
bool Tasks::autoIconScaling() const
{
return constMinIconScale == m_iconScale;
}
bool Tasks::highlightWindows() const
{
return m_highlightWindows;
}
QList<QAction*> Tasks::contextualActions()
{
QList<QAction*> actionList;
if (groupManager().launcherCount() && !groupManager().separateLaunchers() &&
TaskManager::GroupManager::ManualSorting == groupManager().sortingStrategy()) {
if (groupManager().launchersLocked()) {
if (!m_unlockAct) {
m_unlockAct = new QAction(KIcon("object-unlocked"), i18n("Unlock Launchers"), this);
connect(m_unlockAct, SIGNAL(triggered(bool)), this, SLOT(unlockLaunchers()));
}
actionList.append(m_unlockAct);
} else {
if (!m_lockAct) {
m_lockAct = new QAction(KIcon("object-locked"), i18n("Lock Launchers"), this);
connect(m_lockAct, SIGNAL(triggered(bool)), this, SLOT(lockLaunchers()));
}
actionList.append(m_lockAct);
}
}
if (!m_refreshAct) {
m_refreshAct = new QAction(KIcon("view-refresh"), i18n("Refresh"), this);
connect(m_refreshAct, SIGNAL(triggered(bool)), this, SLOT(refresh()));
}
actionList.append(m_refreshAct);
return actionList;
}
void Tasks::lockLaunchers()
{
if (!m_groupManager->launchersLocked()) {
m_groupManager->setLaunchersLocked(true);
config().writeEntry("launchersLocked", m_groupManager->launchersLocked());
emit configNeedsSaving();
}
}
void Tasks::unlockLaunchers()
{
if (m_groupManager->launchersLocked()) {
m_groupManager->setLaunchersLocked(false);
config().writeEntry("launchersLocked", m_groupManager->launchersLocked());
emit configNeedsSaving();
}
}
void Tasks::needsVisualFocus(bool focus)
{
if (focus) {
setStatus(Plasma::NeedsAttentionStatus);
} else {
foreach (AbstractTaskItem * item, m_rootGroupItem->members()) {
if (item->taskFlags() & AbstractTaskItem::TaskWantsAttention) {
// not time to go passive yet! :)
return;
}
}
setStatus(Plasma::PassiveStatus);
}
}
TaskGroupItem* Tasks::rootGroupItem()
{
return m_rootGroupItem;
}
QWidget *Tasks::popupDialog() const
{
return m_popupDialog.data();
}
bool Tasks::isPopupShowing() const
{
return m_popupDialog || m_rootGroupItem->windowPreviewOpen();
}
void Tasks::setPopupDialog(bool status)
{
Q_UNUSED(status)
QWidget *widget = qobject_cast<QWidget *>(sender());
if (status && widget->isVisible()) {
m_popupDialog = widget;
} else if (m_popupDialog.data() == widget) {
m_popupDialog.clear();
}
}
K_EXPORT_PLASMA_APPLET(icontasks, Tasks)
#include "moc_tasks.cpp"

View file

@ -1,255 +0,0 @@
/***************************************************************************
* Copyright (C) 2007 by Robert Knight <robertknight@gmail.com> *
* Copyright (C) 2008 by Alexis Ménard <darktears31@gmail.com> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* 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 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 . *
***************************************************************************/
#ifndef TASKS_H
#define TASKS_H
// Own
#include "ui_appearanceconfig.h"
#include "ui_behaviourconfig.h"
// Qt
#include <QtCore/qsharedpointer.h>
#include <QTimer>
#include <QSize>
// KDE
#include "taskmanager/taskmanager.h"
#include "taskmanager/abstractgroupableitem.h"
#include "taskmanager/groupmanager.h"
#include "taskmanager/taskitem.h"
#include "taskmanager/startup.h"
// Plasma
#include <Plasma/Applet>
#include <QGraphicsLinearLayout>
namespace Plasma
{
class LayoutAnimator;
class FrameSvg;
} // namespace Plasma
namespace TaskManager
{
class GroupManager;
} // namespace TaskManager
class TaskGroupItem;
class GroupManager;
/**
* An applet which provides a visual representation of running
* graphical tasks (ie. tasks that have some form of visual interface),
* and allows the user to perform various actions on those tasks such
* as bringing them to the foreground, sending them to the background
* or closing them.
*/
class Tasks : public Plasma::Applet
{
Q_OBJECT
public:
enum TT_Type {
TT_None,
TT_Instant,
TT_Delayed
};
enum SeparatorType {
Sep_Never,
Sep_WhenNeeded,
Sep_Always
};
enum MiddleClick {
MC_NewInstance,
MC_Close,
MC_None,
MC_MoveToCurrentDesktop
};
enum GroupClick {
GC_MinMax,
GC_PresentWindows,
GC_Popup
};
enum Style {
Style_Plasma,
Style_IconTasks,
Style_IconTasksColored
};
/**
* Constructs a new tasks applet
* With the specified parent.
*/
explicit Tasks(QObject *parent, const QVariantList &args = QVariantList());
~Tasks();
void init();
void constraintsEvent(Plasma::Constraints constraints);
Plasma::FrameSvg *itemBackground();
Plasma::FrameSvg *progressBar();
Plasma::FrameSvg *badgeBackground();
Plasma::Svg* indicators();
qreal itemLeftMargin() {
return m_leftMargin;
}
qreal itemRightMargin() {
return m_rightMargin;
}
qreal itemTopMargin() {
return m_topMargin;
}
qreal itemBottomMargin() {
return m_bottomMargin;
}
qreal offscreenLeftMargin() {
return m_offscreenLeftMargin;
}
qreal offscreenRightMargin() {
return m_offscreenRightMargin;
}
qreal offscreenTopMargin() {
return m_offscreenTopMargin;
}
qreal offscreenBottomMargin() {
return m_offscreenBottomMargin;
}
void resizeItemBackground(const QSizeF &newSize);
void resizeProgressBar(const QSizeF &size);
void resizeBadgeBackground(const QSizeF &size);
TaskGroupItem *rootGroupItem();
TaskManager::GroupManager &groupManager() const;
bool showToolTip() const;
bool instantToolTip() const;
bool autoIconScaling() const;
bool highlightWindows() const;
bool launcherIcons() const {
return m_launcherIcons;
}
GroupClick groupClick() const {
return m_groupClick;
}
bool rotate() const {
return m_rotate;
}
Style style() const {
return m_style;
}
SeparatorType showSeparator() const {
return m_showSeparator;
}
MiddleClick middleClick() const {
return m_middleClick;
}
int spacing() const {
return m_spacing;
}
int iconScale() const {
return m_iconScale;
}
void needsVisualFocus(bool focus);
QWidget *popupDialog() const;
bool isPopupShowing() const;
QList<QAction*> contextualActions();
signals:
/**
* emitted whenever we receive a constraintsEvent
*/
void constraintsChanged(Plasma::Constraints);
void settingsChanged();
public slots:
void configChanged();
void publishIconGeometry();
protected slots:
void configAccepted();
void setPopupDialog(bool status);
protected:
void createConfigurationInterface(KConfigDialog *parent);
QSizeF sizeHint(Qt::SizeHint which, const QSizeF & constraint = QSizeF()) const;
private slots:
/**
* Somthing has changed in the tree of the GroupingStrategy
*/
void reload();
void changeSizeHint(Qt::SizeHint which);
void updateShowSeparator();
void toolTipsModified();
void styleModified();
void refresh();
void lockLaunchers();
void unlockLaunchers();
private:
TT_Type m_toolTips;
bool m_highlightWindows;
bool m_launcherIcons;
GroupClick m_groupClick;
bool m_rotate;
Style m_style;
SeparatorType m_showSeparator;
MiddleClick m_middleClick;
int m_spacing;
int m_iconScale;
QGraphicsLinearLayout *layout;
Ui::appearanceconfig m_appUi;
Ui::behaviourconfig m_behaviourUi;
QTimer m_screenTimer;
Plasma::FrameSvg *m_taskItemBackground;
Plasma::FrameSvg *m_progressBar;
Plasma::FrameSvg *m_badgeBackground;
Plasma::Svg *m_indicators;
qreal m_leftMargin;
qreal m_topMargin;
qreal m_rightMargin;
qreal m_bottomMargin;
qreal m_offscreenLeftMargin;
qreal m_offscreenTopMargin;
qreal m_offscreenRightMargin;
qreal m_offscreenBottomMargin;
TaskGroupItem *m_rootGroupItem;
GroupManager *m_groupManager;
QWeakPointer<QWidget> m_popupDialog;
QAction *m_lockAct;
QAction *m_unlockAct;
QAction *m_refreshAct;
};
#endif

View file

@ -1,541 +0,0 @@
/*
* Copyright 2007 by Dan Meltzer <hydrogen@notyetimplemented.com>
* Copyright (C) 2008 by Alexis Ménard <darktears31@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2, or
* (at your option) any later version.
*
* 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 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 "tooltip_p.h"
#include "tooltipmanager.h"
#include "windowpreview_p.h"
#include <QAbstractTextDocumentLayout>
#include <QBitmap>
#include <QGridLayout>
#include <QLabel>
#include <QPaintEvent>
#include <QPainter>
#include <QPalette>
#include <QTextDocument>
#include <QPropertyAnimation>
#include <QToolButton>
#ifdef Q_WS_X11
#include <QX11Info>
#include <netwm.h>
#endif
#include <KDebug>
#include <KGlobal>
#include <KGlobalSettings>
#include <KWindowSystem>
#include <KIcon>
#include <KIconLoader>
#include <KIconEffect>
#include <KPixmapWidget>
#include <plasma/plasma.h>
#include <plasma/paintutils.h>
#include <plasma/theme.h>
#include <plasma/framesvg.h>
#include <plasma/windoweffects.h>
using namespace Plasma;
namespace IconTasks
{
class TipTextWidget : public QWidget
{
public:
TipTextWidget(ToolTip *parent)
: QWidget(parent),
m_toolTip(parent),
m_document(new QTextDocument(this)) {
}
void setStyleSheet(const QString &css) {
m_document->setDefaultStyleSheet(css);
}
void setContent(const ToolTipContent &data) {
QString html;
if (!data.mainText().isEmpty()) {
html.append("<b>" + data.mainText() + "</b><br/>");
}
html.append(data.subText());
m_anchor.clear();
m_document->clear();
data.registerResources(m_document);
if (!html.isEmpty()) {
m_document->setHtml("<p>" + html + "</p>");
}
m_document->adjustSize();
update();
}
QSize minimumSizeHint() const {
const int margin = 6;
return m_document->size().toSize() + QSize(margin, margin)*2;
}
QSize maximumSizeHint() const {
return minimumSizeHint();
}
void paintEvent(QPaintEvent *event) {
QPainter p(this);
m_document->drawContents(&p, event->rect());
}
void mousePressEvent(QMouseEvent *event) {
QAbstractTextDocumentLayout *layout = m_document->documentLayout();
if (layout) {
m_anchor = layout->anchorAt(event->pos());
}
}
void mouseReleaseEvent(QMouseEvent *event) {
QAbstractTextDocumentLayout *layout = m_document->documentLayout();
if (layout) {
QString anchor = layout->anchorAt(event->pos());
if (anchor == m_anchor) {
m_toolTip->linkActivated(m_anchor, event);
}
m_anchor.clear();
}
}
private:
ToolTip *m_toolTip;
QTextDocument *m_document;
QString m_anchor;
};
class MediaButton : public QWidget
{
public:
MediaButton(ToolTip *parent, const char *i1, const char *i2 = 0)
: QWidget(parent)
, m_toolTip(parent)
, m_state(0)
, m_hover(0) {
int iconSize = 32;
resize(iconSize, iconSize);
setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
setMouseTracking(true);
m_icon[0][0] = KIcon(i1).pixmap(iconSize, iconSize);
KIconEffect *effect = KIconLoader::global()->iconEffect();
if (effect->hasEffect(KIconLoader::Desktop, KIconLoader::ActiveState)) {
m_icon[0][1] = effect->apply(m_icon[0][0], KIconLoader::Desktop, KIconLoader::ActiveState);
} else {
m_icon[0][1] = m_icon[0][0];
}
if (i2) {
m_icon[1][0] = KIcon(i2).pixmap(iconSize, iconSize);
if (effect->hasEffect(KIconLoader::Desktop, KIconLoader::ActiveState)) {
m_icon[1][1] = effect->apply(m_icon[1][0], KIconLoader::Desktop, KIconLoader::ActiveState);
} else {
m_icon[1][1] = m_icon[1][0];
}
}
}
QSize sizeHint() const {
return m_icon[0][0].size();
}
void paintEvent(QPaintEvent *e) {
Q_UNUSED(e)
QPainter painter(this);
painter.drawPixmap(rect().x(), rect().y(), m_icon[m_state][m_hover]);
painter.end();
}
void enterEvent(QEvent *e) {
Q_UNUSED(e)
m_hover = 1;
repaint();
}
void leaveEvent(QEvent *e) {
Q_UNUSED(e)
m_hover = 0;
repaint();
}
void mouseReleaseEvent(QMouseEvent *e) {
Q_UNUSED(e)
m_toolTip->buttonPressed(this);
}
void setChecked(bool c) {
if ((c && 0 == m_state) || (!c && 1 == m_state)) {
m_state = c && !m_icon[1][0].isNull() ? 1 : 0;
if (isVisible()) {
repaint();
}
}
}
private:
ToolTip *m_toolTip;
int m_state;
int m_hover;
QPixmap m_icon[2][2];
};
class ToolTipPrivate
{
public:
ToolTipPrivate()
: text(0),
imageWidget(0),
preview(0),
direction(Plasma::Up),
autohide(true),
hovered(false)
{ }
TipTextWidget *text;
KPixmapWidget *imageWidget;
WindowPreview *preview;
FrameSvg *background;
QWeakPointer<QObject> source;
QPropertyAnimation *animation;
Plasma::Direction direction;
MediaButton *prev;
MediaButton *playPause;
MediaButton *next;
bool autohide;
bool hovered;
};
/*
* media-skip-forward
* media-skip-backward
*/
ToolTip::ToolTip(QWidget *parent)
: QWidget(parent),
d(new ToolTipPrivate())
{
setAttribute(Qt::WA_TranslucentBackground);
setWindowFlags(Qt::ToolTip);
d->preview = new WindowPreview(this);
d->text = new TipTextWidget(this);
d->imageWidget = new KPixmapWidget(this);
d->imageWidget->setAlignment(Qt::AlignTop | Qt::AlignLeft);
d->animation = new QPropertyAnimation(this, "pos", this);
d->animation->setEasingCurve(QEasingCurve::InOutQuad);
d->animation->setDuration(250);
d->background = new FrameSvg(this);
d->background->setImagePath("widgets/tooltip");
d->background->setEnabledBorders(FrameSvg::AllBorders);
updateTheme();
connect(d->background, SIGNAL(repaintNeeded()), this, SLOT(updateTheme()));
connect(d->preview, SIGNAL(windowPreviewClicked(WId, Qt::MouseButtons, Qt::KeyboardModifiers, QPoint)),
this, SIGNAL(activateWindowByWId(WId, Qt::MouseButtons, Qt::KeyboardModifiers, QPoint)));
connect(d->preview, SIGNAL(windowButtonClicked(WId, Qt::MouseButtons, Qt::KeyboardModifiers, QPoint)),
this, SIGNAL(closeWindowByWId(WId, Qt::MouseButtons, Qt::KeyboardModifiers, QPoint)));
QHBoxLayout *previewHBoxLayout = new QHBoxLayout;
previewHBoxLayout->addWidget(d->preview);
QHBoxLayout *iconTextHBoxLayout = new QHBoxLayout;
iconTextHBoxLayout->addWidget(d->imageWidget);
iconTextHBoxLayout->setAlignment(d->imageWidget, Qt::AlignCenter);
iconTextHBoxLayout->addWidget(d->text);
iconTextHBoxLayout->setAlignment(d->text, Qt::AlignLeft | Qt::AlignVCenter);
iconTextHBoxLayout->setStretchFactor(d->text, 1);
QHBoxLayout *mediaHBoxLayout = new QHBoxLayout;
d->prev = new MediaButton(this, "media-skip-backward");
d->playPause = new MediaButton(this, "media-playback-start", "media-playback-pause");
d->next = new MediaButton(this, "media-skip-forward");
mediaHBoxLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::MinimumExpanding, QSizePolicy::Fixed));
mediaHBoxLayout->addWidget(d->prev);
mediaHBoxLayout->addWidget(d->playPause);
mediaHBoxLayout->addWidget(d->next);
mediaHBoxLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::MinimumExpanding, QSizePolicy::Fixed));
QVBoxLayout *mainLayout = new QVBoxLayout;
mainLayout->addLayout(previewHBoxLayout);
mainLayout->addLayout(iconTextHBoxLayout);
mainLayout->addLayout(mediaHBoxLayout);
setLayout(mainLayout);
setProperty("_KDE_NET_WM_SKIP_SHADOW", true); // Prevent oxygen shadows - we're not really a Plasma::ToolTip so need to do this :-(
}
ToolTip::~ToolTip()
{
delete d;
}
void ToolTip::showEvent(QShowEvent *e)
{
checkSize();
QWidget::showEvent(e);
d->preview->setInfo();
}
void ToolTip::hideEvent(QHideEvent *e)
{
QWidget::hideEvent(e);
d->animation->stop();
QObject *source = d->source.data();
if (source && source->metaObject()->indexOfMethod("toolTipHidden()") != -1) {
QMetaObject::invokeMethod(source, "toolTipHidden");
}
WindowEffects::highlightWindows(winId(), QList<WId>());
d->hovered = false;
}
void ToolTip::mouseReleaseEvent(QMouseEvent *event)
{
if (rect().contains(event->pos()) &&
(!d->preview || !d->preview->geometry().contains(event->pos()))) {
hide();
}
}
void ToolTip::enterEvent(QEvent *)
{
d->hovered = true;
emit hovered(true);
}
void ToolTip::leaveEvent(QEvent *)
{
d->hovered = false;
emit hovered(false);
}
void ToolTip::checkSize()
{
//FIXME: layout bugs even on qlayouts? oh, please, no.
d->text->setMinimumSize(0, 0);
d->text->setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
d->text->setMinimumSize(d->text->minimumSizeHint());
d->text->setMaximumSize(d->text->maximumSizeHint());
adjustSize();
}
void ToolTip::adjustPosition(const QSize &previous, const QSize &current)
{
if (previous != current) {
//offsets to stop tooltips from jumping when they resize
int deltaX = 0;
int deltaY = 0;
if (d->direction == Plasma::Up) {
/*
kDebug() << "resizing from" << current << "to" << hint
<< "and moving from" << pos() << "to"
<< x() << y() + (current.height() - hint.height())
<< current.height() - hint.height();
*/
deltaY = previous.height() - current.height();
} else if (d->direction == Plasma::Left) {
/*
kDebug() << "vertical resizing from" << current << "to" << hint
<< "and moving from" << pos() << "to"
<< x() + (current.width() - hint.width()) << y()
<< current.width() - hint.width(); */
deltaX = previous.width() - current.width();
}
// resize then move if we're getting smaller, vice versa when getting bigger
// this prevents overlap with the item in the smaller case, and a repaint of
// the tipped item when getting bigger
move(x() + deltaX, y() + deltaY);
}
}
void ToolTip::setContent(QObject *tipper, const ToolTipContent &data)
{
QObject *source = d->source.data();
if (source && source!=tipper && source->metaObject()->indexOfMethod("toolTipHidden()") != -1) {
QMetaObject::invokeMethod(source, "toolTipHidden");
}
//reset our size
if (data.mediaUpdate()) {
d->playPause->setChecked("Playing" == data.playState());
return;
}
if (data.windowsToPreview().size()) {
d->text->setVisible(false);
d->imageWidget->setVisible(false);
} else {
d->text->setVisible(true);
d->imageWidget->setVisible(true);
d->text->setContent(data);
d->imageWidget->setPixmap(data.image());
}
if (!data.playState().isEmpty()) {
d->prev->setVisible(true);
d->playPause->setVisible(true);
d->playPause->setChecked("Playing" == data.playState());
d->next->setVisible(true);
} else {
d->prev->setVisible(false);
d->playPause->setVisible(false);
d->next->setVisible(false);
}
if (data.highlightWindows() && (data.windowsToPreview().size() > 1 || data.windowToPreview() != 0)) {
WindowEffects::highlightWindows(winId(), QList<WId>() << winId() << data.windowsToPreview());
}
d->preview->setVertical(data.vertical());
if (data.windowsToPreview().size() > 0) {
d->preview->setWindows(data.windowDetailsToPreview());
} else {
d->preview->setWindows(QList<ToolTipContent::Window>());
}
d->preview->setHighlightWindows(data.highlightWindows());
d->autohide = data.autohide();
d->source = tipper;
if (isVisible()) {
d->preview->setInfo();
//kDebug() << "about to check size";
checkSize();
if (d->hovered) {
// Updating tooltip content causes ToolTipManager to restart its hide timer. But if we are visible, and hovered, then re-emit this...
emit hovered(true);
}
}
}
void ToolTip::prepareShowing()
{
if (!d->preview->isEmpty()) {
// show/hide the preview area
d->preview->show();
} else {
d->preview->hide();
}
layout()->activate();
d->preview->setInfo();
//kDebug() << "about to check size";
checkSize();
}
void ToolTip::moveTo(const QPoint &to)
{
if (!isVisible() ||
!(KGlobalSettings::graphicEffectsLevel() & KGlobalSettings::SimpleAnimationEffects)) {
move(to);
return;
}
d->animation->stop();
d->animation->setEndValue(to);
d->animation->start();
}
void ToolTip::resizeEvent(QResizeEvent *e)
{
QWidget::resizeEvent(e);
d->background->resizeFrame(size());
setMask(d->background->mask());
d->preview->setInfo();
if (isVisible()) {
adjustPosition(e->oldSize(), e->size());
}
}
void ToolTip::paintEvent(QPaintEvent *e)
{
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
painter.setClipRect(e->rect());
painter.setCompositionMode(QPainter::CompositionMode_Source);
painter.fillRect(rect(), Qt::transparent);
d->background->paintFrame(&painter);
}
bool ToolTip::autohide() const
{
return d->autohide;
}
void ToolTip::setDirection(Plasma::Direction direction)
{
d->direction = direction;
}
void ToolTip::linkActivated(const QString &anchor, QMouseEvent *event)
{
emit linkActivated(anchor, event->buttons(), event->modifiers(), event->globalPos());
}
void ToolTip::buttonPressed(MediaButton *btn)
{
if (btn == d->prev) {
emit mediaButtonPressed(ToolTipManager::MB_PREV);
} else if (btn == d->playPause) {
emit mediaButtonPressed(ToolTipManager::MB_PLAY_PAUSE);
} else if (btn == d->next) {
emit mediaButtonPressed(ToolTipManager::MB_NEXT);
}
}
void ToolTip::updateTheme()
{
const int topHeight = d->background->marginSize(Plasma::TopMargin);
const int leftWidth = d->background->marginSize(Plasma::LeftMargin);
const int rightWidth = d->background->marginSize(Plasma::RightMargin);
const int bottomHeight = d->background->marginSize(Plasma::BottomMargin);
setContentsMargins(leftWidth, topHeight, rightWidth, bottomHeight);
// Make the tooltip use Plasma's colorscheme
QColor textColor = Plasma::Theme::defaultTheme()->color(Plasma::Theme::TextColor);
QPalette plasmaPalette = QPalette();
plasmaPalette.setColor(QPalette::Window,
Plasma::Theme::defaultTheme()->color(Plasma::Theme::BackgroundColor));
plasmaPalette.setColor(QPalette::WindowText, textColor);
setAutoFillBackground(true);
setPalette(plasmaPalette);
update();
}
} // namespace Plasma
#include "moc_tooltip_p.cpp"

View file

@ -1,86 +0,0 @@
/*
* Copyright 2007 by Dan Meltzer <hydrogen@notyetimplemented.com>
* Copyright (C) 2008 by Alexis Ménard <darktears31@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2, or
* (at your option) any later version.
*
* 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 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.
*/
#ifndef PLASMA_TOOLTIP_P_H
#define PLASMA_TOOLTIP_P_H
#include <QWidget> // base class
#include "tooltipmanager.h" //Content struct
namespace IconTasks
{
class ToolTipPrivate;
class MediaButton;
class ToolTip : public QWidget
{
Q_OBJECT
public:
ToolTip(QWidget *parent);
~ToolTip();
void setContent(QObject *tipper, const ToolTipContent &data);
void prepareShowing();
void moveTo(const QPoint &to);
bool autohide() const;
void setDirection(Plasma::Direction);
void linkActivated(const QString &anchor, QMouseEvent *event);
void buttonPressed(MediaButton *btn);
Q_SIGNALS:
void activateWindowByWId(WId wid,
Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers,
const QPoint& screenPos);
void closeWindowByWId(WId wid,
Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers,
const QPoint& screenPos);
void linkActivated(const QString &anchor,
Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers,
const QPoint& screenPos);
void hovered(bool hovered);
void mediaButtonPressed(int b);
protected:
void checkSize();
void adjustPosition(const QSize &previous, const QSize &current);
void showEvent(QShowEvent *);
void hideEvent(QHideEvent *);
void mouseReleaseEvent(QMouseEvent *);
void enterEvent(QEvent *);
void leaveEvent(QEvent *);
void resizeEvent(QResizeEvent *);
void paintEvent(QPaintEvent *);
private Q_SLOTS:
void updateTheme();
private:
ToolTipPrivate * const d;
};
} // namespace Plasma
#endif // PLASMA_TOOLTIP_P_H

View file

@ -1,330 +0,0 @@
/*
* Copyright 2008 by Aaron Seigo <aseigo@kde.org>
* Copyright 2011 Craig Drummond <craig@kde.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
#include "tooltipcontent.h"
#include <QGraphicsWidget>
#include <QHash>
#include <QTextDocument>
#include <kiconloader.h>
namespace IconTasks
{
struct ToolTipResource {
ToolTipResource() {
}
ToolTipResource(ToolTipContent::ResourceType t, const QVariant &v)
: type(t),
data(v) {
}
ToolTipContent::ResourceType type;
QVariant data;
};
const int MAXIMUM_TEXT_LENGTH = 5000;
class ToolTipContentPrivate
{
public:
ToolTipContentPrivate()
: autohide(true),
instantPopup(false),
clickable(false),
highlightWindows(false),
mediaUpdate(false) {
}
QString mainText;
QString subText;
QPixmap image;
QList<ToolTipContent::Window> windowsToPreview;
QHash<QString, ToolTipResource> resources;
QWeakPointer<QGraphicsWidget> graphicsWidget;
bool autohide : 1;
bool instantPopup : 1;
bool clickable : 1;
bool highlightWindows : 1;
bool vertical : 1;
bool mediaUpdate : 1;
QString playState;
};
ToolTipContent::ToolTipContent()
: d(new ToolTipContentPrivate)
{
}
ToolTipContent::ToolTipContent(const ToolTipContent &other)
: d(new ToolTipContentPrivate(*other.d))
{
}
ToolTipContent::~ToolTipContent()
{
delete d;
}
ToolTipContent &ToolTipContent::operator=(const ToolTipContent &other)
{
*d = *other.d;
return *this;
}
ToolTipContent::ToolTipContent(const QString &mainText,
const QString &subText,
const QPixmap &image)
: d(new ToolTipContentPrivate)
{
setMainText(mainText);
setSubText(subText);
setImage(image);
}
ToolTipContent::ToolTipContent(const QString &mainText,
const QString &subText,
const QIcon &icon)
: d(new ToolTipContentPrivate)
{
setMainText(mainText);
setSubText(subText);
setImage(icon);
}
bool ToolTipContent::isEmpty() const
{
return d->mainText.isEmpty() &&
d->subText.isEmpty() &&
d->image.isNull() &&
(d->windowsToPreview.size() == 0) &&
(!d->mediaUpdate || d->playState.isEmpty());
}
void ToolTipContent::setMainText(const QString &text)
{
d->mainText = text.trimmed();
}
QString ToolTipContent::mainText() const
{
QString text = d->mainText;
text.truncate(MAXIMUM_TEXT_LENGTH);
return text;
}
void ToolTipContent::setSubText(const QString &text)
{
d->subText = text.trimmed();
}
QString ToolTipContent::subText() const
{
QString text = d->subText;
text.truncate(MAXIMUM_TEXT_LENGTH);
return text;
}
void ToolTipContent::setImage(const QPixmap &image)
{
d->image = image;
}
void ToolTipContent::setImage(const QIcon &icon)
{
d->image = icon.pixmap(IconSize(KIconLoader::Desktop));
}
QPixmap ToolTipContent::image() const
{
return d->image;
}
void ToolTipContent::setWindowToPreview(WId id)
{
d->windowsToPreview.clear();
d->windowsToPreview.append(id);
}
WId ToolTipContent::windowToPreview() const
{
if (d->windowsToPreview.size() == 1) {
return d->windowsToPreview.first().id;
} else {
return 0;
}
}
void ToolTipContent::setWindowsToPreview(const QList<WId> & ids)
{
QList<Window> details;
foreach (WId id, ids) {
Window w;
w.id = id;
details.append(w);
}
d->windowsToPreview = details;
}
QList<WId> ToolTipContent::windowsToPreview() const
{
QList<WId> windows;
foreach (Window w, d->windowsToPreview) {
windows.append(w.id);
}
return windows;
}
void ToolTipContent::setPlayState(const QString &ps)
{
d->playState = ps;
}
QString ToolTipContent::playState() const
{
return d->playState;
}
void ToolTipContent::setMediaUpdate(bool m)
{
d->mediaUpdate = m;
}
bool ToolTipContent::mediaUpdate() const
{
return d->mediaUpdate;
}
void ToolTipContent::setWindowDetailsToPreview(const QList<Window> & w)
{
d->windowsToPreview = w;
}
QList<ToolTipContent::Window> ToolTipContent::windowDetailsToPreview() const
{
return d->windowsToPreview;
}
int ToolTipContent::iconSize()
{
return 16;
}
void ToolTipContent::setHighlightWindows(bool highlight)
{
d->highlightWindows = highlight;
}
bool ToolTipContent::highlightWindows() const
{
return d->highlightWindows;
}
void ToolTipContent::setVertical(bool v)
{
d->vertical = v;
}
bool ToolTipContent::vertical() const
{
return d->vertical;
}
void ToolTipContent::setAutohide(bool autohide)
{
d->autohide = autohide;
}
bool ToolTipContent::autohide() const
{
return d->autohide;
}
void ToolTipContent::setInstantPopup(bool enabled)
{
d->instantPopup = enabled;
}
bool ToolTipContent::isInstantPopup() const
{
return d->instantPopup;
}
void ToolTipContent::addResource(ResourceType type, const QUrl &path, const QVariant &resource)
{
d->resources.insert(path.toString(), ToolTipResource(type, resource));
}
void ToolTipContent::registerResources(QTextDocument *document) const
{
if (!document) {
return;
}
QHashIterator<QString, ToolTipResource> it(d->resources);
while (it.hasNext()) {
it.next();
const ToolTipResource &r = it.value();
QTextDocument::ResourceType t;
switch (r.type) {
case ImageResource:
t = QTextDocument::ImageResource;
break;
case HtmlResource:
t = QTextDocument::HtmlResource;
break;
case CssResource:
t = QTextDocument::StyleSheetResource;
break;
}
document->addResource(t, it.key(), r.data);
}
}
void ToolTipContent::setClickable(bool clickable)
{
d->clickable = clickable;
}
bool ToolTipContent::isClickable() const
{
return d->clickable;
}
void ToolTipContent::setGraphicsWidget(QGraphicsWidget *widget)
{
d->graphicsWidget = widget;
}
QGraphicsWidget *ToolTipContent::graphicsWidget() const
{
return d->graphicsWidget.data();
}
} // namespace Plasma

View file

@ -1,258 +0,0 @@
/*
* Copyright 2008 by Aaron Seigo <aseigo@kde.org>
* Copyright 2011 Craig Drummond <craig@kde.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
#ifndef PLASMA_TOOLTIPCONTENT_H
#define PLASMA_TOOLTIPCONTENT_H
#include <QtCore/QString>
#include <QtCore/QUrl>
#include <QtCore/QVariant>
#include <QtCore/QList>
#include <QtGui/QPixmap>
#include <QtGui/QIcon>
//#include <plasma/plasma_export.h>
#ifndef PLASMA_EXPORT
#define PLASMA_EXPORT
#endif
#include <QTextDocument>
#include <QGraphicsWidget>
/**
* This provides the content for a tooltip.
*
* Normally you will want to set at least the @p mainText and
* @p subText.
*/
namespace IconTasks
{
class ToolTipContentPrivate;
class PLASMA_EXPORT ToolTipContent
{
public:
enum ResourceType { ImageResource = 0, HtmlResource, CssResource };
/**
* Creates an empty Content
*/
ToolTipContent();
~ToolTipContent();
/**
* Copy constructor
*/
ToolTipContent(const ToolTipContent &other);
/**
* Constructor that sets the common fields
*/
ToolTipContent(const QString &mainText,
const QString &subText,
const QPixmap &image = QPixmap());
/**
* Constructor that sets the common fields
*/
ToolTipContent(const QString &mainText,
const QString &subText,
const QIcon &icon);
ToolTipContent &operator=(const ToolTipContent &other);
/**
* @return true if all the fields are empty
*/
bool isEmpty() const;
/**
* Sets the main text which containts important information, e.g. the title
*/
void setMainText(const QString &text);
/**
* Important information, e.g. the title
*/
QString mainText() const;
/**
* Sets text which elaborates on the @p mainText
*/
void setSubText(const QString &text) ;
/**
* Elaborates on the @p mainText
*/
QString subText() const;
/**
* Sets the icon to show
*/
void setImage(const QPixmap &image);
/**
* Sets the icon to show
*/
void setImage(const QIcon &icon);
/**
* An icon to display
*/
QPixmap image() const;
/**
* Sets the ID of the window to show a preview for.
* @deprecated
* @see setWindowsToPreview
*/
void setWindowToPreview(WId id);
/**
* Id of a window if you want to show a preview
* @deprecated
* @see windowsToPreview
*/
WId windowToPreview() const;
/**
* Sets the IDS of the windows to show a preview for
* @since 4.3
*/
void setWindowsToPreview(const QList<WId> &ids);
struct Window {
Window(WId i = 0, const QString t = QString(), const QPixmap &p = QPixmap(), bool a = false, int d = 0)
: id(i), text(t), image(p), attention(a), desktop(d) { }
WId id;
QString text;
QPixmap image;
bool attention;
int desktop;
};
void setWindowDetailsToPreview(const QList<Window> &w);
void setPlayState(const QString &ps);
void setMediaUpdate(bool m);
/**
* Ids of a windows if you want to show a preview
* @since 4.3
*/
QList<WId> windowsToPreview() const;
QList<Window> windowDetailsToPreview() const;
QString playState() const;
bool mediaUpdate() const;
static int iconSize();
/**
* sets if when the mouse will be over a thumbnail the corresponding window
* will be highlighted by reducing opacity of all the other windows
* @since 4.4
*/
void setHighlightWindows(bool highlight);
/**
* true if when the mouse will be over a thumbnail the corresponding window
* will be highlighted by reducing opacity of all the other windows
* @since 4.4
*/
bool highlightWindows() const;
void setVertical(bool v);
bool vertical() const;
/** Sets whether or not to autohide the tooltip, defaults to true
*/
void setAutohide(bool autohide);
/**
* Whether or not to autohide the tooltip, defaults to true
*/
bool autohide() const;
/**
* Sets whether or not the tooltip should popup instantly when
* the widget is hovered, defaults to false.
*
* @since 4.7
*/
void setInstantPopup(bool enabled);
/**
* Whether or not the tooltip should popup instantly when
* the widget is hovered, defaults to false.
*
* @since 4.7
*/
bool isInstantPopup() const;
/**
* Adds a resource that can then be referenced from the text elements
* using rich text
*/
void addResource(ResourceType type, const QUrl &path, const QVariant &resource);
/**
* Registers all resources with a given document
*/
void registerResources(QTextDocument *document) const;
/**
* Sets whether or not the tooltip contains clickable content, such as
* window previews. Defaults to false, or not clickable.
*
* @since 4.3
*/
void setClickable(bool clickable);
/**
* @return true if the tooltip is clickabel
*
* @since 4.3
*/
bool isClickable() const;
/**
* Sets an optional graphicsWidget that will be used for positioning the tooltip
* @since 4.6
*/
void setGraphicsWidget(QGraphicsWidget *widget);
/**
* the graphicsWidget used for positioning the tooltip, if any
* @since 4.6
*/
QGraphicsWidget *graphicsWidget() const;
private:
ToolTipContentPrivate * const d;
};
} // namespace Plasma
#endif

View file

@ -1,566 +0,0 @@
/*
* Copyright 2007 by Dan Meltzer <hydrogen@notyetimplemented.com>
* Copyright 2008 by Aaron Seigo <aseigo@kde.org>
* Copyright 2008 by Alexis Ménard <darktears31@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
#include "tooltipmanager.h"
//Qt
#include <QCoreApplication>
#include <QLabel>
#include <QTimer>
#include <QGridLayout>
#include <QGraphicsView>
#include <QtGui/qgraphicssceneevent.h>
//KDE
#include <kwindowsystem.h>
//Plasma
#include "plasma/applet.h"
#include "plasma/containment.h"
#include "plasma/corona.h"
#include "plasma/framesvg.h"
#include "plasma/popupapplet.h"
#include "plasma/theme.h"
#include "plasma/view.h"
#include "plasma/dialogshadows.h"
#include "tooltip_p.h"
using namespace Plasma;
namespace IconTasks
{
#define PREVIEW_SCALE 0.75
class ToolTipManagerPrivate
{
public :
ToolTipManagerPrivate(ToolTipManager *manager)
: q(manager),
shadow(new DialogShadows(q, "widgets/tooltip")),
currentWidget(0),
showTimer(new QTimer(manager)),
hideTimer(new QTimer(manager)),
tipWidget(0),
state(ToolTipManager::Activated),
isShown(false),
delayedHide(false),
clickable(false),
timerPaused(false),
previewWidth(ToolTipManager::DEF_PREVIEW_SIZE),
previewHeight(ToolTipManager::DEF_PREVIEW_SIZE*PREVIEW_SCALE) {
}
~ToolTipManagerPrivate()
{
if (!QCoreApplication::closingDown()) {
shadow->removeWindow(tipWidget);
delete tipWidget;
}
}
void showToolTip();
void resetShownState();
/**
* called when a widget inside the tooltip manager is deleted
*/
void onWidgetDestroyed(QObject * object);
void removeWidget(QGraphicsWidget *w, bool canSafelyAccess = true);
void clearTips();
void doDelayedHide();
void toolTipHovered(bool);
void createTipWidget();
void hideTipWidget();
ToolTipManager *q;
DialogShadows *shadow;
QGraphicsWidget *currentWidget;
QTimer *showTimer;
QTimer *hideTimer;
QHash<QGraphicsWidget *, ToolTipContent> tooltips;
ToolTip *tipWidget;
ToolTipManager::State state;
bool isShown : 1;
bool delayedHide : 1;
bool clickable : 1;
bool timerPaused;
int previewWidth;
int previewHeight;
};
//TOOLTIP IMPLEMENTATION
class ToolTipManagerSingleton
{
public:
ToolTipManagerSingleton()
{
}
ToolTipManager self;
};
K_GLOBAL_STATIC(ToolTipManagerSingleton, privateInstance)
ToolTipManager *ToolTipManager::self()
{
return &privateInstance->self;
}
ToolTipManager::ToolTipManager(QObject *parent)
: QObject(parent),
d(new ToolTipManagerPrivate(this)),
m_corona(0)
{
d->showTimer->setSingleShot(true);
connect(d->showTimer, SIGNAL(timeout()), SLOT(showToolTip()));
d->hideTimer->setSingleShot(true);
connect(d->hideTimer, SIGNAL(timeout()), SLOT(resetShownState()));
}
ToolTipManager::~ToolTipManager()
{
delete d;
}
void ToolTipManager::show(QGraphicsWidget *widget)
{
if (!d->tooltips.contains(widget)) {
return;
}
qreal delay = 0.0;
ToolTipContent content = d->tooltips[widget];
if (!content.isInstantPopup()) {
KConfig config("plasmarc");
KConfigGroup cg(&config, "PlasmaToolTips");
delay = cg.readEntry("Delay", qreal(0.7));
if (delay < 0) {
return;
}
}
d->hideTimer->stop();
d->delayedHide = false;
d->showTimer->stop();
d->currentWidget = widget;
if (d->isShown) {
// small delay to prevent unnecessary showing when the mouse is moving quickly across items
// which can be too much for less powerful CPUs to keep up with
d->showTimer->start(200);
} else {
d->showTimer->start(delay * 1000);
}
}
bool ToolTipManager::isVisible(const QGraphicsWidget *widget) const
{
return d->currentWidget == widget && d->tipWidget && d->tipWidget->isVisible();
}
void ToolTipManagerPrivate::doDelayedHide()
{
showTimer->stop(); // stop the timer to show the tooltip
delayedHide = true;
if (isShown && clickable) {
// leave enough time for user to choose
hideTimer->start(1000);
} else {
hideTimer->start(250);
}
}
void ToolTipManager::hide(QGraphicsWidget *widget)
{
if (d->currentWidget != widget) {
return;
}
d->currentWidget = 0;
d->showTimer->stop(); // stop the timer to show the tooltip
d->delayedHide = false;
d->hideTipWidget();
}
bool ToolTipManager::stopHideTimer(QGraphicsWidget *widget)
{
if (d->currentWidget != widget) {
return false;
}
d->timerPaused = true;
d->hideTimer->stop();
return true;
}
void ToolTipManager::startHideTimer(QGraphicsWidget *widget)
{
if (d->currentWidget != widget) {
return;
}
d->hideTimer->start(250);
d->timerPaused = false;
}
void ToolTipManager::registerWidget(QGraphicsWidget *widget)
{
if (d->state == Deactivated || d->tooltips.contains(widget)) {
return;
}
//the tooltip is not registered we add it in our map of tooltips
d->tooltips.insert(widget, ToolTipContent());
widget->installEventFilter(this);
connect(widget, SIGNAL(destroyed(QObject*)), this, SLOT(onWidgetDestroyed(QObject*)));
}
void ToolTipManager::unregisterWidget(QGraphicsWidget *widget)
{
if (!d->tooltips.contains(widget)) {
return;
}
widget->removeEventFilter(this);
d->removeWidget(widget);
}
void ToolTipManager::setContent(QGraphicsWidget *widget, const ToolTipContent &data)
{
if (d->state == Deactivated || !widget) {
return;
}
if (data.mediaUpdate()) {
if (d->tipWidget) {
d->tipWidget->setContent(widget, data);
}
return;
}
registerWidget(widget);
d->tooltips.insert(widget, data);
if (d->currentWidget == widget && d->tipWidget && d->tipWidget->isVisible()) {
if (data.isEmpty()) {
// after this call, d->tipWidget will be null
hide(widget);
} else {
d->delayedHide = data.autohide();
d->clickable = data.isClickable();
if (d->delayedHide) {
//kDebug() << "starting authoide";
d->hideTimer->start(3000);
} else {
d->hideTimer->stop();
}
}
if (d->tipWidget) {
d->tipWidget->setContent(widget, data);
d->tipWidget->prepareShowing();
//look if the data prefers aother graphicswidget, otherwise use the one used as event catcher
QGraphicsWidget *referenceWidget = data.graphicsWidget() ? data.graphicsWidget() : widget;
Corona *corona = qobject_cast<Corona *>(referenceWidget->scene());
if (!corona) {
// fallback to the corona we were given
corona = m_corona;
}
if (corona) {
d->tipWidget->moveTo(corona->popupPosition(referenceWidget, d->tipWidget->size(), Qt::AlignCenter));
}
}
}
}
void ToolTipManager::clearContent(QGraphicsWidget *widget)
{
setContent(widget, ToolTipContent());
}
void ToolTipManager::setState(ToolTipManager::State state)
{
d->state = state;
switch (state) {
case Activated:
break;
case Deactivated:
d->clearTips();
//fallthrough
case Inhibited:
d->resetShownState();
break;
}
}
ToolTipManager::State ToolTipManager::state() const
{
return d->state;
}
void ToolTipManager::setPreviewSize(int s)
{
if (s >= MIN_PREVIEW_SIZE && s <= MAX_PREVIEW_SIZE) {
d->previewWidth = s;
d->previewHeight = s * PREVIEW_SCALE;
}
}
int ToolTipManager::previewWidth() const
{
return d->previewWidth;
}
int ToolTipManager::previewHeight() const
{
return d->previewHeight;
}
void ToolTipManagerPrivate::createTipWidget()
{
if (tipWidget) {
return;
}
tipWidget = new ToolTip(0);
shadow->addWindow(tipWidget);
QObject::connect(tipWidget, SIGNAL(activateWindowByWId(WId, Qt::MouseButtons, Qt::KeyboardModifiers, QPoint)),
q, SIGNAL(windowPreviewActivated(WId, Qt::MouseButtons, Qt::KeyboardModifiers, QPoint)));
QObject::connect(tipWidget, SIGNAL(closeWindowByWId(WId, Qt::MouseButtons, Qt::KeyboardModifiers, QPoint)),
q, SIGNAL(windowButtonActivated(WId, Qt::MouseButtons, Qt::KeyboardModifiers, QPoint)));
QObject::connect(tipWidget, SIGNAL(linkActivated(QString, Qt::MouseButtons, Qt::KeyboardModifiers, QPoint)),
q, SIGNAL(linkActivated(QString, Qt::MouseButtons, Qt::KeyboardModifiers, QPoint)));
QObject::connect(tipWidget, SIGNAL(hovered(bool)), q, SLOT(toolTipHovered(bool)));
QObject::connect(tipWidget, SIGNAL(mediaButtonPressed(int)), q, SIGNAL(mediaButtonPressed(int)));
}
void ToolTipManagerPrivate::hideTipWidget()
{
if (tipWidget) {
tipWidget->hide();
shadow->removeWindow(tipWidget);
tipWidget->deleteLater();
tipWidget = 0;
}
}
void ToolTipManagerPrivate::onWidgetDestroyed(QObject *object)
{
if (!object) {
return;
}
// we do a static_cast here since it really isn't a QGraphicsWidget by this
// point anymore since we are in the QObject dtor. we don't actually
// try and do anything with it, we just need the value of the pointer
// so this unsafe looking code is actually just fine.
//
// NOTE: DO NOT USE THE w VARIABLE FOR ANYTHING OTHER THAN COMPARING
// THE ADDRESS! ACTUALLY USING THE OBJECT WILL RESULT IN A CRASH!!!
QGraphicsWidget *w = static_cast<QGraphicsWidget*>(object);
removeWidget(w, false);
}
void ToolTipManagerPrivate::removeWidget(QGraphicsWidget *w, bool canSafelyAccess)
{
if (currentWidget == w && currentWidget) {
currentWidget = 0;
showTimer->stop(); // stop the timer to show the tooltip
hideTipWidget();
delayedHide = false;
}
if (w && canSafelyAccess) {
QObject::disconnect(q, 0, w, 0);
}
tooltips.remove(w);
}
void ToolTipManagerPrivate::clearTips()
{
tooltips.clear();
}
void ToolTipManagerPrivate::resetShownState()
{
if (timerPaused) {
return;
}
if (currentWidget) {
if (!tipWidget || !tipWidget->isVisible() || delayedHide) {
//One might have moused out and back in again
delayedHide = false;
isShown = false;
currentWidget = 0;
hideTipWidget();
}
}
}
void ToolTipManagerPrivate::showToolTip()
{
if (state != ToolTipManager::Activated ||
!currentWidget ||
QApplication::activePopupWidget() ||
QApplication::activeModalWidget()) {
return;
}
PopupApplet *popup = qobject_cast<PopupApplet*>(currentWidget);
if (popup && popup->isPopupShowing()) {
return;
}
if (currentWidget->metaObject()->indexOfMethod("toolTipAboutToShow()") != -1) {
// toolTipAboutToShow may call into methods such as setContent which play
// with the current widget; so let's just pretend for a moment that we don't have
// a current widget
QGraphicsWidget *temp = currentWidget;
currentWidget = 0;
QMetaObject::invokeMethod(temp, "toolTipAboutToShow");
currentWidget = temp;
}
QHash<QGraphicsWidget *, ToolTipContent>::const_iterator tooltip = tooltips.constFind(currentWidget);
if (tooltip == tooltips.constEnd() || tooltip.value().isEmpty()) {
if (isShown) {
delayedHide = true;
hideTimer->start(250);
}
return;
}
createTipWidget();
Containment *c = dynamic_cast<Containment *>(currentWidget->topLevelItem());
//kDebug() << "about to show" << (QObject*)c;
if (c) {
tipWidget->setDirection(Plasma::locationToDirection(c->location()));
}
clickable = tooltip.value().isClickable();
tipWidget->setContent(currentWidget, tooltip.value());
tipWidget->prepareShowing();
QGraphicsWidget *referenceWidget = tooltip.value().graphicsWidget() ? tooltip.value().graphicsWidget() : currentWidget;
Corona *corona = qobject_cast<Corona *>(referenceWidget->scene());
if (!corona) {
// fallback to the corona we were given
corona = q->m_corona;
}
if (corona) {
tipWidget->moveTo(corona->popupPosition(referenceWidget, tipWidget->size(), Qt::AlignCenter));
}
tipWidget->show();
isShown = true; //ToolTip is visible
delayedHide = tooltip.value().autohide();
if (delayedHide) {
//kDebug() << "starting authoide";
hideTimer->start(3000);
} else {
hideTimer->stop();
}
}
void ToolTipManagerPrivate::toolTipHovered(bool hovered)
{
if (!clickable) {
return;
}
if (hovered) {
hideTimer->stop();
} else {
hideTimer->start(500);
}
}
bool ToolTipManager::eventFilter(QObject *watched, QEvent *event)
{
QGraphicsWidget * widget = qobject_cast<QGraphicsWidget *>(watched);
if (d->state != Activated || !widget) {
return QObject::eventFilter(watched, event);
}
switch (event->type()) {
case QEvent::GraphicsSceneHoverMove:
// If the tooltip isn't visible, run through showing the tooltip again
// so that it only becomes visible after a stationary hover
if (IconTasks::ToolTipManager::self()->isVisible(widget)) {
break;
}
// Don't restart the show timer on a mouse move event if there hasn't
// been an enter event or the current widget has been cleared by a click
// or wheel event.
{
QGraphicsSceneHoverEvent *me = static_cast<QGraphicsSceneHoverEvent *>(event);
//FIXME: seems that wheel events generate hovermoves as well, with 0 delta
if (!d->currentWidget || (me->pos() == me->lastPos())) {
break;
}
}
case QEvent::GraphicsSceneHoverEnter: {
// Check that there is a tooltip to show
if (!d->tooltips.contains(widget)) {
break;
}
show(widget);
break;
}
case QEvent::GraphicsSceneHoverLeave:
if (d->currentWidget == widget) {
d->doDelayedHide();
}
break;
case QEvent::GraphicsSceneMousePress:
if (d->currentWidget == widget) {
hide(widget);
}
break;
case QEvent::GraphicsSceneWheel:
default:
break;
}
return QObject::eventFilter(watched, event);
}
} // Plasma namespace
#include "moc_tooltipmanager.cpp"

View file

@ -1,249 +0,0 @@
/*
* Copyright 2007 by Dan Meltzer <hydrogen@notyetimplemented.com>
* Copyright 2008 by Aaron Seigo <aseigo@kde.org>
* Copyright 2008 by Alexis Ménard <darktears31@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
#ifndef PLASMA_TOOLTIP_MANAGER_H
#define PLASMA_TOOLTIP_MANAGER_H
#include <kurl.h>
#include <plasma/plasma.h>
#include <plasma/framesvg.h>
#include <plasma/corona.h>
// #include <plasma/plasma_export.h>
#ifndef PLASMA_EXPORT
#define PLASMA_EXPORT
#endif
#include "tooltips/tooltipcontent.h"
using namespace Plasma;
namespace IconTasks
{
class ToolTipManagerPrivate;
/**
* @class ToolTipManager plasma/tooltipmanager.h <Plasma/ToolTipManager>
*
* @short Manages tooltips for QGraphicsWidgets in Plasma
*
* If you want a widget to have a tooltip displayed when the mouse is hovered over
* it, you should do something like:
*
* @code
* // widget is a QGraphicsWidget*
* Plasma::ToolTipContent data;
* data.mainText = i18n("My Title");
* data.subText = i18n("This is a little tooltip");
* data.image = KIcon("some-icon").pixmap(IconSize(KIconLoader::Desktop));
* Plasma::ToolTipManager::self()->setContent(widget, data);
* @endcode
*
* Note that, since a Plasma::Applet is a QGraphicsWidget, you can use
* Plasma::ToolTipManager::self()->setContent(this, data); in the
* applet's init() method to set a tooltip for the whole applet.
*
* The tooltip will be registered automatically by setContent(). It will be
* automatically unregistered when the associated widget is deleted, freeing the
* memory used by the tooltip, but you can manually unregister it at any time by
* calling unregisterWidget().
*
* When a tooltip for a widget is about to be shown, the widget's toolTipAboutToShow() slot will be
* invoked if it exists. Similarly, when a tooltip is hidden, the widget's toolTipHidden() slot
* will be invoked if it exists. This allows widgets to provide on-demand tooltip data.
*/
class PLASMA_EXPORT ToolTipManager : public QObject
{
Q_OBJECT
public:
enum State {
Activated = 0 /**<< Will accept tooltip data and show tooltips */,
Inhibited /**<< Will accept tooltip data, but not show tooltips */,
Deactivated /**<< Will discard tooltip data, and not attempt to show them */
};
/**
* @return The singleton instance of the manager.
*/
static ToolTipManager *self();
/**
* Show the tooltip for a widget registered in the tooltip manager
*
* @param widget the widget for which the tooltip will be displayed
*/
void show(QGraphicsWidget *widget);
/**
* Find out whether the tooltip for a given widget is currently being displayed.
*
* @param widget the widget to check the tooltip for
* @return true if the tooltip of the widget is currently displayed,
* false if not
*/
bool isVisible(const QGraphicsWidget *widget) const;
/**
* Hides the tooltip for a widget immediately.
*
* @param widget the widget to hide the tooltip for
*/
void hide(QGraphicsWidget *widget);
bool stopHideTimer(QGraphicsWidget *widget);
void startHideTimer(QGraphicsWidget *widget);
/**
* Registers a widget with the tooltip manager.
*
* Note that setContent() will register the widget if it
* has not already been registered, and so you do not normally
* need to use the method.
*
* This is useful for creating tooltip content on demand. You can
* register your widget with registerWidget(), then implement
* a slot named toolTipAboutToShow for the widget. This will be
* called before the tooltip is shown, allowing you to set the
* data with setContent().
*
* If the widget also has a toolTipHidden slot, this will be called
* after the tooltip is hidden.
*
* @param widget the desired widget
*/
void registerWidget(QGraphicsWidget *widget);
/**
* Unregisters a widget from the tooltip manager.
*
* This will free the memory used by the tooltip associated with the widget.
*
* @param widget the desired widget to delete
*/
void unregisterWidget(QGraphicsWidget *widget);
/**
* Sets the content for the tooltip associated with a widget.
*
* Note that this will register the widget with the ToolTipManager if
* necessary, so there is usually no need to call registerWidget().
*
* @param widget the widget the tooltip should be associated with
* @param data the content of the tooltip. If an empty Content
* is passed in, the tooltip content will be reset.
*/
void setContent(QGraphicsWidget *widget,
const ToolTipContent &data);
/**
* Clears the tooltip data associated with this widget, but keeps
* the widget registered.
*/
void clearContent(QGraphicsWidget *widget);
/**
* Sets the current state of the manager.
* @see State
* @param state the state to put the manager in
*/
void setState(ToolTipManager::State state);
/**
* @return the current state of the manager; @see State
*/
ToolTipManager::State state() const;
void setCorona(Corona *c) {
m_corona = c;
}
void setPreviewSize(int s);
int previewWidth() const;
int previewHeight() const;
enum PreviewLimits {
MIN_PREVIEW_SIZE = 100,
MAX_PREVIEW_SIZE = 500,
DEF_PREVIEW_SIZE = 200
};
enum MediaButton {
MB_PREV,
MB_PLAY_PAUSE,
MB_NEXT
};
Q_SIGNALS:
/**
* This signal is emitted when a window preview in the tooltip is clicked.
* @param window the id of the window that was clicked
* @param buttons the mouse buttons involved in the activation
* @param modifiers the keyboard modifiers involved in the activation, if any
* @since 4.4
*/
void windowPreviewActivated(WId window, Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers,
const QPoint &screenPos);
void windowButtonActivated(WId window, Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers,
const QPoint &screenPos);
/**
* This signal is emitted when a link in the tooltip is clicked.
* @param anchor the achor text (e.g. url) that was clicked on
* @param buttons the mouse buttons involved in the activation
* @param modifiers the keyboard modifiers involved in the activation, if any
* @since 4.4
*/
void linkActivated(const QString &anchor, Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers,
const QPoint &screenPos);
void mediaButtonPressed(int b);
private:
/**
* Default constructor.
*
* You should normall use self() instead.
*/
explicit ToolTipManager(QObject *parent = 0);
/**
* Default destructor.
*/
~ToolTipManager();
friend class ToolTipManagerSingleton;
friend class Corona; // The corona needs to register itself
friend class ToolTipManagerPrivate;
bool eventFilter(QObject *watched, QEvent *event);
ToolTipManagerPrivate *const d;
Corona* m_corona;
Q_PRIVATE_SLOT(d, void showToolTip())
Q_PRIVATE_SLOT(d, void toolTipHovered(bool))
Q_PRIVATE_SLOT(d, void resetShownState())
Q_PRIVATE_SLOT(d, void onWidgetDestroyed(QObject*))
};
} // namespace Plasma
#endif // PLASMA_TOOL_TIP_MANAGER_H

View file

@ -1,498 +0,0 @@
/*
* Copyright 2007 by Dan Meltzer <hydrogen@notyetimplemented.com>
* Copyright (C) 2008 by Alexis Ménard <darktears31@gmail.com>
* Copyright 2011 Craig Drummond <craig@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2, or
* (at your option) any later version.
*
* 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 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 "windowpreview_p.h"
#include "tooltipcontent.h"
#include "tooltipmanager.h"
#include <QPainter>
#include <QPaintEvent>
#include <QFontMetrics>
#include <QX11Info>
#include <QDesktopWidget>
#include <kwindowsystem.h>
#include <kdebug.h>
#include <kicon.h>
#include <kiconeffect.h>
#include <kiconloader.h>
#include <kglobalsettings.h>
#include <plasma/framesvg.h>
#include <plasma/svg.h>
#include <plasma/windoweffects.h>
#include <plasma/paintutils.h>
namespace IconTasks
{
WindowPreview::WindowPreview(QWidget *parent)
: QWidget(parent),
m_highlightWindows(false)
{
m_background = new Plasma::FrameSvg(this);
m_background->setImagePath("widgets/tasks");
m_background->setElementPrefix("normal");
setMouseTracking(true);
const QString svgPath("widgets/configuration-icons");
if (Plasma::Theme::defaultTheme()->imagePath(svgPath).isEmpty()) {
m_closePixmap = KIcon("window-close").pixmap(ToolTipContent::iconSize(), ToolTipContent::iconSize());
} else {
Plasma::Svg svg(this);
svg.setImagePath(svgPath);
m_closePixmap = svg.pixmap(QLatin1String("close")).scaled(ToolTipContent::iconSize(), ToolTipContent::iconSize(), Qt::KeepAspectRatio, Qt::SmoothTransformation);
}
KIconEffect *effect = KIconLoader::global()->iconEffect();
if (effect->hasEffect(KIconLoader::Desktop, KIconLoader::ActiveState)) {
m_hoverClosePixmap = effect->apply(m_closePixmap, KIconLoader::Desktop, KIconLoader::ActiveState);
}
if (effect->hasEffect(KIconLoader::Desktop, KIconLoader::DisabledState)) {
m_disabledClosePixmap = effect->apply(m_closePixmap, KIconLoader::Desktop, KIconLoader::DisabledState);
}
m_textHeight = QFontMetrics(font()).height() + 6;
m_subTextHeight = QFontMetrics(KGlobalSettings::smallestReadableFont()).height() + 4;
m_hoverThumbnailId = m_hoverBtnId = -1;
m_maxRows = m_rows = 1;
m_maxColumns = m_columns = 4;
}
void WindowPreview::setWindows(const QList<ToolTipContent::Window> &wins)
{
// if (!WindowEffects::isEffectAvailable(WindowEffects::WindowPreview)) {
// setMinimumSize(0,0);
// setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
// m_windowIds.clear();
// m_windows.clear();
// return;
// }
bool havePreviews = WindowEffects::isEffectAvailable(WindowEffects::WindowPreview);
#ifdef Q_WS_X11
static const int constMargin = 48;
QRect screenSize(QApplication::desktop()->screen(x11Info().screen())->geometry().adjusted(constMargin, constMargin, -constMargin, -constMargin));
int titleSpace = qMax(ToolTipContent::iconSize(), m_textHeight);
m_maxColumns = m_columns = qMax(4, screenSize.width() / (ToolTipManager::self()->previewWidth() + WINDOW_MARGIN));
m_maxRows = m_rows = qMax(1, screenSize.height() / ((havePreviews ? ToolTipManager::self()->previewHeight() : 0) + WINDOW_MARGIN + titleSpace));
#endif
int max = m_maxRows * m_maxColumns;
if (wins.count() <= max) {
m_moreWindows = 0;
m_windows = wins;
// Work out actual rows/columns...
bool vertical = m_vertical || !havePreviews;
int orientMax = vertical ? m_maxRows : m_maxColumns;
if (wins.count() > orientMax) {
double optimum = sqrt((double)wins.count());
m_rows = m_columns = optimum > ((int)optimum) ? ((int)optimum + 1) : ((int)optimum);
if (m_rows > m_maxRows) {
m_rows = m_maxRows;
m_columns = (wins.count() / (double)m_rows) + 0.5;
}
if (m_columns > m_maxColumns) {
m_columns = m_maxColumns;
m_rows = (wins.count() / (double)m_columns) + 0.5;
}
} else if (vertical) {
m_rows = wins.count();
m_columns = 1;
} else {
m_columns = wins.count();
m_rows = 1;
}
} else {
m_moreWindows = wins.count() - max;
m_windows = wins.mid(0, max);
}
m_windowIds.clear();
m_showDesktop = false;
foreach (ToolTipContent::Window w, m_windows) {
m_windowIds.append(w.id);
if (0 != w.desktop) {
m_showDesktop = true;
}
}
if (havePreviews) {
m_windowSizes = WindowEffects::windowSizes(m_windowIds);
} else {
m_windowSizes.clear();
}
QSize s(sizeHint());
if (s.isValid()) {
setFixedSize(sizeHint());
}
}
QSize WindowPreview::sizeHint() const
{
if (m_windowIds.size() == 0) {
return QSize();
}
m_rowSizes.clear();
m_columnSizes.clear();
m_itemSizes.clear();
int column = 0;
int row = 0;
bool havePreviews = WindowEffects::isEffectAvailable(WindowEffects::WindowPreview);
if (havePreviews) {
if (m_windowSizes.size() == 0) {
m_windowSizes = WindowEffects::windowSizes(m_windowIds);
}
int maxHeight = 0;
if ((1 == m_columns && m_rows > 1) || (1 == m_rows && m_columns > 1)) {
foreach (const QSize & s, m_windowSizes) {
maxHeight = qMax(s.height(), maxHeight);
}
}
foreach (const QSize & s, m_windowSizes) {
QSize sz(s);
sz.scale(ToolTipManager::self()->previewWidth(), maxHeight ? maxHeight : ToolTipManager::self()->previewHeight(), Qt::KeepAspectRatio);
if (sz.height() > ToolTipManager::self()->previewHeight()) {
sz.scale(ToolTipManager::self()->previewWidth(), ToolTipManager::self()->previewHeight(), Qt::KeepAspectRatio);
}
m_itemSizes.append(sz);
if (m_rowSizes[row] < sz.height()) {
m_rowSizes[row] = sz.height();
}
if (m_columnSizes[column] < sz.width()) {
m_columnSizes[column] = sz.width();
}
if (++column == m_columns) {
column = 0;
row++;
}
}
} else {
for (int i = 0; i < m_windowIds.size(); ++i) {
m_rowSizes[row] = 0;
m_columnSizes[column] = ToolTipManager::DEF_PREVIEW_SIZE;
m_itemSizes.append(QSize(m_columnSizes[column], m_rowSizes[row]));;
if (++column == m_columns) {
column = 0;
row++;
}
}
}
QSize sz(0, 0);
int titleSpace = qMax(ToolTipContent::iconSize(), m_textHeight);
foreach (int v, m_rowSizes.values()) {
sz = sz + QSize(0, v + (WINDOW_MARGIN) + titleSpace + (havePreviews ? (WINDOW_MARGIN / 2.0) : 0.0));
if (m_showDesktop) {
sz = sz + QSize(0, m_subTextHeight);
}
}
foreach (int v, m_columnSizes.values()) {
sz = sz + QSize(v + WINDOW_MARGIN, 0);
}
if (m_moreWindows) {
sz = sz + QSize(0, WINDOW_MARGIN + m_textHeight);
}
return sz;
}
bool WindowPreview::isEmpty() const
{
foreach (WId id, m_windowIds) {
if (id != 0) {
return false;
}
}
return true;
}
void WindowPreview::setHighlightWindows(const bool highlight)
{
m_highlightWindows = highlight;
}
void WindowPreview::setVertical(const bool v)
{
m_vertical = v;
}
bool WindowPreview::highlightWindows() const
{
return m_highlightWindows;
}
void WindowPreview::setInfo()
{
QWidget *w = parentWidget();
if (isEmpty()) {
WindowEffects::showWindowThumbnails(w->winId());
return;
}
bool havePreviews = WindowEffects::isEffectAvailable(WindowEffects::WindowPreview);
if (havePreviews) {
if (m_windowSizes.size() == 0) {
m_windowSizes = WindowEffects::windowSizes(m_windowIds);
}
if (m_windowSizes.size() == 0) {
WindowEffects::showWindowThumbnails(w->winId());
return;
}
}
Q_ASSERT(w->isWindow()); // parent must be toplevel
QSize thumbnailSize = sizeHint();
thumbnailSize.scale(size(), Qt::KeepAspectRatio);
m_background->resizeFrame(thumbnailSize);
qreal left, top, right, bottom;
m_background->getMargins(left, top, right, bottom);
left -= 2; top -= 2; right -= 2; bottom -= 2;
const QRect thumbnailRect(QPoint(left, top), size() - QSize(left + right, top + bottom));
QList<QRect> inParentCoords;
m_rects.clear();
int x = thumbnailRect.x();
int y = thumbnailRect.y();
int column = 0;
int row = 0;
int titleHeight = qMax(ToolTipContent::iconSize(), m_textHeight);
int titleSpace = titleHeight + (WINDOW_MARGIN / 2.0);
bool rtl = QApplication::layoutDirection() == Qt::RightToLeft;
foreach (QSize s, m_itemSizes) {
int width = m_columnSizes[column];
int height = m_rowSizes[row];
Rects rects;
rects.thumb = QRect(QPoint(x + (1 == m_columns && m_rows > 1 ? 0 : (width - s.width()) / 2), y + titleSpace), s);
rects.button = QRect((x + width) - ToolTipContent::iconSize(), y + (titleHeight - ToolTipContent::iconSize()) / 2, ToolTipContent::iconSize(), ToolTipContent::iconSize());
rects.icon = QRect(x, y + (titleHeight - ToolTipContent::iconSize()) / 2, ToolTipContent::iconSize(), ToolTipContent::iconSize());
if (rtl) {
QRect a = rects.button;
rects.button = rects.icon;
rects.icon = a;
}
rects.text = QRect(x + ToolTipContent::iconSize() + 2, y, width - ((ToolTipContent::iconSize() + 2) * 2), titleHeight);
if (m_showDesktop) {
rects.sub = QRect(rtl ? rects.thumb.left() : rects.text.left(),
rects.text.bottom(),
rects.thumb.width() - (ToolTipContent::iconSize() + 2),
m_subTextHeight);
rects.thumb.adjust(0, m_subTextHeight, 0, m_subTextHeight);
}
inParentCoords.append(QRect(mapToParent(rects.thumb.topLeft()), s));
rects.hover = rects.thumb.adjusted(-left, -top, right, bottom).united(rects.icon).united(rects.button);
m_rects.append(rects);
x += width + WINDOW_MARGIN;
if (++column == m_columns) {
column = 0;
row++;
x = thumbnailRect.x();
y += height + (havePreviews ? WINDOW_MARGIN : (WINDOW_MARGIN / 2.0)) + titleSpace + (m_showDesktop ? m_subTextHeight : 0);
}
}
if (havePreviews) {
WindowEffects::showWindowThumbnails(w->winId(), m_windowIds, inParentCoords);
}
m_hoverThumbnailId = m_hoverBtnId = -1;
repaint();
}
void WindowPreview::paintEvent(QPaintEvent *e)
{
Q_UNUSED(e)
QPainter painter(this);
QWidget *w = parentWidget();
qreal left, top, right, bottom;
m_background->getMargins(left, top, right, bottom);
left -= 2; top -= 2; right -= 2; bottom -= 2;
const QSize delta(left + right, top + bottom);
const QPoint topLeft(left, top);
bool havePreviews = WindowEffects::isEffectAvailable(WindowEffects::WindowPreview);
int i = 0;
QFont f(font());
QFontMetrics fm(f);
QFont small = KGlobalSettings::smallestReadableFont();
small.setItalic(true);
QFontMetrics smallFm(small);
painter.setFont(font());
foreach (Rects rects, m_rects) {
if (havePreviews) {
m_background->setElementPrefix(i == m_hoverBtnId || i == m_hoverThumbnailId ? "hover" : "normal");
m_background->resizeFrame(rects.thumb.size() + delta);
m_background->paintFrame(&painter, rects.thumb.topLeft() - topLeft);
}
if (i == m_hoverBtnId || i == m_hoverThumbnailId || !m_disabledClosePixmap.isNull()) {
painter.drawPixmap(rects.button.x(), rects.button.y(), i == m_hoverBtnId
? m_hoverClosePixmap
: i == m_hoverThumbnailId
? m_closePixmap
: m_disabledClosePixmap);
}
QString s(fm.elidedText(m_windows[i].text, Qt::ElideRight, rects.text.width(), QPalette::WindowText));
QString sub;
if (m_showDesktop && 0 != m_windows[i].desktop) {
sub = -1 == m_windows[i].desktop
? i18n("(On All Desktops)")
: i18nc("Which virtual desktop a window is currently on", "(On %1)", KWindowSystem::desktopName(m_windows[i].desktop));
}
painter.drawText(rects.text, s, QTextOption(Qt::AlignVCenter));
if (m_windows[i].attention) {
painter.drawText(rects.text.adjusted(1, 0, 1, 0), s, QTextOption(Qt::AlignVCenter));
}
if (!sub.isEmpty()) {
painter.setFont(small);
painter.drawText(rects.sub.adjusted(1, 0, 1, 0), sub, QTextOption(Qt::AlignVCenter));
painter.setFont(f);
}
painter.drawPixmap(rects.icon.x(), rects.icon.y(), m_windows[i].image);
i++;
}
if (m_moreWindows) {
QRect windowRect = w->rect();
int height = fm.height();
QRect textRect = QRect(windowRect.x() + left, windowRect.bottom() - ((WINDOW_MARGIN * 2.5) + height + bottom), windowRect.width() - ((2 * (WINDOW_MARGIN)) + left + right), height);
QString s(i18n("Plus %1 more...", m_moreWindows));
f.setItalic(true);
painter.setFont(f);
painter.drawText(textRect, s, QTextOption(Qt::AlignVCenter));
}
}
void WindowPreview::mousePressEvent(QMouseEvent *event)
{
m_pos = event->pos();
m_btns = event->buttons();
}
void WindowPreview::mouseReleaseEvent(QMouseEvent *event)
{
if (m_pos.isNull()) {
return;
}
for (int i = 0; i < m_rects.size(); ++i) {
if (m_rects[i].button.contains(event->pos()) && m_rects[i].button.contains(m_pos)) {
emit windowButtonClicked(m_windowIds[i], m_btns, event->modifiers(), event->globalPos());
break;
} else if ((m_rects[i].hover.contains(event->pos()) && m_rects[i].hover.contains(m_pos))) {
emit windowPreviewClicked(m_windowIds[i], m_btns, event->modifiers(), event->globalPos());
break;
}
}
m_pos = QPoint();
}
void WindowPreview::mouseMoveEvent(QMouseEvent *event)
{
controlButtons(event);
if (!m_highlightWindows) {
return;
}
for (int i = 0; i < m_rects.size(); ++i) {
if (m_rects[i].hover.contains(event->pos())) {
WindowEffects::highlightWindows(effectiveWinId(), QList<WId>() << effectiveWinId() << m_windowIds[i]);
return;
}
}
WindowEffects::highlightWindows(effectiveWinId(), QList<WId>());
}
void WindowPreview::leaveEvent(QEvent *event)
{
controlButtons(0L);
Q_UNUSED(event)
if (!m_highlightWindows) {
return;
}
WindowEffects::highlightWindows(effectiveWinId(), QList<WId>());
}
void WindowPreview::controlButtons(QMouseEvent *event)
{
bool needUpdate = !event && (m_hoverThumbnailId >= 0 || m_hoverThumbnailId >= 0);
if (!needUpdate && event) {
int hoverThumbnailId = -1, hoverBtnId = -1;
for (int i = 0; i < m_rects.size(); ++i) {
if (m_rects[i].hover.contains(event->pos())) {
hoverThumbnailId = i;
break;
}
}
if (!m_hoverClosePixmap.isNull()) {
for (int i = 0; i < m_rects.size(); ++i) {
if (m_rects[i].button.contains(event->pos())) {
hoverBtnId = i;
break;
}
}
}
needUpdate = ((m_hoverThumbnailId >= 0 || hoverThumbnailId >= 0) && m_hoverThumbnailId != hoverThumbnailId) ||
((m_hoverBtnId >= 0 || hoverBtnId >= 0) && m_hoverBtnId != hoverBtnId);
m_hoverThumbnailId = hoverThumbnailId;
m_hoverBtnId = hoverBtnId;
}
if (needUpdate) {
if (!event) {
m_hoverThumbnailId = m_hoverBtnId = -1;
}
repaint();
}
}
} // namespace Plasma
#include "moc_windowpreview_p.cpp"

View file

@ -1,116 +0,0 @@
/*
* Copyright 2007 by Dan Meltzer <hydrogen@notyetimplemented.com>
* Copyright (C) 2008 by Alexis Ménard <darktears31@gmail.com>
* Copyright 2011 Craig Drummond <craig@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2, or
* (at your option) any later version.
*
* 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 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.
*/
#ifndef PLASMA_WINDOWPREVIEW_P_H
#define PLASMA_WINDOWPREVIEW_P_H
#include <QWidget> // base class
#include <QSize> // stack allocated
#include <plasma/framesvg.h>
#include "tooltipcontent.h"
using namespace Plasma;
namespace IconTasks
{
/**
* @internal
*
* A widget which reserves area for window preview and sets hints on the toplevel
* tooltip widget that tells KWin to render the preview in this area. This depends
* on KWin's TaskbarThumbnail compositing effect (which is automatically detected).
*/
class WindowPreview : public QWidget
{
Q_OBJECT
public:
// static bool previewsAvailable();
static int setPreviewSize(int size);
WindowPreview(QWidget *parent = 0);
void setWindows(const QList<ToolTipContent::Window> &wins);
void setInfo();
bool isEmpty() const;
virtual QSize sizeHint() const;
void setHighlightWindows(const bool highlight);
void setVertical(const bool v);
bool highlightWindows() const;
Q_SIGNALS:
void windowPreviewClicked(WId wid, Qt::MouseButtons buttons, Qt::KeyboardModifiers keys, const QPoint &screenPos);
void windowButtonClicked(WId wid, Qt::MouseButtons buttons, Qt::KeyboardModifiers keys, const QPoint &screenPos);
protected:
void paintEvent(QPaintEvent *e);
void mousePressEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event);
void leaveEvent(QEvent *event);
void controlButtons(QMouseEvent *event);
private:
struct Rects {
QRect thumb;
QRect icon;
QRect button;
QRect text;
QRect sub;
QRect hover;
};
QList<ToolTipContent::Window> m_windows;
QList<WId> m_windowIds;
mutable QList<QSize> m_windowSizes;
QList <Rects> m_rects;
mutable QList<QSize> m_itemSizes;
mutable QMap<int, int> m_rowSizes;
mutable QMap<int, int> m_columnSizes;
FrameSvg *m_background;
bool m_highlightWindows;
QPixmap m_closePixmap;
QPixmap m_hoverClosePixmap;
QPixmap m_disabledClosePixmap;
QPoint m_pos;
Qt::MouseButtons m_btns;
int m_textHeight;
int m_subTextHeight;
int m_hoverThumbnailId;
int m_hoverBtnId;
int m_rows;
int m_columns;
int m_maxRows;
int m_maxColumns;
bool m_vertical;
bool m_showDesktop;
int m_moreWindows;
static const int WINDOW_MARGIN = 10;
};
} // namespace Plasma
#endif // PLASMA_WINDOWPREVIEW_P_H

View file

@ -1,452 +0,0 @@
/***************************************************************************
* Copyright (C) 2007 by Robert Knight <robertknight@gmail.com> *
* Copyright (C) 2008 by Alexis Ménard <darktears31@gmail.com> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* 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 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 . *
***************************************************************************/
// Own
#include "windowtaskitem.h"
#include "taskgroupitem.h"
#include "taskitemlayout.h"
#include "jobmanager.h"
#include "mediabuttons.h"
// Qt
#include <QtGui/qgraphicssceneevent.h>
#include <QtGui/qstyleoption.h>
#include <QGraphicsView>
// KDE
#include <KDebug>
#include <KIcon>
#include <KIconLoader>
#include "taskmanager/taskactions.h"
#include "taskmanager/task.h"
#include "taskmanager/taskmanager.h"
#include "taskmanager/taskgroup.h"
#include <Plasma/Theme>
#include <Plasma/FrameSvg>
#include "tooltips/tooltipmanager.h"
#include <Plasma/Corona>
#include <Plasma/Containment>
#include <Plasma/BusyWidget>
#include "tasks.h"
#ifdef Q_WS_X11
#include <X11/Xlib.h>
#include <fixx11h.h>
#endif
// Busy widget is placed over taskbar icon - therefore need to ignore mouse press/release events!
class WindowTaskItem::BusyWidget : public Plasma::BusyWidget
{
public:
BusyWidget(QGraphicsWidget *p) : Plasma::BusyWidget(p) { };
virtual ~BusyWidget() { }
void mousePressEvent(QGraphicsSceneMouseEvent *event) {
event->ignore();
}
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) {
event->ignore();
}
};
WindowTaskItem::WindowTaskItem(QGraphicsWidget *parent, Tasks *applet)
: AbstractTaskItem(parent, applet),
m_busyWidget(0)
{
}
WindowTaskItem::~WindowTaskItem()
{
close(false);
}
void WindowTaskItem::activate()
{
// the Task class has a method called activateRaiseOrIconify() which
// should perform the required action here.
//
// however it currently does not minimize the task's window if the item
// is clicked whilst the window is active probably because the active window by
// the time the mouse is released over the window task button is not the
// task's window but instead the desktop window
//
// TODO: the Kicker panel in KDE 3.x has a feature whereby clicking on it
// does not take away the focus from the active window (unless clicking
// in a widget such as a line edit which does accept the focus)
// this needs to be implemented for Plasma's own panels.
//kDebug();
if (m_task && m_task.data()->task()) {
m_task.data()->task()->activateRaiseOrIconify();
// emit windowSelected(this);
}
}
QString WindowTaskItem::appName() const
{
return m_task ? m_task.data()->taskName() : QString();
}
KUrl WindowTaskItem::launcherUrl() const
{
return m_task ? m_task.data()->launcherUrl() : KUrl();
}
QString WindowTaskItem::windowClass() const
{
return m_task && m_task.data()->task() ? m_task.data()->task()->classClass() : QString();
}
void WindowTaskItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
if (event->buttons() & Qt::MiddleButton) {
if (isGrouped() && parentGroup()) {
parentGroup()->collapse();
}
} else {
AbstractTaskItem::mousePressEvent(event);
}
event->accept();
}
void WindowTaskItem::keyPressEvent(QKeyEvent *event)
{
if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) {
activate();
} else {
QGraphicsWidget::keyPressEvent(event);
}
}
//destroy this item
void WindowTaskItem::close()
{
close(true);
}
void WindowTaskItem::close(bool hide)
{
//kDebug();
delete m_busyWidget;
m_busyWidget = 0;
unregisterFromHelpers();
if (hide) {
setVisible(false);
}
}
void WindowTaskItem::publishIconGeometry() const
{
if (!m_task || !m_task.data()->task()) {
return;
}
QRect rect = iconGeometry();
if (QRect(0, 0, 0, 0) != rect) {
m_task.data()->task()->publishIconGeometry(rect);
}
}
void WindowTaskItem::publishIconGeometry(const QRect &rect) const
{
if (m_task && m_task.data()->task() && QRect(0, 0, 0, 0) != rect) {
m_task.data()->task()->publishIconGeometry(rect);
}
}
void WindowTaskItem::updateTask(::TaskManager::TaskChanges changes)
{
if (!m_task) {
return;
}
bool needsUpdate = false;
TaskFlags flags = m_flags;
if (changes & TaskManager::StateChanged) {
if (m_task.data()->isActive()) {
flags |= TaskHasFocus;
if (!(m_flags & TaskHasFocus)) {
emit activated(this);
// We have focus now, so remove any attention state...
if (m_task.data()->demandsAttention()) {
KWindowSystem::demandAttention(m_task.data()->task()->window(), false);
}
}
} else {
flags &= ~TaskHasFocus;
}
if (m_task.data()->isMinimized()) {
flags |= TaskIsMinimized;
} else {
flags &= ~TaskIsMinimized;
}
}
if (changes & TaskManager::AttentionChanged) {
if (m_task.data()->demandsAttention()) {
flags |= TaskWantsAttention;
} else {
flags &= ~TaskWantsAttention;
}
}
if (m_flags != flags) {
needsUpdate = true;
setTaskFlags(flags);
}
// basic title and icon
if (changes & TaskManager::IconChanged) {
needsUpdate = true;
}
if (changes & TaskManager::NameChanged) {
needsUpdate = true;
}
if (IconTasks::ToolTipManager::self()->isVisible(this) &&
(changes & TaskManager::IconChanged ||
changes & TaskManager::NameChanged ||
changes & TaskManager::DesktopChanged)) {
updateToolTip();
}
if (needsUpdate) {
//redraw
//kDebug() << m_task.data()->name();
queueUpdate();
}
}
void WindowTaskItem::updateToolTip()
{
if (!m_task || !m_task.data()->task()) {
return;
}
bool showToolTip = true;
TaskGroupItem *group = parentGroup();
if (group) {
QWidget *groupPopupDialog = parentGroup()->popupDialog();
QWidget *dialog = m_applet->popupDialog();
if (dialog && dialog->isVisible()) {
if (groupPopupDialog && groupPopupDialog == dialog) {
showToolTip = true;
} else {
showToolTip = false;
}
}
}
if (showToolTip) {
IconTasks::ToolTipContent data;
data.setMainText(m_task.data()->name());
data.setWindowDetailsToPreview(QList<IconTasks::ToolTipContent::Window>()
<< IconTasks::ToolTipContent::Window(m_task.data()->task()->window(),
m_task.data()->name(),
icon().pixmap(IconTasks::ToolTipContent::iconSize(), IconTasks::ToolTipContent::iconSize()),
m_task.data()->task()->demandsAttention(),
!m_applet->groupManager().showOnlyCurrentDesktop() || !m_task.data()->isOnCurrentDesktop()
? m_task.data()->desktop() : 0));
data.setClickable(true);
data.setInstantPopup(m_applet->instantToolTip());
data.setHighlightWindows(m_applet->highlightWindows());
data.setVertical(Plasma::Vertical == m_applet->formFactor());
QString key = mediaButtonKey();
if (!key.isEmpty()) {
data.setPlayState(MediaButtons::self()->playbackStatus(key, pid()));
}
if (group && group->collapsed()) {
data.setGraphicsWidget(parentWidget());
}
IconTasks::ToolTipManager::self()->setContent(this, data);
} else {
clearToolTip();
}
}
void WindowTaskItem::setStartupTask(TaskItem *task)
{
//kDebug();
if (!task->startup()) {
kDebug() << "Error";
return;
}
m_abstractItem = task;
if (m_abstractItem) {
connect(m_abstractItem, SIGNAL(destroyed(QObject*)), this, SLOT(clearAbstractItem()));
connect(task, SIGNAL(gotTaskPointer()), this, SLOT(gotTaskPointer()));
if (!m_busyWidget) {
m_busyWidget = new BusyWidget(parentGroup());
m_busyWidget->hide();
}
}
}
void WindowTaskItem::gotTaskPointer()
{
//kDebug();
TaskManager::TaskItem *item = qobject_cast<TaskManager::TaskItem*>(sender());
if (item) {
bool addToLayout = 0 != m_busyWidget;
delete m_busyWidget;
m_busyWidget = 0;
setWindowTask(item);
// If we were a busy widget, then we will not have been added to layout. To ensure we are,
// manually add now...
TaskGroupItem *pg = 0;
if (addToLayout && (pg = parentGroup()) && pg->isRootGroup() && pg->tasksLayout()) {
pg->tasksLayout()->addTaskItem(this);
}
}
}
void WindowTaskItem::setWindowTask(TaskManager::TaskItem* taskItem)
{
if (m_task && m_task.data()->task()) {
disconnect(m_task.data()->task(), 0, this, 0);
}
m_task = taskItem;
m_abstractItem = taskItem;
if (m_abstractItem) {
connect(m_abstractItem, SIGNAL(destroyed(QObject*)), this, SLOT(clearAbstractItem()));
}
if (m_task) {
connect(m_task.data(), SIGNAL(changed(::TaskManager::TaskChanges)),
this, SLOT(updateTask(::TaskManager::TaskChanges)));
}
updateTask(::TaskManager::EverythingChanged);
publishIconGeometry();
registerWithHelpers();
//kDebug() << "Task added, isActive = " << task->isActive();
}
void WindowTaskItem::setTask(TaskManager::TaskItem* taskItem)
{
if (!taskItem->startup() && !taskItem->task()) {
kDebug() << "Error";
return;
}
if (!taskItem->task()) {
setStartupTask(taskItem);
} else {
setWindowTask(taskItem);
}
}
TaskManager::Task *WindowTaskItem::windowTask() const
{
return m_task ? m_task.data()->task() : 0;
}
void WindowTaskItem::contextMenuEvent(QGraphicsSceneContextMenuEvent *e)
{
if (!m_task) {
QGraphicsWidget::contextMenuEvent(e);
return;
}
showContextMenu(QPoint(), true);
}
void WindowTaskItem::showContextMenu(const QPoint &pos, bool showAppMenu)
{
QList <QAction*> actionList;
QAction *a(0);
QAction *configAction = m_applet->action("configure");
if (configAction && configAction->isEnabled()) {
actionList.append(configAction);
}
TaskManager::BasicMenu * menu = new TaskManager::BasicMenu(0, m_task.data(), &m_applet->groupManager(), actionList, showAppMenu ? getAppMenu() : QList <QAction*>());
menu->adjustSize();
if (m_applet->formFactor() != Plasma::Vertical) {
menu->setMinimumWidth(size().width());
}
Q_ASSERT(m_applet->containment());
Q_ASSERT(m_applet->containment()->corona());
stopWindowHoverEffect();
menu->exec(pos.isNull() ? m_applet->containment()->corona()->popupPosition(this, menu->size()) : pos);
menu->deleteLater();
delete a;
}
int WindowTaskItem::pid() const
{
return m_task && m_task.data()->task() ? m_task.data()->task()->pid() : 0;
}
void WindowTaskItem::toCurrentDesktop()
{
if (m_task && m_task.data()->task()) {
m_task.data()->task()->toCurrentDesktop();
}
}
bool WindowTaskItem::isWindowItem() const
{
return true;
}
bool WindowTaskItem::isActive() const
{
return m_task ? m_task.data()->isActive() : false;
}
void WindowTaskItem::setAdditionalMimeData(QMimeData* mimeData)
{
if (m_task) {
m_task.data()->addMimeData(mimeData);
}
}
QGraphicsWidget *WindowTaskItem::busyWidget() const
{
return m_busyWidget;
}
#include "moc_windowtaskitem.cpp"

View file

@ -1,101 +0,0 @@
/***************************************************************************
* Copyright (C) 2007 by Robert Knight <robertknight@gmail.com> *
* Copyright (C) 2008 by Alexis Ménard <darktears31@gmail.com> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* 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 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 . *
***************************************************************************/
#ifndef WINDOWTASKITEM_H
#define WINDOWTASKITEM_H
#include "abstracttaskitem.h"
// Own
#include "taskmanager/taskmanager.h"
#include "taskmanager/taskitem.h"
#include <KUrl>
/**
* A task item for a task which represents a window on the desktop.
*/
class WindowTaskItem : public AbstractTaskItem
{
class BusyWidget;
Q_OBJECT
public:
/** Constructs a new representation for a window task. */
WindowTaskItem(QGraphicsWidget *parent, Tasks *applet);
virtual ~WindowTaskItem();
/** Sets the window/startup represented by this task. */
void setTask(TaskManager::TaskItem* taskItem);
/** Returns the window represented by this task. */
TaskManager::Task *windowTask() const;
/** Tells the window manager the minimized task's geometry. */
void publishIconGeometry() const;
// used by the group; for efficiency this avoids multiple calls to
// AbstractTaskItem::iconScreenGeometry
void publishIconGeometry(const QRect &rect) const;
virtual bool isWindowItem() const;
virtual bool isActive() const;
virtual void setAdditionalMimeData(QMimeData* mimeData);
QGraphicsWidget *busyWidget() const;
QString appName() const;
KUrl launcherUrl() const;
QString windowClass() const;
void showContextMenu(const QPoint &pos, bool showAppMenu);
virtual int pid() const;
virtual void toCurrentDesktop();
signals:
/** Emitted when a window is selected for activation, minimization, iconification */
//void windowSelected(WindowTaskItem *); //what is it for?
public slots:
void activate();
void close();
protected:
void contextMenuEvent(QGraphicsSceneContextMenuEvent *event);
void mousePressEvent(QGraphicsSceneMouseEvent *event);
void keyPressEvent(QKeyEvent *event);
void updateToolTip();
private slots:
void updateTask(::TaskManager::TaskChanges changes);
void gotTaskPointer();
private:
void close(bool hide);
/** Sets the starting task represented by this item. */
void setStartupTask(TaskManager::TaskItem* task);
/** Sets the window represented by this task. */
void setWindowTask(TaskManager::TaskItem* taskItem);
QWeakPointer<TaskManager::TaskItem> m_task;
BusyWidget *m_busyWidget;
};
#endif