mirror of
https://bitbucket.org/smil3y/kde-extraapps.git
synced 2025-02-23 10:22:52 +00:00
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:
parent
e55350d4d5
commit
2f61410d65
43 changed files with 0 additions and 11449 deletions
|
@ -26,5 +26,4 @@ add_subdirectory(systemloadviewer)
|
|||
if(KDE4WORKSPACE_FOUND)
|
||||
add_subdirectory(binary-clock)
|
||||
add_subdirectory(fuzzy-clock)
|
||||
add_subdirectory(icontasks)
|
||||
endif()
|
||||
|
|
|
@ -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
|
||||
)
|
|
@ -1,3 +0,0 @@
|
|||
#! /usr/bin/env bash
|
||||
$EXTRACTRC *.ui >> rc.cpp
|
||||
$XGETTEXT */*.cpp *.cpp -o $podir/plasma_applet_icontasks.pot
|
|
@ -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
|
@ -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
|
|
@ -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><p>Controls whether the frames drawn around taskbar entries should be rotated 90-degrees counter-clockwise when the taskbar is in a vertical panel.</p></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><p>Controls the width of window previews with tooltips.</p></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><p>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.</p></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><p>Controls the scaling of the taskbar icon. When set to &quot;Automatic&quot;, the taskbar will attempt to determine the optimal size.</p></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><p>Set the amount of extra spacing between items.</p></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><p>Controls the maximum number of rows (for a horizontal taskbar), or columns (for a vertical taskbar), that will be used.</p></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><p>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.</p></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>
|
|
@ -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"
|
||||
|
|
@ -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
|
Binary file not shown.
|
@ -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><p>When enabled, a progressbar will be drawn over the applications icons to represent its overall job progress.</p></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><p>When enabled - previous, play/pause, and next buttons will be shown in the tooltips for media players.</p></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><p>Toggles support for listing an application's recent documents in its popup menu.</p></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><p>Configures what should occur when a task group is clicked.</p></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>
|
|
@ -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;
|
||||
}
|
|
@ -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
|
Binary file not shown.
Binary file not shown.
|
@ -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"
|
|
@ -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
|
Binary file not shown.
|
@ -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"
|
|
@ -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
|
|
@ -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
|
|
@ -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>
|
|
@ -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>
|
|
@ -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
|
Binary file not shown.
|
@ -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"
|
|
@ -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
|
@ -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
|
|
@ -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"
|
||||
|
|
@ -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
|
|
@ -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"
|
|
@ -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
|
|
@ -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 ¤t)
|
||||
{
|
||||
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"
|
|
@ -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 ¤t);
|
||||
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
|
||||
|
|
@ -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
|
||||
|
||||
|
|
@ -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
|
||||
|
|
@ -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"
|
||||
|
|
@ -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
|
|
@ -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"
|
|
@ -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
|
||||
|
|
@ -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"
|
||||
|
|
@ -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
|
Loading…
Add table
Reference in a new issue