plasma: new MultiWidget class

Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
Ivailo Monev 2024-04-13 19:17:44 +03:00
parent 649e704698
commit e6a2556a80
21 changed files with 867 additions and 2417 deletions

View file

@ -41,6 +41,7 @@ install(
KPasswdStore
KHTTP
KDNSSD
KDnDEventFilter
KCharMacroExpander
KCharsets
KCmdLineArgs
@ -473,6 +474,7 @@ install(
Plasma/FrameSvg
Plasma/GroupBox
Plasma/IconWidget
Plasma/MultiWidget
Plasma/ItemBackground
Plasma/Label
Plasma/LineEdit

View file

@ -0,0 +1 @@
#include "../../plasma/widgets/multiwidget.h"

View file

@ -166,6 +166,7 @@ set(kdeui_LIB_SRCS
util/kcompletionbase.cpp
util/kcrash.cpp
util/kcursor.cpp
util/kdndeventfilter.cpp
util/kguiitem.cpp
util/kkeyserver.cpp
util/kselectionowner.cpp
@ -430,6 +431,7 @@ install(
util/kcompletion.h
util/kcrash.h
util/kcursor.h
util/kdndeventfilter.h
util/kguiitem.h
util/kkeyserver.h
util/kkeyboardlayout.h

View file

@ -0,0 +1,171 @@
/*
This file is part of the KDE libraries
Copyright (C) 2024 Ivailo Monev <xakepa10@gmail.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License version 2, as published by the Free Software Foundation.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "kdndeventfilter.h"
#include "kglobalsettings.h"
#include "kdebug.h"
#include <QMouseEvent>
#include <QGraphicsSceneMouseEvent>
class KDnDEventFilterPrivate
{
public:
KDnDEventFilterPrivate();
QList<QObject*> objects;
QList<QGraphicsItem*> items;
QPointF dragstartpos;
bool filterEvent(QEvent *event);
};
KDnDEventFilterPrivate::KDnDEventFilterPrivate()
: dragstartpos(0.0, 0.0)
{
}
bool KDnDEventFilterPrivate::filterEvent(QEvent *event)
{
switch (event->type()) {
case QEvent::MouseButtonPress: {
QMouseEvent* mouseevent = static_cast<QMouseEvent*>(event);
dragstartpos = mouseevent->pos();
qDebug() << Q_FUNC_INFO << event << dragstartpos;
return false;
}
case QEvent::GraphicsSceneMousePress: {
QGraphicsSceneMouseEvent* mouseevent = static_cast<QGraphicsSceneMouseEvent*>(event);
dragstartpos = mouseevent->pos();
qDebug() << Q_FUNC_INFO << event << dragstartpos;
return false;
}
case QEvent::MouseMove: {
QMouseEvent* mouseevent = static_cast<QMouseEvent*>(event);
if (mouseevent->buttons() & Qt::LeftButton &&
(mouseevent->pos() - dragstartpos).manhattanLength() > KGlobalSettings::dndEventDelay())
{
return true;
}
return false;
}
case QEvent::GraphicsSceneMouseMove: {
QGraphicsSceneMouseEvent* mouseevent = static_cast<QGraphicsSceneMouseEvent*>(event);
if (mouseevent->buttons() & Qt::LeftButton &&
(mouseevent->pos() - dragstartpos).manhattanLength() > KGlobalSettings::dndEventDelay())
{
return true;
}
return false;
}
default: {
return false;
}
}
Q_UNREACHABLE();
return false;
}
KDnDEventFilter::KDnDEventFilter(QGraphicsItem *parent)
: QGraphicsObject(parent),
d(new KDnDEventFilterPrivate())
{
}
KDnDEventFilter::~KDnDEventFilter()
{
}
void KDnDEventFilter::filterObject(QObject *object)
{
d->objects.append(object);
object->installEventFilter(this);
}
void KDnDEventFilter::unfilterObject(QObject *object)
{
d->objects.removeAll(object);
object->removeEventFilter(this);
}
void KDnDEventFilter::filterItem(QGraphicsItem *item)
{
d->items.append(item);
item->installSceneEventFilter(this);
}
void KDnDEventFilter::unfilterItem(QGraphicsItem *item)
{
d->items.removeAll(item);
item->removeSceneEventFilter(this);
}
bool KDnDEventFilter::eventFilter(QObject *object, QEvent *event)
{
if (d->objects.contains(object)) {
if (d->filterEvent(event)) {
qDebug() << Q_FUNC_INFO << event;
emit dragStarted(object);
return true;
}
}
return false;
}
bool KDnDEventFilter::sceneEventFilter(QGraphicsItem *item, QEvent *event)
{
if (d->items.contains(item)) {
if (d->filterEvent(event)) {
qDebug() << Q_FUNC_INFO << event;
emit dragStarted(item);
return true;
}
}
return false;
}
// similar to Plasma::Applet::view(), the important thing is to get a window (preferably active
// one)
QGraphicsView* KDnDEventFilter::dragSceneView(const QGraphicsScene *scene)
{
if (!scene) {
kWarning() << "No drag-n-drop scene";
return nullptr;
}
foreach (QGraphicsView *view, scene->views()) {
if (view->isActiveWindow()) {
return view;
}
}
kWarning() << "No active window for drag-n-drop";
return nullptr;
}
QRectF KDnDEventFilter::boundingRect() const
{
// dummy
return QRectF(0, 0, 0, 0);
}
void KDnDEventFilter::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
// dummy
}
#include "moc_kdndeventfilter.cpp"

View file

@ -0,0 +1,67 @@
/*
This file is part of the KDE libraries
Copyright (C) 2024 Ivailo Monev <xakepa10@gmail.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License version 2, as published by the Free Software Foundation.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef KDNDEVENTFILTER_H
#define KDNDEVENTFILTER_H
#include <kdecore_export.h>
#include <QGraphicsObject>
#include <QGraphicsItem>
#include <QGraphicsScene>
#include <QGraphicsView>
class KDnDEventFilterPrivate;
/*!
Class to catch Drag-n-Drop events from specified objects
@since 4.24
*/
class KDECORE_EXPORT KDnDEventFilter : public QGraphicsObject
{
Q_OBJECT
public:
KDnDEventFilter(QGraphicsItem *parent = nullptr);
~KDnDEventFilter();
void filterObject(QObject *object);
void unfilterObject(QObject *object);
void filterItem(QGraphicsItem *item);
void unfilterItem(QGraphicsItem *item);
static QGraphicsView* dragSceneView(const QGraphicsScene *scene);
Q_SIGNALS:
void dragStarted(QObject *object);
void dragStarted(QGraphicsItem *item);
protected:
bool eventFilter(QObject *object, QEvent *event);
bool sceneEventFilter(QGraphicsItem *item, QEvent *event);
virtual QRectF boundingRect() const;
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
private:
Q_DISABLE_COPY(KDnDEventFilter);
KDnDEventFilterPrivate * const d;
};
#endif // KDNDEVENTFILTER_H

View file

@ -77,6 +77,7 @@ set(plasma_LIB_SRCS
widgets/frame.cpp
widgets/groupbox.cpp
widgets/iconwidget.cpp
widgets/multiwidget.cpp
widgets/itembackground.cpp
widgets/label.cpp
widgets/lineedit.cpp
@ -184,6 +185,7 @@ install(
widgets/frame.h
widgets/groupbox.h
widgets/iconwidget.h
widgets/multiwidget.h
widgets/itembackground.h
widgets/label.h
widgets/lineedit.h

View file

@ -78,8 +78,7 @@ public:
*
* @since 4.6
*/
static KPluginInfo::List listToolBoxInfo(const QString
&parentApp = QString());
static KPluginInfo::List listToolBoxInfo(const QString &parentApp = QString());
/**
* create a toolbox tool from the given action

View file

@ -342,8 +342,7 @@ void Applet::setFailedToLaunch(bool failed, const QString &reason)
Label *failureWidget = new Plasma::Label(this);
failureWidget->setText(d->visibleFailureText(reason));
QLabel *label = failureWidget->nativeWidget();
label->setWordWrap(true);
failureWidget->setWordWrap(true);
failureLayout->addItem(failureWidget);
Plasma::ToolTipManager::self()->registerWidget(failureIcon);
@ -971,7 +970,7 @@ void Applet::showMessage(const QIcon &icon, const QString &message, const Messag
IconWidget *messageIcon = new IconWidget(mainWidget);
Label *messageText = new Label(mainWidget);
messageText->nativeWidget()->setWordWrap(true);
messageText->setWordWrap(true);
messageLayout->addStretch();
messageLayout->addItem(messageIcon);

View file

@ -829,14 +829,14 @@ void ExtenderPrivate::updateEmptyExtenderLabel()
{
if (q->isEmpty() && !emptyExtenderLabel &&
!emptyExtenderMessage.isEmpty() && !spacerWidget ) {
//add the empty extender label.
// add the empty extender label.
emptyExtenderLabel = new Label(q);
emptyExtenderLabel->setAlignment(Qt::AlignCenter);
emptyExtenderLabel->setText(emptyExtenderMessage);
qreal left, top, right, bottom;
background->getMargins(left, top, right, bottom);
emptyExtenderLabel->nativeWidget()->setMargin(left + right);
emptyExtenderLabel->setContentsMargins(left, top, right, bottom);
emptyExtenderLabel->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
layout->addItem(emptyExtenderLabel);

View file

@ -48,7 +48,7 @@
#include "widgets/iconwidget.h"
#include "widgets/pushbutton.h"
#include "widgets/toolbutton.h"
#include "private/extender_p.h"
#include "private/extenderapplet_p.h"
#include "private/extendergroup_p.h"
@ -181,7 +181,7 @@ ExtenderItem::ExtenderItem(Extender *hostExtender, uint extenderItemId)
if (iconName.isEmpty()) {
iconName = "utilities-desktop-extra";
}
d->collapseIcon->setIcon(iconName);
d->collapseIcon->setIcon(KIcon(iconName));
//Find the group if it's already there.
QString groupName = dg.readEntry("group", "");
@ -332,7 +332,7 @@ void ExtenderItem::setIcon(const QIcon &icon)
void ExtenderItem::setIcon(const QString &icon)
{
if (icon != d->iconName) {
d->collapseIcon->setIcon(icon);
d->collapseIcon->setIcon(KIcon(icon));
d->iconName = icon;
config().writeEntry("extenderIconName", icon);
}
@ -833,7 +833,7 @@ void ExtenderItemPrivate::updateToolBox()
int returnToSourceIndex = -1;
const int startingIndex = 2; // collapse item is index 0, title label is 1
int lastIndex = 2;
const QSizeF widgetSize = collapseIcon->sizeFromIconSize(toolbox->iconSize());
const QSizeF widgetSize = QSizeF(toolbox->iconSize(), toolbox->iconSize());
QSet<QAction*> shownActions = actionsInOrder.toSet();
@ -844,8 +844,8 @@ void ExtenderItemPrivate::updateToolBox()
if (!widget) {
continue;
} else if (qobject_cast<IconWidget*>(widget)) {
widgetAction = static_cast<IconWidget*>(widget)->action();
} else if (qobject_cast<ToolButton*>(widget)) {
widgetAction = static_cast<ToolButton*>(widget)->action();
} else if (qobject_cast<PushButton*>(widget)) {
widgetAction = static_cast<PushButton*>(widget)->action();
} else {
@ -879,44 +879,27 @@ void ExtenderItemPrivate::updateToolBox()
collapseIcon->setMinimumSize(widgetSize);
collapseIcon->setMaximumSize(widgetSize);
//add the actions that are actually set to visible.
// add the actions that are actually set to visible.
foreach (QAction *action, actionsInOrder) {
if (action->isVisible() && action != closeAction) {
IconWidget *icon = qobject_cast<IconWidget*>(actionWidgets.value(action));
PushButton *button = qobject_cast<PushButton*>(actionWidgets.value(action));
ToolButton *tool = qobject_cast<ToolButton*>(actionWidgets.value(action));
if (action->icon().isNull() && !action->text().isNull()) {
if (!button) {
button = new PushButton(q);
button->setAction(action);
}
button->setMinimumHeight(widgetSize.height());
button->setMaximumHeight(widgetSize.height());
button->setCursor(Qt::ArrowCursor);
toolboxLayout->insertItem(startingIndex, button);
++lastIndex;
} else {
if (!icon) {
icon = new IconWidget(q);
icon->setAction(action);
}
if (action->icon().isNull()) {
icon->setText(action->text());
}
icon->setMinimumSize(widgetSize);
icon->setMaximumSize(widgetSize);
icon->setCursor(Qt::ArrowCursor);
toolboxLayout->insertItem(startingIndex, icon);
++lastIndex;
if (!tool) {
tool = new ToolButton(q);
tool->setAction(action);
}
tool->setMinimumHeight(widgetSize.height());
tool->setMaximumHeight(widgetSize.height());
tool->setCursor(Qt::ArrowCursor);
toolboxLayout->insertItem(startingIndex, tool);
++lastIndex;
}
}
//add the returntosource icon if we are detached, and have a source applet.
// add the returntosource icon if we are detached, and have a source applet.
if (returnToSourceVisibility && returnToSourceIndex == -1) {
IconWidget *returnToSourceIcon = new IconWidget(q);
ToolButton *returnToSourceButton = new ToolButton(q);
if (!returnToSourceAction) {
returnToSourceAction = new QAction(q);
returnToSourceAction->setToolTip(i18n("Reattach"));
@ -924,23 +907,23 @@ void ExtenderItemPrivate::updateToolBox()
QObject::connect(returnToSourceAction, SIGNAL(triggered()), q, SLOT(returnToSource()));
}
returnToSourceIcon->setAction(returnToSourceAction);
returnToSourceIcon->setSvg("widgets/configuration-icons", "return-to-source");
returnToSourceIcon->setMinimumSize(widgetSize);
returnToSourceIcon->setMaximumSize(widgetSize);
returnToSourceIcon->setCursor(Qt::ArrowCursor);
returnToSourceButton->setAction(returnToSourceAction);
returnToSourceButton->setImage("widgets/configuration-icons", "return-to-source");
returnToSourceButton->setMinimumSize(widgetSize);
returnToSourceButton->setMaximumSize(widgetSize);
returnToSourceButton->setCursor(Qt::ArrowCursor);
if (closeIndex == -1) {
toolboxLayout->addItem(returnToSourceIcon);
toolboxLayout->addItem(returnToSourceButton);
} else {
toolboxLayout->insertItem(closeIndex - 1, returnToSourceIcon);
toolboxLayout->insertItem(closeIndex - 1, returnToSourceButton);
}
++lastIndex;
}
//add the close icon if desired.
// add the close icon if desired.
if (destroyActionVisibility && closeIndex == -1) {
IconWidget *destroyButton = new IconWidget(q);
ToolButton *destroyButton = new ToolButton(q);
if (!closeAction) {
closeAction = new QAction(q);
actions.insert("close", closeAction);
@ -951,7 +934,7 @@ void ExtenderItemPrivate::updateToolBox()
}
destroyButton->setAction(closeAction);
destroyButton->setSvg("widgets/configuration-icons", "close");
destroyButton->setImage("widgets/configuration-icons", "close");
destroyButton->setMinimumSize(widgetSize);
destroyButton->setMaximumSize(widgetSize);
destroyButton->setCursor(Qt::ArrowCursor);

View file

@ -85,8 +85,8 @@ void PopupApplet::setPopupIcon(const QString &iconName)
const QString name = QString("icons/") + iconName.split("-").first();
if (!Plasma::Theme::defaultTheme()->imagePath(name).isEmpty()) {
d->createIconWidget();
d->icon->setSvg(name, iconName);
if (d->icon->svg().isEmpty()) {
d->icon->setImage(name, iconName);
if (d->icon->image().isEmpty()) {
setPopupIcon(KIcon(iconName));
}
@ -259,7 +259,7 @@ void PopupAppletPrivate::popupConstraintsEvent(Plasma::Constraints constraints)
}
//Applet on desktop
if ((((!parentApplet || parentApplet->isContainment() ) && icon && (!icon->svg().isEmpty() || !icon->icon().isNull()) && ((f != Plasma::Vertical && f != Plasma::Horizontal))) ||
if ((((!parentApplet || parentApplet->isContainment() ) && icon && (!icon->image().isEmpty() || !icon->icon().isNull()) && ((f != Plasma::Vertical && f != Plasma::Horizontal))) ||
(((f == Plasma::Vertical && parentSize.width() >= minimum.width()) ||
(f == Plasma::Horizontal && parentSize.height() >= minimum.height())) &&
(!q->parentWidget() || (q->parentWidget()->size().width() >= minimum.width() && q->parentWidget()->size().height() >= minimum.height()))))) {

View file

@ -79,4 +79,4 @@ private:
};
}
#endif // multiple inclusion guard
#endif // PLASMA_CALENDARWIDGET_H

File diff suppressed because it is too large Load diff

View file

@ -1,33 +1,27 @@
/*
* Copyright (C) 2007 by Siraj Razick <siraj@kde.org>
* Copyright (C) 2007 by Riccardo Iaconelli <riccardo@kde.org>
* Copyright (C) 2007 by Matt Broadstone <mbroadst@gmail.com>
* Copyright 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.
*/
* Copyright 2024 Ivailo Monev <xakepa10@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_ICONWIDGET_H
#define PLASMA_ICONWIDGET_H
#include <QtCore/QObject>
#include <QtCore/qsharedpointer.h>
#include <QtGui/qgraphicsitem.h>
#include <QtGui/QIcon>
#include <QtGui/QGraphicsWidget>
#include <QIcon>
#include <QGraphicsWidget>
#include <plasma/animator.h>
#include <plasma/plasma_export.h>
@ -44,8 +38,7 @@
* contain text. Currently, the IconWidget class is primarily used for desktop items,
* but is designed to be used anywhere an icon is needed in an applet.
*
* @author Siraj Razick <siraj@kde.org>
* @author Matt Broadstone <mbroadst@gmail.com>
* @author Siraj Razick <xakepa10@gmail.com>
*/
namespace Plasma
{
@ -55,41 +48,16 @@ class IconWidgetPrivate;
class PLASMA_EXPORT IconWidget : public QGraphicsWidget
{
Q_OBJECT
Q_PROPERTY(QString text READ text WRITE setText)
Q_PROPERTY(QString infoText READ infoText WRITE setInfoText)
Q_PROPERTY(QIcon icon READ icon WRITE setIcon)
Q_PROPERTY(QColor textBackgroundColor READ textBackgroundColor WRITE setTextBackgroundColor)
Q_PROPERTY(QSizeF iconSize READ iconSize)
Q_PROPERTY(QString svg READ svg WRITE setSvg)
Q_PROPERTY(bool drawBackground READ drawBackground WRITE setDrawBackground)
Q_PROPERTY(QAction *action READ action WRITE setAction)
Q_PROPERTY(Qt::Orientation orientation READ orientation WRITE setOrientation)
Q_PROPERTY(int numDisplayLines READ numDisplayLines WRITE setNumDisplayLines)
Q_PROPERTY(QSizeF preferredIconSize READ preferredIconSize WRITE setPreferredIconSize)
Q_PROPERTY(QSizeF minimumIconSize READ minimumIconSize WRITE setMinimumIconSize)
Q_PROPERTY(QSizeF maximumIconSize READ maximumIconSize WRITE setMaximumIconSize)
Q_PROPERTY(QSizeF iconSize READ iconSize WRITE setIconSize)
Q_PROPERTY(QString image READ image WRITE setImage)
public:
/**
* Creates a new Plasma::IconWidget.
* @param parent the QGraphicsItem this icon is parented to.
*/
explicit IconWidget(QGraphicsItem *parent = 0);
/**
* Convenience constructor to create a Plasma::IconWidget with text.
* @param text the text that will be displayed with this icon.
* @param parent the QGraphicsItem this icon is parented to.
*/
explicit IconWidget(const QString &text, QGraphicsItem *parent = 0);
/**
* Creates a new Plasma::IconWidget with text and an icon.
* @param icon the icon that will be displayed with this icon.
* @param text the text that will be displayed with this icon.
* @param parent The QGraphicsItem this icon is parented to.
*/
IconWidget(const QIcon &icon, const QString &text, QGraphicsItem *parent = 0);
explicit IconWidget(QGraphicsItem *parent = nullptr);
/**
* Destroys this Plasma::IconWidget.
@ -97,39 +65,26 @@ public:
virtual ~IconWidget();
/**
* Returns the text associated with this icon.
*/
QString text() const;
/**
* Sets the text associated with this icon.
* @param text the text to associate with this icon.
*/
void setText(const QString &text);
/**
* Convenience method to set the svg image to use when given the filepath and name of svg.
* @param svgFilePath the svg filepath including name of the svg.
* @param svgIconElement the svg element to use when displaying the svg. Defaults to all of them.
*/
void setSvg(const QString &svgFilePath, const QString &svgIconElement = QString());
/**
* @return the path to the svg file set, if any
* Sets the path to an image to display.
*
* @param path the path to the image; if a relative path, then a themed image will be loaded.
*/
QString svg() const;
void setImage(const QString &path);
/**
* Returns the meta text associated with this icon.
*/
QString infoText() const;
* Sets the path to an svg image to display and the id of the used svg element, if necessary.
*
* @param path the path to the image; if a relative path, then a themed image will be loaded.
* @param elementid the id of a svg element.
*
* @since 4.4
*/
void setImage(const QString &path, const QString &elementid);
/**
* Sets the additional information to be displayed by
* this icon.
* @param text additional meta text associated with this icon.
*/
void setInfoText(const QString &text);
* @return the image path being displayed currently, or an empty string if none.
*/
QString image() const;
/**
* @return the icon associated with this icon.
@ -142,26 +97,6 @@ public:
*/
void setIcon(const QIcon &icon);
/**
* @return the color to use behind the text of the icon
* @since 4.3
*/
QColor textBackgroundColor() const;
/**
* Sets the color to use behind the text of the icon
* @param color the color, or QColor() to reset it to no background color
* @since 4.3
*/
void setTextBackgroundColor(const QColor &color);
/**
* Convenience method to set the icon of this Plasma::IconWidget
* using a QString path to the icon.
* @param icon the path to the icon to associate with this Plasma::IconWidget.
*/
Q_INVOKABLE void setIcon(const QString &icon);
/**
* @return the size of this Plasma::IconWidget's graphical icon.
*/
@ -169,157 +104,22 @@ public:
/**
* Set the size you prefer the icon will be when positioned in a layout.
* @param preferred icon size, pass an invalid size to unset this value
* @param size icon size, pass an invalid size to unset this value
*
* @since 4.5
*/
void setPreferredIconSize(const QSizeF &size);
void setIconSize(const QSizeF &size);
/**
* @return The size you prefer the icon will be when positioned in a layout.
* The default is QSizeF(-1, -1); an invalid size means the icon
* will attempt to be at its default and "optimal" size
*
* @since 4.5
*/
QSizeF preferredIconSize() const;
/**
* Set the size that should be the minimum beyond the icon shouldn't scale when
* the icon will be when positioned in a layout.
* @param preferred icon size, pass an invalid size to unset this value
*
* @since 4.5
*/
void setMinimumIconSize(const QSizeF &size);
/**
* @return The size that should be the minimum beyond the icon shouldn't scale when
* the icon will be when positioned in a layout.
* The default is QSizeF(-1, -1); an invalid size means the icon
* will attempt to be at its default and "optimal" size
*
* @since 4.5
*/
QSizeF minimumIconSize() const;
/**
* Set the size that should be the maximum beyond the icon shouldn't scale when
* the icon will be when positioned in a layout.
* @param preferred icon size, pass an invalid size to unset this value
*
* @since 4.5
*/
void setMaximumIconSize(const QSizeF &size);
/**
* @return The size that should be the maximum beyond the icon shouldn't scale when
* the icon will be when positioned in a layout.
* The default is QSizeF(-1, -1); an invalid size means the icon
* will attempt to be at its default and "optimal" size
*
* @since 4.5
*/
QSizeF maximumIconSize() const;
/**
* Plasma::IconWidget allows the user to specify a number of actions
* (currently four) to be displayed around the widget. This method
* allows for a created QAction to be added to the Plasma::IconWidget.
* @param action the QAction to associate with this icon.
*/
void addIconAction(QAction *action);
/**
* Removes a previously set iconAction. The action will be removed from the widget
* but will not be deleted.
*
* @param the QAction to be removed, if 0 all actions will be removed
*/
void removeIconAction(QAction *action);
/**
* Associate an action with this IconWidget
* this makes the IconWidget follow the state of the action, using its icon, text, etc.
* when the IconWidget is clicked, it will also trigger the action.
* Unlike addIconAction, there can be only one associated action.
*/
void setAction(QAction *action);
/**
* @return the currently associated action, if any.
*/
QAction *action() const;
/**
* let set the orientation of the icon
* Qt::Vertical: text under the icon
* Qt::Horizontal text at a side of the icon depending
* by the direction of the language
* @param orientation the orientation we want
*/
void setOrientation(Qt::Orientation orientation);
/**
* @return the orientation of the icon
*/
Qt::Orientation orientation() const;
/**
* inverts the layout of the icons if the orientation is horizontal,
* normally we get icon on the left with left-to-right languages
* @param invert if we want to invert the layout of icons
*/
void invertLayout(bool invert);
/**
* @return if the layout of the icons should appear inverted or not
*/
bool invertedLayout() const;
/**
* @return optimal size given a size for the icon
* @param iconWidth desired width of the icon
*/
Q_INVOKABLE QSizeF sizeFromIconSize(const qreal iconWidth) const;
/**
* @return the number of lines allowed to display
*/
int numDisplayLines() const;
/**
* @param numLines the number of lines to show in the display.
*/
void setNumDisplayLines(int numLines);
/**
* Sets whether or not to draw a background area for the icon
*
* @param draw true if a background should be drawn or not
*/
void setDrawBackground(bool draw);
/**
* @return true if a background area is to be drawn for the icon
*/
bool drawBackground() const;
/**
* reimplemented from QGraphicsItem
*/
QPainterPath shape() const;
bool isDown() const;
public Q_SLOTS:
/**
* Sets the appearance of the icon to pressed or restores the appearance
* to normal. This does not simulate a mouse button press.
* @param pressed whether to appear as pressed (true) or as normal (false)
* Sets the appearance of the icon to pressed. This does not simulate a mouse button press.
*/
void setPressed(bool pressed = true);
void setPressed();
/**
* Shortcut for setPressed(false)
* The opposite of setPressed()
*/
void setUnpressed();
@ -344,51 +144,28 @@ Q_SIGNALS:
void doubleClicked();
/**
* Indicates when the icon has been activated following the single
* or doubleclick settings
* Indicates when the icon has been activated following the single or double-click settings
*/
void activated();
/**
* Indicates that something about the icon may have changed (image, text, etc)
* only actually works for icons associated with an action
*/
void changed();
protected:
bool isDown();
void mousePressEvent(QGraphicsSceneMouseEvent *event);
void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event);
void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
bool sceneEventFilter(QGraphicsItem *watched, QEvent *event);
void changeEvent(QEvent *event);
public:
/**
* @internal
**/
void drawActionButtonBase(QPainter *painter, const QSize &size, int element);
private:
Q_PRIVATE_SLOT(d, void syncToAction())
Q_PRIVATE_SLOT(d, void clearAction())
Q_PRIVATE_SLOT(d, void svgChanged())
Q_PRIVATE_SLOT(d, void actionDestroyed(QObject *obj))
Q_PRIVATE_SLOT(d, void hoverAnimationFinished())
Q_PRIVATE_SLOT(d, void colorConfigChanged())
Q_PRIVATE_SLOT(d, void iconConfigChanged())
Q_PRIVATE_SLOT(d, void setPalette())
IconWidgetPrivate * const d;
friend class IconWidgetPrivate;
friend class PopupAppletPrivate;
};
} // namespace Plasma
#endif
#endif // PLASMA_ICONWIDGET_H

View file

@ -1,411 +0,0 @@
/*
* Copyright (C) 2007 by Aaron Seigo <aseigo@kde.org>
* Copyright (C) 2007 by Matt Broadstone <mbroadst@gmail.com>
* Copyright (C) 2006-2007 Fredrik Höglund <fredrik@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_ICONWIDGET_P_H
#define PLASMA_ICONWIDGET_P_H
#include <QtCore/QTimer>
#include <QtCore/QEvent>
#include <QtCore/qsharedpointer.h>
#include <QtGui/QApplication>
#include <QtGui/QIcon>
#include <QtGui/qstyleoption.h>
#include <QtGui/QTextLayout>
#include <QtGui/QTextOption>
#include "iconwidget.h"
#include "framesvg.h"
#include "private/actionwidgetinterface_p.h"
#include "theme.h"
#include <QAction>
#include <QPainter>
#include <QTextLayout>
#include <QPropertyAnimation>
namespace Plasma
{
class Animation;
class IconHoverAnimation;
class IconHoverAnimation : public QObject
{
Q_OBJECT
Q_PROPERTY(qreal value READ value WRITE setValue)
public:
IconHoverAnimation(QObject *parent = 0);
qreal value() const;
bool fadeIn() const;
void setFadeIn(bool fadeIn);
QPropertyAnimation *animation() const;
void setAnimation(QPropertyAnimation *animation);
protected slots:
void setValue(qreal value);
private:
qreal m_value;
bool m_fadeIn;
QWeakPointer<QPropertyAnimation> m_animation;
};
class PLASMA_EXPORT IconAction
{
public:
IconAction(IconWidget *icon, QAction *action);
void show();
void hide();
bool isVisible() const;
bool isAnimating() const;
QAction *action() const;
void paint(QPainter *painter) const;
bool event(QEvent::Type type, const QPointF &pos);
void setSelected(bool selected);
bool isSelected() const;
bool isHovered() const;
bool isPressed() const;
void setRect(const QRectF &rect);
QRectF rect() const;
private:
void rebuildPixmap();
IconWidget *m_icon;
QAction *m_action;
QPixmap m_pixmap;
QRectF m_rect;
bool m_hovered;
bool m_pressed;
bool m_selected;
bool m_visible;
QWeakPointer<Animation> m_animation;
};
struct Margin
{
qreal left, right, top, bottom;
};
class IconWidgetPrivate : public ActionWidgetInterface<IconWidget>
{
public:
enum MarginType {
ItemMargin = 0,
TextMargin,
IconMargin,
NMargins
};
enum IconWidgetState {
NoState = 0,
HoverState = 1,
PressedState = 2,
ManualPressedState = 4
};
Q_DECLARE_FLAGS(IconWidgetStates, IconWidgetState)
IconWidgetPrivate(IconWidget *i);
~IconWidgetPrivate();
void changed()
{
emit q->changed();
}
void drawBackground(QPainter *painter, IconWidgetState state);
void drawText(QPainter *painter);
void drawTextItems(QPainter *painter, const QStyleOptionGraphicsItem *option,
const QTextLayout &labelLayout, const QTextLayout &infoLayout) const;
QPixmap decoration(const QStyleOptionGraphicsItem *option, bool useHoverEffect, bool usePressedEffect);
QPointF iconPosition(const QStyleOptionGraphicsItem *option, const QPixmap &pixmap) const;
QSizeF displaySizeHint(const QStyleOptionGraphicsItem *option, const qreal width) const;
QString elidedText(QTextLayout &layout,
const QSizeF &maxSize) const;
QSizeF layoutText(QTextLayout &layout,
const QString &text, const QSizeF &constraints) const;
QSizeF layoutText(QTextLayout &layout, const QString &text,
qreal maxWidth) const;
QRectF labelRectangle(const QStyleOptionGraphicsItem *option,
const QPixmap &icon, const QString &string) const;
void layoutTextItems(const QStyleOptionGraphicsItem *option,
const QPixmap &icon, QTextLayout *labelLayout,
QTextLayout *infoLayout, QRectF *textBoundingRect);
int maxWordWidth(const QString text) const;
inline void setLayoutOptions(QTextLayout &layout,
const QStyleOptionGraphicsItem *options,
const Qt::Orientation orientation) const;
inline Qt::LayoutDirection iconDirection(const QStyleOptionGraphicsItem *option) const;
enum {
Minibutton = 64,
MinibuttonHover = 128,
MinibuttonPressed = 256
};
enum ActionPosition {
TopLeft = 0,
TopRight,
BottomLeft,
BottomRight,
LastIconPosition = BottomRight
};
// Margin functions
inline void setActiveMargins();
void setVerticalMargin(MarginType type, qreal left, qreal right, qreal top, qreal bottom);
void setHorizontalMargin(MarginType type, qreal left, qreal right, qreal top, qreal bottom);
inline void setVerticalMargin(MarginType type, qreal hor, qreal ver);
inline void setHorizontalMargin(MarginType type, qreal hor, qreal ver);
inline QRectF addMargin(const QRectF &rect, MarginType type) const;
inline QRectF subtractMargin(const QRectF &rect, MarginType type) const;
inline QSizeF addMargin(const QSizeF &size, MarginType type) const;
inline QSizeF subtractMargin(const QSizeF &size, MarginType type) const;
inline QRectF actionRect(ActionPosition position) const;
void actionDestroyed(QObject *obj);
void svgChanged();
void readColors();
void colorConfigChanged();
void iconConfigChanged();
void hoverAnimationFinished();
void init();
void layoutIcons(const QStyleOptionGraphicsItem *option);
QSizeF iconSizeForWidgetSize(const QStyleOptionGraphicsItem *option, const QSizeF &widgetSize);
void animateMainIcon(bool, const IconWidgetStates state);
QString text;
QString infoText;
Svg *iconSvg;
FrameSvg *background;
QString iconSvgElement;
QPixmap iconSvgPixmap;
QColor textColor;
QColor textBgColor;
QColor shadowColor;
IconHoverAnimation *hoverAnimation;
QSizeF iconSize;
QSizeF preferredIconSize;
QSizeF minimumIconSize;
QSizeF maximumIconSize;
QIcon icon;
QIcon oldIcon;
IconWidgetStates states;
Qt::Orientation orientation;
int numDisplayLines;
QSizeF currentSize;
QPointF clickStartPos;
QList<QRect> haloRects;
QTimer *iconChangeTimer;
QList<IconAction*> cornerActions;
Margin verticalMargin[NMargins];
Margin horizontalMargin[NMargins];
Margin *activeMargins;
bool iconSvgElementChanged;
bool invertLayout;
bool drawBg;
bool textBgCustomized;
static const int maxDisplayLines = 5;
static const int iconActionSize = 26;
static const int iconActionMargin = 4;
};
Q_DECLARE_OPERATORS_FOR_FLAGS(IconWidgetPrivate::IconWidgetStates)
// Inline methods
void IconWidgetPrivate::setLayoutOptions(QTextLayout &layout,
const QStyleOptionGraphicsItem *option,
const Qt::Orientation orientation) const
{
QTextOption textoption;
textoption.setTextDirection(option->direction);
if (orientation == Qt::Horizontal) {
textoption.setAlignment(Qt::Alignment(Qt::AlignLeft|Qt::AlignVCenter));
} else {
textoption.setAlignment(Qt::AlignCenter);
}
textoption.setWrapMode(QTextOption::WordWrap); // NOTE: assumption as well
layout.setFont(q->font());
layout.setTextOption(textoption);
}
Qt::LayoutDirection IconWidgetPrivate::iconDirection(const QStyleOptionGraphicsItem *option) const
{
Qt::LayoutDirection direction;
if (invertLayout && orientation == Qt::Horizontal) {
if (option->direction == Qt::LeftToRight) {
direction = Qt::RightToLeft;
} else {
direction = Qt::LeftToRight;
}
} else {
direction = option->direction;
}
return direction;
}
void IconWidgetPrivate::setActiveMargins()
{
//sync here itemmargin with contentsrect, not overly pretty but it's where it's more reliable
qreal left, top, right, bottom;
q->getContentsMargins(&left, &top, &right, &bottom);
if (left || top || right || bottom) {
verticalMargin[ItemMargin].left = horizontalMargin[ItemMargin].left = left;
verticalMargin[ItemMargin].top = horizontalMargin[ItemMargin].top = top;
verticalMargin[ItemMargin].right = horizontalMargin[ItemMargin].right = right;
verticalMargin[ItemMargin].bottom = horizontalMargin[ItemMargin].bottom = bottom;
}
activeMargins = (orientation == Qt::Horizontal ? horizontalMargin : verticalMargin);
}
void IconWidgetPrivate::setVerticalMargin(MarginType type, qreal left, qreal top,
qreal right, qreal bottom)
{
verticalMargin[type].left = left;
verticalMargin[type].right = right;
verticalMargin[type].top = top;
verticalMargin[type].bottom = bottom;
}
void IconWidgetPrivate::setHorizontalMargin(MarginType type, qreal left, qreal top,
qreal right, qreal bottom)
{
horizontalMargin[type].left = left;
horizontalMargin[type].right = right;
horizontalMargin[type].top = top;
horizontalMargin[type].bottom = bottom;
}
void IconWidgetPrivate::setVerticalMargin(MarginType type, qreal horizontal, qreal vertical)
{
setVerticalMargin(type, horizontal, vertical, horizontal, vertical);
}
void IconWidgetPrivate::setHorizontalMargin(MarginType type, qreal horizontal, qreal vertical)
{
setHorizontalMargin(type, horizontal, vertical, horizontal, vertical);
}
QRectF IconWidgetPrivate::addMargin(const QRectF &rect, MarginType type) const
{
Q_ASSERT(activeMargins);
const Margin &m = activeMargins[type];
return rect.adjusted(-m.left, -m.top, m.right, m.bottom);
}
QRectF IconWidgetPrivate::subtractMargin(const QRectF &rect, MarginType type) const
{
Q_ASSERT(activeMargins);
const Margin &m = activeMargins[type];
return rect.adjusted(m.left, m.top, -m.right, -m.bottom);
}
QSizeF IconWidgetPrivate::addMargin(const QSizeF &size, MarginType type) const
{
Q_ASSERT(activeMargins);
const Margin &m = activeMargins[type];
return QSizeF(size.width() + m.left + m.right, size.height() + m.top + m.bottom);
}
QSizeF IconWidgetPrivate::subtractMargin(const QSizeF &size, MarginType type) const
{
Q_ASSERT(activeMargins);
const Margin &m = activeMargins[type];
return QSizeF(size.width() - m.left - m.right, size.height() - m.top - m.bottom);
}
int IconWidgetPrivate::maxWordWidth(const QString text) const
{
QFontMetricsF fm = Plasma::Theme::defaultTheme()->fontMetrics();
QStringList words = text.split(' ');
qreal maxWidth = 0;
foreach (const QString &word, words) {
maxWidth = qMax(maxWidth, fm.width(word));
}
return maxWidth;
}
QRectF IconWidgetPrivate::actionRect(ActionPosition position) const
{
switch (position) {
case TopLeft:
return QRectF(iconActionMargin,
iconActionMargin,
iconActionSize,
iconActionSize);
case TopRight:
return QRectF(currentSize.width() - iconActionSize - iconActionMargin,
iconActionMargin,
iconActionSize,
iconActionSize);
case BottomLeft:
return QRectF(iconActionMargin,
currentSize.height() - iconActionSize - iconActionMargin,
iconActionSize,
iconActionSize);
//BottomRight
default:
return QRectF(currentSize.width() - iconActionSize - iconActionMargin,
currentSize.height() - iconActionSize - iconActionMargin,
iconActionSize,
iconActionSize);
}
}
} // Namespace
#endif

View file

@ -19,21 +19,10 @@
#include "label.h"
#include <QApplication>
#include <QDir>
#include <QtGui/qgraphicssceneevent.h>
#include <QLabel>
#include <QMenu>
#include <QPainter>
#include <QtGui/qstyleoption.h>
#include <kcolorscheme.h>
#include <kglobalsettings.h>
#include <kmimetype.h>
#include <QStyleOptionGraphicsItem>
#include "private/themedwidgetinterface_p.h"
#include "svg.h"
#include "theme.h"
namespace Plasma
{
@ -43,70 +32,22 @@ class LabelPrivate : public ThemedWidgetInterface<Label>
public:
LabelPrivate(Label *label)
: ThemedWidgetInterface<Label>(label),
svg(nullptr),
textSelectable(false),
hasLinks(false)
textoption(Qt::AlignCenter)
{
textoption.setWrapMode(QTextOption::NoWrap);
}
~LabelPrivate()
{
delete svg;
}
void setPixmap()
{
if (imagePath.isEmpty()) {
delete svg;
svg = nullptr;
return;
}
KMimeType::Ptr mime = KMimeType::findByPath(absImagePath);
QPixmap pm(q->size().toSize());
if (mime->is("image/svg+xml") || mime->is("image/svg+xml-compressed")) {
if (!svg || svg->imagePath() != absImagePath) {
delete svg;
svg = new Svg();
svg->setImagePath(imagePath);
QObject::connect(svg, SIGNAL(repaintNeeded()), q, SLOT(setPixmap()));
}
QPainter p(&pm);
svg->paint(&p, pm.rect());
} else {
delete svg;
svg = nullptr;
pm = QPixmap(absImagePath);
}
q->nativeWidget()->setPixmap(pm);
}
QString imagePath;
QString absImagePath;
Svg *svg;
bool textSelectable;
bool hasLinks;
QString text;
QTextOption textoption;
};
Label::Label(QGraphicsWidget *parent)
: QGraphicsProxyWidget(parent),
: QGraphicsWidget(parent),
d(new LabelPrivate(this))
{
QLabel *native = new QLabel();
native->setWindowFlags(native->windowFlags()|Qt::BypassGraphicsProxyWidget);
native->setAttribute(Qt::WA_NoSystemBackground);
native->setWordWrap(true);
native->setWindowIcon(QIcon());
connect(native, SIGNAL(linkActivated(QString)), this, SIGNAL(linkActivated(QString)));
connect(native, SIGNAL(linkHovered(QString)), this, SIGNAL(linkHovered(QString)));
d->setWidget(native);
d->initTheming();
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
}
Label::~Label()
@ -116,153 +57,77 @@ Label::~Label()
void Label::setText(const QString &text)
{
d->hasLinks = text.contains("<a ", Qt::CaseInsensitive);
nativeWidget()->setText(text);
d->text = text;
updateGeometry();
update();
}
QString Label::text() const
{
return nativeWidget()->text();
}
void Label::setImage(const QString &path)
{
if (d->imagePath == path) {
return;
}
delete d->svg;
d->svg = nullptr;
d->imagePath = path;
const bool absolutePath = (!path.isEmpty() && path[0] == '/');
if (absolutePath) {
d->absImagePath = path;
} else {
d->absImagePath = Theme::defaultTheme()->imagePath(path);
}
d->setPixmap();
}
QString Label::image() const
{
return d->imagePath;
}
void Label::setScaledContents(bool scaled)
{
nativeWidget()->setScaledContents(scaled);
}
bool Label::hasScaledContents() const
{
return nativeWidget()->hasScaledContents();
}
void Label::setTextSelectable(bool enable)
{
if (enable) {
nativeWidget()->setTextInteractionFlags(Qt::TextBrowserInteraction);
} else {
nativeWidget()->setTextInteractionFlags(Qt::LinksAccessibleByMouse | Qt::LinksAccessibleByKeyboard);
}
d->textSelectable = enable;
}
bool Label::textSelectable() const
{
return d->textSelectable;
return d->text;
}
void Label::setAlignment(Qt::Alignment alignment)
{
nativeWidget()->setAlignment(alignment);
d->textoption.setAlignment(alignment);
update();
}
Qt::Alignment Label::alignment() const
{
return nativeWidget()->alignment();
return d->textoption.alignment();
}
void Label::setWordWrap(bool wrap)
{
nativeWidget()->setWordWrap(wrap);
d->textoption.setWrapMode(wrap ? QTextOption::WordWrap : QTextOption::NoWrap);
update();
}
bool Label::wordWrap() const
{
return nativeWidget()->wordWrap();
return (d->textoption.wrapMode() != QTextOption::NoWrap);
}
QLabel *Label::nativeWidget() const
void Label::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
return static_cast<QLabel*>(widget());
const QFont oldfont = painter->font();
const QSizeF rectsize = option->rect.size();
const QFontMetricsF fontmetricsf(font());
painter->setFont(font());
// TODO: wrap is not really a thing here
painter->drawText(
option->rect,
fontmetricsf.elidedText(d->text, Qt::ElideRight, rectsize.width(), Qt::TextSingleLine),
d->textoption
);
painter->setFont(oldfont);
}
void Label::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
QSizeF Label::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
{
if (d->textSelectable || d->hasLinks){
QContextMenuEvent contextMenuEvent(QContextMenuEvent::Reason(event->reason()),
event->pos().toPoint(), event->screenPos(), event->modifiers());
QApplication::sendEvent(nativeWidget(), &contextMenuEvent);
}else{
event->ignore();
if (which == Qt::PreferredSize) {
const QFontMetricsF fontmetricsf(font());
return fontmetricsf.size(Qt::TextSingleLine, d->text);
}
return QGraphicsWidget::sizeHint(which, constraint);
}
void Label::resizeEvent(QGraphicsSceneResizeEvent *event)
{
d->setPixmap();
QGraphicsProxyWidget::resizeEvent(event);
}
void Label::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
QGraphicsProxyWidget::mousePressEvent(event);
//FIXME: when QTextControl accept()s mouse press events (as of Qt 4.6.2, it processes them
//but never marks them as accepted) the following event->accept() can be removed
if (d->textSelectable || d->hasLinks) {
event->accept();
}
}
void Label::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
if (d->textSelectable) {
QGraphicsProxyWidget::mouseMoveEvent(event);
}
QGraphicsWidget::resizeEvent(event);
}
void Label::changeEvent(QEvent *event)
{
d->changeEvent(event);
QGraphicsProxyWidget::changeEvent(event);
QGraphicsWidget::changeEvent(event);
}
bool Label::event(QEvent *event)
{
d->event(event);
return QGraphicsProxyWidget::event(event);
}
QVariant Label::itemChange(GraphicsItemChange change, const QVariant & value)
{
if (change == QGraphicsItem::ItemCursorHasChanged) {
nativeWidget()->setCursor(cursor());
}
return QGraphicsProxyWidget::itemChange(change, value);
}
QSizeF Label::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
{
if (sizePolicy().verticalPolicy() == QSizePolicy::Fixed) {
return QGraphicsProxyWidget::sizeHint(Qt::PreferredSize, constraint);
} else {
return QGraphicsProxyWidget::sizeHint(which, constraint);
}
return QGraphicsWidget::event(event);
}
} // namespace Plasma

View file

@ -20,12 +20,10 @@
#ifndef PLASMA_LABEL_H
#define PLASMA_LABEL_H
#include <QtGui/QGraphicsProxyWidget>
#include <QtGui/QGraphicsWidget>
#include <plasma/plasma_export.h>
#include <QLabel>
namespace Plasma
{
@ -36,18 +34,12 @@ class LabelPrivate;
*
* @short Provides a plasma-themed QLabel.
*/
class PLASMA_EXPORT Label : public QGraphicsProxyWidget
class PLASMA_EXPORT Label : public QGraphicsWidget
{
Q_OBJECT
Q_PROPERTY(QGraphicsWidget *parentWidget READ parentWidget)
Q_PROPERTY(QString text READ text WRITE setText)
Q_PROPERTY(QString image READ image WRITE setImage)
Q_PROPERTY(Qt::Alignment alignment READ alignment WRITE setAlignment)
Q_PROPERTY(bool hasScaledContents READ hasScaledContents WRITE setScaledContents)
Q_PROPERTY(bool textSelectable READ textSelectable WRITE setTextSelectable)
Q_PROPERTY(bool wordWrap READ wordWrap WRITE setWordWrap)
Q_PROPERTY(QLabel *nativeWidget READ nativeWidget)
public:
/**
@ -55,7 +47,7 @@ public:
*
* @param parent the parent of this widget
*/
explicit Label(QGraphicsWidget *parent = 0);
explicit Label(QGraphicsWidget *parent = nullptr);
~Label();
/**
@ -70,18 +62,6 @@ public:
*/
QString text() const;
/**
* Sets the path to an image to display.
*
* @param path the path to the image; if a relative path, then a themed image will be loaded.
*/
void setImage(const QString &path);
/**
* @return the image path being displayed currently, or an empty string if none.
*/
QString image() const;
/**
* Sets the alignment for the text
*
@ -94,32 +74,6 @@ public:
*/
Qt::Alignment alignment() const;
/**
* Scale or not the contents of the label to the label size
*
* @param scale
*/
void setScaledContents(bool scaled);
/**
* @return true if the contents are scaled to the label size
*/
bool hasScaledContents() const;
/**
* Set if the text on the label can be selected with the mouse
*
* @param enable true if we want to manage text selection with the mouse
* @since 4.4
*/
void setTextSelectable(bool enable);
/**
* @return true if the text is selectable with the mouse
* @since 4.4
*/
bool textSelectable() const;
/**
* Sets if the text of the label can wrap in multiple lines
*
@ -134,28 +88,15 @@ public:
*/
bool wordWrap() const;
/**
* @return the native widget wrapped by this Label
*/
QLabel *nativeWidget() const;
Q_SIGNALS:
void linkActivated(const QString &link);
void linkHovered(const QString &link);
protected:
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint) const;
void resizeEvent(QGraphicsSceneResizeEvent *event);
void mousePressEvent(QGraphicsSceneMouseEvent *event);
void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
void changeEvent(QEvent *event);
bool event(QEvent *event);
QVariant itemChange(GraphicsItemChange change, const QVariant & value);
void contextMenuEvent(QGraphicsSceneContextMenuEvent *event);
QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint) const;
private:
Q_PRIVATE_SLOT(d, void setPalette())
Q_PRIVATE_SLOT(d, void setPixmap())
LabelPrivate * const d;
};

View file

@ -0,0 +1,266 @@
/*
* Copyright 2024 Ivailo Monev <xakepa10@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 "multiwidget.h"
#include "private/themedwidgetinterface_p.h"
#include "widgets/iconwidget.h"
#include "widgets/label.h"
#include "kdndeventfilter.h"
#include "kdebug.h"
#include <QGraphicsLinearLayout>
#include <QGraphicsView>
#include <QTimer>
namespace Plasma
{
class MultiWidgetPrivate : public ThemedWidgetInterface<MultiWidget>
{
public:
MultiWidgetPrivate(MultiWidget *multiwidget);
void setupFonts();
void setupIconSizes();
void setupFilter();
QGraphicsLinearLayout* mainlayout;
Plasma::IconWidget* mainiconwidget;
QGraphicsLinearLayout* labelslayout;
Plasma::Label* label1;
Plasma::Label* label2;
QGraphicsLinearLayout* iconslayout;
Plasma::IconWidget* icon1widget;
Plasma::IconWidget* icon2widget;
KDnDEventFilter* dndfilter;
};
MultiWidgetPrivate::MultiWidgetPrivate(MultiWidget *multiwidget)
: ThemedWidgetInterface<MultiWidget>(multiwidget),
mainlayout(nullptr),
mainiconwidget(nullptr),
labelslayout(nullptr),
label1(nullptr),
label2(nullptr),
iconslayout(nullptr),
icon1widget(nullptr),
icon2widget(nullptr),
dndfilter(nullptr)
{
}
void MultiWidgetPrivate::setupFonts()
{
const QFont font = q->font();
QFont boldfont(font);
boldfont.setBold(true);
label1->setFont(boldfont);
QFont italicfont(font);
italicfont.setItalic(true);
label2->setFont(italicfont);
}
void MultiWidgetPrivate::setupIconSizes()
{
const QSizeF halfsize = (mainiconwidget->iconSize() / 2);
icon1widget->setIconSize(halfsize);
icon2widget->setIconSize(halfsize);
}
void MultiWidgetPrivate::setupFilter()
{
dndfilter->filterItem(q);
dndfilter->filterItem(mainiconwidget);
dndfilter->filterItem(label1);
dndfilter->filterItem(label2);
dndfilter->filterItem(icon1widget);
dndfilter->filterItem(icon2widget);
}
MultiWidget::MultiWidget(QGraphicsWidget *parent)
: QGraphicsWidget(parent),
d(new MultiWidgetPrivate(this))
{
d->initTheming();
d->mainlayout = new QGraphicsLinearLayout(this);
d->mainlayout->setOrientation(Qt::Horizontal);
setLayout(d->mainlayout);
d->mainiconwidget = new Plasma::IconWidget(this);
d->mainiconwidget->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
d->mainlayout->addItem(d->mainiconwidget);
d->labelslayout = new QGraphicsLinearLayout(d->mainlayout);
d->labelslayout->setOrientation(Qt::Vertical);
d->labelslayout->setContentsMargins(8, 8, 8, 8);
d->labelslayout->setSpacing(0);
d->mainlayout->addItem(d->labelslayout);
d->label1 = new Plasma::Label(this);
d->label1->setAcceptedMouseButtons(Qt::LeftButton);
d->label1->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
d->label1->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
d->label1->setWordWrap(false);
d->labelslayout->addItem(d->label1);
d->label2 = new Plasma::Label(this);
d->label2->setAcceptedMouseButtons(Qt::LeftButton);
d->label2->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
d->label2->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
d->label2->setWordWrap(false);
d->labelslayout->addItem(d->label2);
d->label2->setVisible(false);
d->iconslayout = new QGraphicsLinearLayout(d->mainlayout);
d->iconslayout->setOrientation(Qt::Vertical);
// d->iconslayout->setContentsMargins(5, 5, 5, 5);
d->iconslayout->setSpacing(0);
d->mainlayout->addItem(d->iconslayout);
d->icon1widget = new Plasma::IconWidget(this);
d->icon1widget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
d->iconslayout->addItem(d->icon1widget);
d->icon2widget = new Plasma::IconWidget(this);
d->icon2widget->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
d->iconslayout->addItem(d->icon2widget);
d->setupFonts();
d->setupIconSizes();
d->dndfilter = new KDnDEventFilter(this);
connect(
d->mainiconwidget, SIGNAL(clicked()),
this, SIGNAL(clicked())
);
connect(
d->mainiconwidget, SIGNAL(doubleClicked()),
this, SIGNAL(doubleClicked())
);
connect(
d->mainiconwidget, SIGNAL(activated()),
this, SIGNAL(activated())
);
connect(
d->icon1widget, SIGNAL(activated()),
this, SIGNAL(icon1Activated())
);
connect(
d->icon2widget, SIGNAL(activated()),
this, SIGNAL(icon2Activated())
);
connect(
d->dndfilter, SIGNAL(dragStarted(QGraphicsItem*)),
this, SIGNAL(dragStarted(QGraphicsItem*))
);
QTimer::singleShot(500, this, SLOT(setupFilter()));
}
MultiWidget::~MultiWidget()
{
delete d;
}
QIcon MultiWidget::icon() const
{
return d->mainiconwidget->icon();
}
void MultiWidget::setIcon(const QIcon &icon)
{
d->mainiconwidget->setIcon(icon);
}
QSizeF MultiWidget::iconSize() const
{
return d->mainiconwidget->iconSize();
}
void MultiWidget::setIconSize(const QSizeF &size)
{
d->mainiconwidget->setIconSize(size);
d->setupIconSizes();
}
QString MultiWidget::text() const
{
return d->label1->text();
}
void MultiWidget::setText(const QString &text)
{
d->label1->setText(text);
}
QString MultiWidget::subText() const
{
return d->label2->text();
}
void MultiWidget::setSubText(const QString &text)
{
d->label2->setText(text);
if (text.isEmpty()) {
d->label2->setVisible(false);
} else {
d->label2->setVisible(true);
}
}
Qt::Orientation MultiWidget::orientation() const
{
return d->mainlayout->orientation();
}
void MultiWidget::setOrientation(const Qt::Orientation orientation)
{
d->mainlayout->setOrientation(orientation);
}
QIcon MultiWidget::icon1() const
{
return d->icon1widget->icon();
}
void MultiWidget::setIcon1(const QIcon &icon)
{
d->icon1widget->setIcon(icon);
}
QIcon MultiWidget::icon2() const
{
return d->icon2widget->icon();
}
void MultiWidget::setIcon2(const QIcon &icon)
{
d->icon2widget->setIcon(icon);
}
void MultiWidget::changeEvent(QEvent *event)
{
d->changeEvent(event);
if (event->type() == QEvent::FontChange) {
d->setupFonts();
}
QGraphicsWidget::changeEvent(event);
}
} // namespace Plasma
#include "moc_multiwidget.cpp"

View file

@ -0,0 +1,94 @@
/*
* Copyright 2023 Ivailo Monev <xakepa10@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_MULTIWIDGET_H
#define PLASMA_MULTIWIDGET_H
#include <QtGui/QGraphicsWidget>
#include <QtGui/QGraphicsItem>
#include <QtGui/QIcon>
#include <plasma/plasma_export.h>
class KCalendarWidget;
namespace Plasma
{
class MultiWidgetPrivate;
/**
* @class MultiWidget plasma/widgets/multiwidget.h <Plasma/Widgets/MultiWidget>
*
* @short Provides a widget with icon, text and two mini-icons.
* @since 4.24
*/
class PLASMA_EXPORT MultiWidget : public QGraphicsWidget
{
Q_OBJECT
Q_PROPERTY(QIcon icon READ icon WRITE setIcon)
Q_PROPERTY(QSizeF iconSize READ iconSize WRITE setIconSize)
Q_PROPERTY(QString text READ text WRITE setText)
Q_PROPERTY(QString subText READ subText WRITE setSubText)
Q_PROPERTY(Qt::Orientation orientation READ orientation WRITE setOrientation)
public:
explicit MultiWidget(QGraphicsWidget *parent = nullptr);
~MultiWidget();
QIcon icon() const;
void setIcon(const QIcon &icon);
QSizeF iconSize() const;
void setIconSize(const QSizeF &size);
QString text() const;
void setText(const QString &text);
QString subText() const;
void setSubText(const QString &text);
Qt::Orientation orientation() const;
void setOrientation(const Qt::Orientation orientation);
QIcon icon1() const;
void setIcon1(const QIcon &icon);
QIcon icon2() const;
void setIcon2(const QIcon &icon);
Q_SIGNALS:
void clicked();
void doubleClicked();
void activated();
void icon1Activated();
void icon2Activated();
void dragStarted(QGraphicsItem *item);
protected:
void changeEvent(QEvent *event);
private:
Q_PRIVATE_SLOT(d, void setPalette())
Q_PRIVATE_SLOT(d, void setupFilter())
MultiWidgetPrivate *const d;
};
}
#endif // PLASMA_MULTIWIDGET_H

View file

@ -1419,11 +1419,6 @@ bool ScrollWidget::sceneEventFilter(QGraphicsItem *i, QEvent *e)
}
if (i->isWidget()) {
Plasma::Label *label = dynamic_cast<Plasma::Label *>(static_cast<QGraphicsWidget *>(i));
if (label && (label->nativeWidget()->textInteractionFlags() & Qt::TextSelectableByMouse)) {
return false;
}
Plasma::TextEdit *textEdit = dynamic_cast<Plasma::TextEdit *>(static_cast<QGraphicsWidget *>(i));
if (textEdit && (textEdit->nativeWidget()->textInteractionFlags() & Qt::TextSelectableByMouse)) {
return false;

View file

@ -37,22 +37,21 @@ class SeparatorPrivate;
class PLASMA_EXPORT Separator : public QGraphicsWidget
{
Q_OBJECT
Q_PROPERTY(Qt::Orientation orientation READ orientation WRITE setOrientation)
public:
explicit Separator(QGraphicsItem *parent = 0, Qt::WindowFlags wFlags = 0);
virtual ~Separator();
public:
explicit Separator(QGraphicsItem *parent = 0, Qt::WindowFlags wFlags = 0);
virtual ~Separator();
void setOrientation(Qt::Orientation orientation);
Qt::Orientation orientation();
void setOrientation(Qt::Orientation orientation);
Qt::Orientation orientation();
protected:
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
QSizeF sizeHint(Qt::SizeHint which, const QSizeF & constraint) const;
protected:
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
QSizeF sizeHint(Qt::SizeHint which, const QSizeF & constraint) const;
private:
SeparatorPrivate * const d;
private:
SeparatorPrivate * const d;
};
} // Plasma namespace