File indexing completed on 2024-05-19 15:27:52

0001 /* This file is part of KGraphViewer.
0002    Copyright (C) 2005-2007 Gael de Chalendar <kleag@free.fr>
0003 
0004    KGraphViewer is free software; you can redistribute it and/or
0005    modify it under the terms of the GNU General Public
0006    License as published by the Free Software Foundation, version 2.
0007 
0008    This program is distributed in the hope that it will be useful,
0009    but WITHOUT ANY WARRANTY; without even the implied warranty of
0010    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0011    General Public License for more details.
0012 
0013    You should have received a copy of the GNU General Public License
0014    along with this program; if not, write to the Free Software
0015    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
0016    02110-1301, USA
0017 */
0018 
0019 /* This file was callgraphview.cpp, part of KCachegrind.
0020    Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
0021 
0022    KCachegrind is free software; you can redistribute it and/or
0023    modify it under the terms of the GNU General Public
0024    License as published by the Free Software Foundation, version 2.
0025 */
0026 
0027 /*
0028  * Callgraph View
0029  */
0030 
0031 #include "pannerview.h"
0032 #include "dotgraphview.h"
0033 #include "kgraphviewerlib_debug.h"
0034 
0035 #include <iostream>
0036 #include <math.h>
0037 #include <stdlib.h>
0038 
0039 #include <QDebug>
0040 #include <QGraphicsScene>
0041 #include <QMouseEvent>
0042 #include <QPainter>
0043 
0044 #include <klocalizedstring.h>
0045 
0046 namespace KGraphViewer
0047 {
0048 //
0049 // PannerView
0050 //
0051 PannerView::PannerView(DotGraphView *parent)
0052     : QGraphicsView(parent)
0053     , m_drawContents(true)
0054     , m_parent(parent)
0055 {
0056     m_movingZoomRect = false;
0057 
0058     // why doesn't this avoid flicker ?
0059     // viewport()->setBackgroundMode(Qt::NoBackground);
0060 
0061     // if there are ever graphic glitches to be found, remove this again
0062     setOptimizationFlags(QGraphicsView::DontAdjustForAntialiasing | QGraphicsView::DontClipPainter | QGraphicsView::DontSavePainterState);
0063 
0064     setToolTip(i18n("View of the complete graph. Click and drag to move the visible part."));
0065     setWhatsThis(
0066         i18n("<h1>View of the Complete Graph</h1>"
0067              "<p>Single clicking somewhere without the red square will move the center of the "
0068              "view to where the mouse was clicked.</p><p>Clicking and dragging within the red square "
0069              "will cause the view to follow the movement.</p>"));
0070 }
0071 
0072 void PannerView::setZoomRect(QRectF r)
0073 {
0074     //   qCDebug(KGRAPHVIEWERLIB_LOG) << "PannerView::setZoomRect " << r;
0075     if (r == m_zoomRect) {
0076         return;
0077     }
0078     scene()->invalidate(m_zoomRect, QGraphicsScene::ForegroundLayer);
0079     // get new zoom rect
0080     m_zoomRect = r;
0081     qreal q = mapToScene(15, 0).x();
0082     if (!m_zoomRect.isValid() || m_zoomRect.width() < q || m_zoomRect.height() < q) {
0083         double factor = ((double)m_zoomRect.width()) / m_zoomRect.height();
0084         qreal newWidth, newHeight;
0085         if (factor < 1.0) {
0086             newWidth = q;
0087             newHeight = newWidth / factor;
0088         } else {
0089             newHeight = q;
0090             newWidth = newHeight * factor;
0091         }
0092         qreal newXPos = m_zoomRect.x() + (m_zoomRect.width() - newWidth) / 2;
0093         qreal newYPos = m_zoomRect.y() + (m_zoomRect.height() - newHeight) / 2;
0094         m_zoomRect.setX(newXPos);
0095         m_zoomRect.setY(newYPos);
0096         m_zoomRect.setWidth(newWidth);
0097         m_zoomRect.setHeight(newHeight);
0098     }
0099     scene()->invalidate(m_zoomRect, QGraphicsScene::ForegroundLayer);
0100 }
0101 
0102 void PannerView::moveZoomRectTo(const QPointF &newPos, bool notify)
0103 {
0104     if (!m_zoomRect.isValid()) {
0105         return;
0106     }
0107 
0108     if (m_zoomRect.center() == newPos) {
0109         qCDebug(KGRAPHVIEWERLIB_LOG) << "same pos, don't do anything";
0110         return;
0111     }
0112 
0113     scene()->invalidate(m_zoomRect, QGraphicsScene::ForegroundLayer);
0114     m_zoomRect.moveCenter(newPos);
0115     scene()->invalidate(m_zoomRect, QGraphicsScene::ForegroundLayer);
0116 
0117     if (m_zoomRect.isValid() && notify) {
0118         emit zoomRectMovedTo(newPos);
0119         m_lastPos = newPos;
0120     }
0121 }
0122 
0123 void PannerView::drawForeground(QPainter *p, const QRectF &rect)
0124 {
0125     if (m_zoomRect.isValid() && rect.intersects(m_zoomRect)) {
0126         p->save();
0127         if (m_zoomRect.width() > 10 && m_zoomRect.height() > 10) {
0128             p->setPen(Qt::red);
0129             // subtract pen width, i.e. draw inside
0130             qreal penWidth = p->pen().widthF();
0131             p->drawRect(m_zoomRect.adjusted(-penWidth, -penWidth, -penWidth, -penWidth));
0132         } else {
0133             QBrush brush(Qt::red);
0134             p->fillRect(m_zoomRect, brush);
0135         }
0136         p->restore();
0137     }
0138 }
0139 
0140 void PannerView::mousePressEvent(QMouseEvent *e)
0141 {
0142     if (e->button() != Qt::LeftButton) {
0143         return;
0144     }
0145     /*  qCDebug(KGRAPHVIEWERLIB_LOG) << "PannerView::mousePressEvent "
0146                   << mapToScene(e->pos()) << " / " << m_zoomRect << " / " << m_zoomRect.center() <<endl;*/
0147     moveZoomRectTo(mapToScene(e->pos()));
0148     m_movingZoomRect = true;
0149 }
0150 
0151 void PannerView::mouseMoveEvent(QMouseEvent *e)
0152 {
0153     if (!m_movingZoomRect) {
0154         return;
0155     }
0156 
0157     //   qCDebug(KGRAPHVIEWERLIB_LOG) << "PannerView::mouseMoveEvent " << pos;
0158     moveZoomRectTo(mapToScene(e->pos()));
0159 }
0160 
0161 void PannerView::mouseReleaseEvent(QMouseEvent *e)
0162 {
0163     if (e->button() != Qt::LeftButton) {
0164         return;
0165     }
0166     moveZoomRectTo(mapToScene(e->pos()));
0167     //   qCDebug(KGRAPHVIEWERLIB_LOG) << "PannerView::mouseReleaseEvent " << pos;
0168     m_movingZoomRect = false;
0169     emit zoomRectMoveFinished();
0170 }
0171 
0172 void PannerView::contextMenuEvent(QContextMenuEvent *event)
0173 {
0174     m_parent->contextMenuEvent(event);
0175 }
0176 
0177 }
0178 
0179 #include "moc_pannerview.cpp"