kde-extraapps/kdeplasma-addons/applets/magnifique/magnifique.cpp
Ivailo Monev 7c098060fd generic: make changes required for building against Katie
Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
2015-11-25 11:50:42 +00:00

220 lines
7 KiB
C++

/***************************************************************************
* Copyright 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 . *
***************************************************************************/
#include "magnifique.h"
#include <QGraphicsView>
#include <QGraphicsProxyWidget>
#include <QGraphicsLinearLayout>
#include <QtGui/qgraphicssceneevent.h>
#include <QApplication>
#include <QSlider>
#include <QVBoxLayout>
#include <KWindowSystem>
#include <KIcon>
#include <Plasma/IconWidget>
#include <Plasma/Theme>
#include <Plasma/Dialog>
#include <Plasma/ToolTipManager>
#include <Plasma/Containment>
#include <Plasma/Corona>
#include <Plasma/View>
Magnifique::Magnifique(QObject *parent, const QVariantList &args)
: Plasma::Applet(parent, args),
m_view(0),
m_mainWindow(0)
{
resize(48, 48);
}
Magnifique::~Magnifique()
{
delete m_mainWindow;
}
void Magnifique::init()
{
QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(this);
layout->setContentsMargins(0, 0, 0, 0);
Plasma::IconWidget *icon = new Plasma::IconWidget(this);
icon->setIcon(QLatin1String("zoom-in"));
layout->addItem(icon);
setAspectRatioMode(Plasma::ConstrainedSquare);
connect(icon, SIGNAL(clicked()), this, SLOT(toggleView()));
Plasma::ToolTipContent data;
data.setMainText(i18n("Magnifying glass"));
data.setSubText(i18n("See the contents of your desktop through the windows"));
data.setImage(KIcon(QLatin1String("zoom-in")));
Plasma::ToolTipManager::self()->setContent(this, data);
}
void Magnifique::toggleView()
{
if (!m_mainWindow) {
m_mainWindow = new QWidget;
QVBoxLayout *layout = new QVBoxLayout(m_mainWindow);
layout->setContentsMargins(0,0,0,0);
m_view = new QGraphicsView(m_mainWindow);
m_view->setScene(scene());
m_view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
m_view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
m_view->setWindowTitle(i18n("Plasma Magnifier"));
m_slider = new QSlider(Qt::Horizontal, m_mainWindow);
m_slider->setMinimum(-2);
m_slider->setMaximum(2);
m_slider->setPageStep(1);
connect(m_slider, SIGNAL(valueChanged(int)), this, SLOT(setZoom(int)));
layout->addWidget(m_view);
layout->addWidget(m_slider);
}
KConfigGroup conf = config();
if (m_mainWindow->isVisible()) {
conf.writeEntry("Geometry", m_mainWindow->geometry());
conf.writeEntry("Zoom", m_view->transform().m11());
m_mainWindow->removeEventFilter(this);
m_mainWindow->deleteLater();
m_mainWindow = 0;
} else {
QRect geom = conf.readEntry("Geometry", QRect(0, 0, 200, 200));
int zoom = conf.readEntry("Zoom", 1);
m_mainWindow->setGeometry(geom);
QTransform viewTransform;
viewTransform.setMatrix(zoom, 0, 0, 0, zoom, 0, 0, 0, 1);
m_view->setTransform(viewTransform);
m_mainWindow->show();
syncViewToScene();
m_mainWindow->installEventFilter(this);
}
}
void Magnifique::setZoom(int zoom)
{
QTransform transform;
if (zoom > 0) {
transform.scale(zoom*2, zoom*2);
} else if (zoom < 0) {
transform.scale(1/(-(qreal)zoom*2), 1/(-(qreal)zoom*2));
}
m_view->setTransform(transform);
syncViewToScene();
}
void Magnifique::syncViewToScene()
{
QRect mappedRect(m_view->transform().inverted().mapRect(QRect(QPoint(0,0), m_view->size())));
QPoint viewPos = m_view->mapToGlobal(m_view->pos());
QRect originalRect(scenePosFromScreenPos(QPoint(qMax(viewPos.x(), 0), qMax(viewPos.y(), 0))).toPoint(), m_view->size());
mappedRect.moveCenter(originalRect.center());
//avoid to show negative coordinates in the view - we don't want to show the panel :)
mappedRect.moveTop(qMax(mappedRect.top(), 0));
mappedRect.moveLeft(qMax(mappedRect.left(), 0));
m_view->setSceneRect(mappedRect);
}
bool Magnifique::eventFilter(QObject *watched, QEvent *event)
{
if (event->type() == QEvent::Move || event->type() == QEvent::Resize) {
syncViewToScene();
return true;
}
return Applet::eventFilter(watched, event);
}
void Magnifique::wheelEvent(QGraphicsSceneWheelEvent *event)
{
if (!m_view) {
return;
}
qreal delta = 1;
//don't allow too big zooming, for speed reason :/
if (event->delta() < 0 && m_view->transform().m11() > 0.25) {
delta = 0.5;
} else if(event->delta() > 0 && m_view->transform().m11() < 4) {
delta = 2;
}
m_view->scale(delta, delta);
qreal factor = m_view->transform().m11();
if (factor > 1) {
m_slider->setValue(factor/2);
} else if (factor < 1 && factor > 0) {
m_slider->setValue(-((1/factor)/2));
} else {
m_slider->setValue(0);
}
syncViewToScene();
}
QPointF Magnifique::scenePosFromScreenPos(const QPoint &pos) const
{
Plasma::Corona *corona = containment()->corona();
Plasma::Containment *cont = 0;
if (corona) {
cont = corona->containmentForScreen(containment()->screen(), KWindowSystem::currentDesktop()-1);
if (!cont) {
cont = corona->containmentForScreen(containment()->screen(), -1);
}
}
if (!corona || !cont) {
return QPoint();
}
//get the stacking order of the toplevel windows and remove the toplevel view that's
//only here while dragging, since we're not interested in finding that.
QList<WId> order = KWindowSystem::stackingOrder();
Plasma::View *found = 0;
foreach (QWidget *w, QApplication::topLevelWidgets()) {
Plasma::View *v = qobject_cast<Plasma::View *>(w);
if (v && v->containment() == cont) {
found = v;
break;
}
}
if (!found) {
return QPointF();
}
return found->mapToScene(found->mapFromGlobal(pos));
}
#include "moc_magnifique.cpp"