File indexing completed on 2024-05-12 16:35:45

0001 /* This file is part of the KDE project
0002    Copyright 2006 Robert Knight <robertknight@gmail.com>
0003    Copyright 2006 Inge Wallin <inge@lysator.liu.se>
0004    Copyright 2006 Stefan Nikolaus <stefan.nikolaus@kdemail.net>
0005    Copyright 1999-2002,2004 Laurent Montel <montel@kde.org>
0006    Copyright 2002-2005 Ariya Hidayat <ariya@kde.org>
0007    Copyright 1999-2004 David Faure <faure@kde.org>
0008    Copyright 2004-2005 Meni Livne <livne@kde.org>
0009    Copyright 2001-2003 Philipp Mueller <philipp.mueller@gmx.de>
0010    Copyright 2002-2003 Norbert Andres <nandres@web.de>
0011    Copyright 2003 Hamish Rodda <rodda@kde.org>
0012    Copyright 2003 Joseph Wenninger <jowenn@kde.org>
0013    Copyright 2003 Lukas Tinkl <lukas@kde.org>
0014    Copyright 2000-2002 Werner Trobin <trobin@kde.org>
0015    Copyright 2002 Harri Porten <porten@kde.org>
0016    Copyright 2002 John Dailey <dailey@vt.edu>
0017    Copyright 2002 Daniel Naber <daniel.naber@t-online.de>
0018    Copyright 1999-2000 Torben Weis <weis@kde.org>
0019    Copyright 1999-2000 Stephan Kulow <coolo@kde.org>
0020    Copyright 2000 Bernd Wuebben <wuebben@kde.org>
0021    Copyright 2000 Wilco Greven <greven@kde.org>
0022    Copyright 2000 Simon Hausmann <hausmann@kde.org
0023    Copyright 1999 Michael Reiher <michael.reiher@gmx.de>
0024    Copyright 1999 Boris Wedl <boris.wedl@kfunigraz.ac.at>
0025    Copyright 1999 Reginald Stadlbauer <reggie@kde.org>
0026 
0027    This library is free software; you can redistribute it and/or
0028    modify it under the terms of the GNU Library General Public
0029    License as published by the Free Software Foundation; either
0030    version 2 of the License, or (at your option) any later version.
0031 
0032    This library is distributed in the hope that it will be useful,
0033    but WITHOUT ANY WARRANTY; without even the implied warranty of
0034    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0035    Library General Public License for more details.
0036 
0037    You should have received a copy of the GNU Library General Public License
0038    along with this library; see the file COPYING.LIB.  If not, write to
0039    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0040    Boston, MA 02110-1301, USA.
0041 */
0042 
0043 // Local
0044 #include "HeaderItems.h"
0045 
0046 // Qt
0047 #include <QApplication>
0048 #include <QDesktopWidget>
0049 #include <QLabel>
0050 #include <QPainter>
0051 #include <QRubberBand>
0052 #include <QStyle>
0053 #include <QTextLayout>
0054 #include <QToolTip>
0055 #include <QScrollBar>
0056 #include <QStyleOptionGraphicsItem>
0057 #include <QGraphicsSceneWheelEvent>
0058 
0059 // KF5
0060 #include <KLocalizedString>
0061 
0062 // Calligra
0063 #include <KoCanvasController.h>
0064 #include <KoToolProxy.h>
0065 #include <KoZoomHandler.h>
0066 #include <KoPointerEvent.h>
0067 #include <KoUnit.h>
0068 
0069 // Sheets
0070 #include "CanvasItem.h"
0071 #include "Cell.h"
0072 #include "Doc.h"
0073 #include "calligra_sheets_limits.h"
0074 #include "RowColumnFormat.h"
0075 #include "Sheet.h"
0076 
0077 // commands
0078 #include "commands/RowColumnManipulators.h"
0079 
0080 // ui
0081 #include "ui/Selection.h"
0082 
0083 using namespace Calligra::Sheets;
0084 
0085 /****************************************************************
0086  *
0087  * RowHeaderItem
0088  *
0089  ****************************************************************/
0090 
0091 RowHeaderItem::RowHeaderItem(QGraphicsItem *_parent, CanvasItem *_canvas)
0092         : QGraphicsWidget(_parent), RowHeader(_canvas)
0093 {
0094     //setMouseTracking(true);
0095     setAcceptHoverEvents(true);
0096 
0097     //connect(m_pView, SIGNAL(autoScroll(QPoint)),
0098             //this, SLOT(slotAutoScroll(QPoint)));
0099     connect(m_pCanvas->toolProxy(), SIGNAL(toolChanged(QString)),
0100             this, SLOT(toolChanged(QString)));
0101 
0102     setFlag(ItemClipsToShape, true);
0103 }
0104 
0105 
0106 RowHeaderItem::~RowHeaderItem()
0107 {
0108 }
0109 
0110 void RowHeaderItem::mousePressEvent(QGraphicsSceneMouseEvent * _ev)
0111 {
0112     KoPointerEvent pev(_ev, QPointF());
0113     mousePress(&pev);
0114 }
0115 
0116 void RowHeaderItem::mouseReleaseEvent(QGraphicsSceneMouseEvent * _ev)
0117 {
0118     KoPointerEvent pev(_ev, QPointF());
0119     mouseRelease(&pev);
0120 }
0121 
0122 void RowHeaderItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent* _ev)
0123 {
0124     KoPointerEvent pev(_ev, QPointF());
0125     mouseDoubleClick(&pev);
0126 }
0127 
0128 
0129 void RowHeaderItem::mouseMoveEvent(QGraphicsSceneMouseEvent * _ev)
0130 {
0131     KoPointerEvent pev(_ev, QPointF());
0132     mouseMove(&pev);
0133 }
0134 /*
0135 void RowHeaderItem::slotAutoScroll(const QPoint& scrollDistance)
0136 {
0137     // NOTE Stefan: This slot is triggered by the same signal as
0138     //              Canvas::slotAutoScroll and ColumnHeaderItem::slotAutoScroll.
0139     //              Therefore, nothing has to be done except the scrolling was
0140     //              initiated in this header.
0141     if (!m_bMousePressed)
0142         return;
0143     if (scrollDistance.y() == 0)
0144         return;
0145     const QPoint offset = m_pCanvas->viewConverter()->documentToView(m_pCanvas->offset()).toPoint();
0146     if (offset.y() + scrollDistance.y() < 0)
0147         return;
0148     m_pCanvas->setDocumentOffset(offset + QPoint(0, scrollDistance.y()));
0149     // XXX: Port!
0150     //QGraphicsSceneMouseEvent event(QEvent::MouseMove, mapFromGlobal(QCursor::pos()),
0151     //                  Qt::NoButton, Qt::NoButton, QApplication::keyboardModifiers());
0152     //QApplication::sendEvent(this, &event);
0153     m_pCanvas->update();
0154 }
0155 */
0156 void RowHeaderItem::wheelEvent(QGraphicsSceneWheelEvent* _ev)
0157 {
0158     Q_UNUSED(_ev);
0159     // TODO XXX
0160 }
0161 
0162 void RowHeaderItem::paintSizeIndicator(int mouseY)
0163 {
0164     register Sheet * const sheet = m_pCanvas->activeSheet();
0165     if (!sheet)
0166         return;
0167 
0168     m_iResizePos = mouseY;
0169 
0170     // Don't make the row have a height < 2 pixel.
0171     double y = m_pCanvas->zoomHandler()->zoomItY(sheet->rowPosition(m_iResizedRow) - m_pCanvas->yOffset());
0172     if (m_iResizePos < y + 2)
0173         m_iResizePos = (int) y;
0174 
0175     // XXX: Port to QGraphicsView
0176     //if (!m_rubberband) {
0177     //    m_rubberband = new QRubberBand(QRubberBand::Line, m_pCanvas);
0178     //    m_rubberband->setGeometry(0, m_iResizePos, m_pCanvas->width(), 2);
0179     //    m_rubberband->show();
0180     //}
0181     //m_rubberband->move(0, m_iResizePos);
0182 
0183     QString tmpSize;
0184     double hh = m_pCanvas->zoomHandler()->unzoomItY(m_iResizePos - y);
0185     double hu = m_pCanvas->doc()->unit().toUserValue(hh);
0186     if (hu > 0.01)
0187         tmpSize = i18n("Height: %1 %2", hu, m_pCanvas->doc()->unit().symbol());
0188     else
0189         tmpSize = i18n("Hide Row");
0190 
0191     if (!m_lSize) {
0192         int screenNo = 0; //QApplication::desktop()->screenNumber(topLevelWidget());
0193         m_lSize = new QLabel(QApplication::desktop()->screen(screenNo) , Qt::ToolTip);
0194         m_lSize->setAlignment(Qt::AlignVCenter);
0195         m_lSize->setAutoFillBackground(true);
0196         m_lSize->setPalette(QToolTip::palette());
0197         m_lSize->setMargin(1 + style()->pixelMetric(QStyle::PM_ToolTipLabelFrameWidth, 0, m_lSize));
0198         m_lSize->setFrameShape(QFrame::Box);
0199         m_lSize->setIndent(1);
0200     }
0201 
0202     m_lSize->setText(tmpSize);
0203     m_lSize->adjustSize();
0204     QRectF rcf = static_cast<CanvasItem*>(m_pCanvas)->boundingRect();
0205     QPoint pos = (sheet->layoutDirection() == Qt::RightToLeft) ? QPoint(rcf.width() - m_lSize->width() - 3, (int)y + 3) : QPoint(3, (int)y + 3);
0206     pos -= QPoint(0, m_lSize->height());
0207     // XXX: Port
0208     //m_lSize->move(m_pCanvas->mapToGlobal(pos).x(), m_pCanvas->mapToGlobal(pos).y());
0209     m_lSize->show();
0210 }
0211 
0212 void RowHeaderItem::removeSizeIndicator()
0213 {
0214     // XXX TODO
0215 }
0216 
0217 void RowHeaderItem::updateRows(int from, int to)
0218 {
0219     register Sheet * const sheet = m_pCanvas->activeSheet();
0220     if (!sheet)
0221         return;
0222 
0223     double y0 = m_pCanvas->zoomHandler()->zoomItY(sheet->rowPosition(from));
0224     double y1 = m_pCanvas->zoomHandler()->zoomItY(sheet->rowPosition(to + 1));
0225     QGraphicsItem::update(0, (int) y0, boundingRect().width(), (int)(y1 - y0));
0226 }
0227 
0228 void RowHeaderItem::paint(QPainter *painter, const QStyleOptionGraphicsItem * option, QWidget * widget)
0229 {
0230     Q_UNUSED(widget);
0231     RowHeader::paint(painter, option->exposedRect);
0232 }
0233 
0234 
0235 void RowHeaderItem::focusOutEvent(QFocusEvent* _ev)
0236 {
0237     focusOut(_ev);
0238 }
0239 
0240 void RowHeaderItem::toolChanged(const QString& toolId)
0241 {
0242     doToolChanged(toolId);
0243 }
0244 
0245 /****************************************************************
0246  *
0247  * ColumnHeaderItem
0248  *
0249  ****************************************************************/
0250 
0251 ColumnHeaderItem::ColumnHeaderItem(QGraphicsItem *_parent, CanvasItem *_canvas)
0252         : QGraphicsWidget(_parent), ColumnHeader(_canvas)
0253 {
0254     //setMouseTracking(true);
0255     setAcceptHoverEvents(true);
0256 
0257     //connect(_view, SIGNAL(autoScroll(QPoint)),
0258             //this, SLOT(slotAutoScroll(QPoint)));
0259     connect(_canvas->toolProxy(), SIGNAL(toolChanged(QString)),
0260             this, SLOT(toolChanged(QString)));
0261 
0262     setFlag(ItemClipsToShape, true);
0263 }
0264 
0265 
0266 ColumnHeaderItem::~ColumnHeaderItem()
0267 {
0268 }
0269 
0270 void ColumnHeaderItem::mousePressEvent(QGraphicsSceneMouseEvent * _ev)
0271 {
0272     KoPointerEvent pev(_ev, QPointF());
0273     mousePress(&pev);
0274 }
0275 
0276 void ColumnHeaderItem::mouseReleaseEvent(QGraphicsSceneMouseEvent * _ev)
0277 {
0278     KoPointerEvent pev(_ev, QPointF());
0279     mouseRelease(&pev);
0280 }
0281 
0282 void ColumnHeaderItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent* _ev)
0283 {
0284     KoPointerEvent pev(_ev, QPointF());
0285     mouseDoubleClick(&pev);
0286 }
0287 
0288 void ColumnHeaderItem::mouseMoveEvent(QGraphicsSceneMouseEvent * _ev)
0289 {
0290     KoPointerEvent pev(_ev, QPointF());
0291     mouseMove(&pev);
0292 }
0293 /*
0294 void ColumnHeaderItem::slotAutoScroll(const QPoint& scrollDistance)
0295 {
0296     // NOTE Stefan: This slot is triggered by the same signal as
0297     //              Canvas::slotAutoScroll and RowHeaderItem::slotAutoScroll.
0298     //              Therefore, nothing has to be done except the scrolling was
0299     //              initiated in this header.
0300     if (!m_bMousePressed)
0301         return;
0302     if (scrollDistance.x() == 0)
0303         return;
0304     const QPoint offset = m_pCanvas->viewConverter()->documentToView(m_pCanvas->offset()).toPoint();
0305     if (offset.x() + scrollDistance.x() < 0)
0306         return;
0307     m_pCanvas->setDocumentOffset(offset + QPoint(scrollDistance.x(), 0));
0308     //QGraphicsSceneMouseEvent event(QEvent::MouseMove, mapFromGlobal(QCursor::pos()),
0309     //                  Qt::NoButton, Qt::NoButton, QApplication::keyboardModifiers());
0310     //QApplication::sendEvent(this, &event);
0311     m_pCanvas->update();
0312 }
0313 */
0314 void ColumnHeaderItem::wheelEvent(QGraphicsSceneWheelEvent* _ev)
0315 {
0316     Q_UNUSED(_ev);
0317     // TODO XXX
0318 }
0319 
0320 void ColumnHeaderItem::resizeEvent(QGraphicsSceneResizeEvent* _ev)
0321 {
0322     ColumnHeader::resize(_ev->newSize(), _ev->oldSize());
0323 }
0324 
0325 void ColumnHeaderItem::paintSizeIndicator(int mouseX)
0326 {
0327     register Sheet * const sheet = m_pCanvas->activeSheet();
0328     if (!sheet)
0329         return;
0330 
0331     if (sheet->layoutDirection() == Qt::RightToLeft)
0332         m_iResizePos = mouseX + m_pCanvas->width() - boundingRect().width();
0333     else
0334         m_iResizePos = mouseX;
0335 
0336     // Don't make the column have a width < 2 pixels.
0337     double x = m_pCanvas->zoomHandler()->zoomItX(sheet->columnPosition(m_iResizedColumn) - m_pCanvas->xOffset());
0338 
0339     if (sheet->layoutDirection() == Qt::RightToLeft) {
0340         x = m_pCanvas->width() - x;
0341 
0342         if (m_iResizePos > x - 2)
0343             m_iResizePos = (int) x;
0344     } else {
0345         if (m_iResizePos < x + 2)
0346             m_iResizePos = (int) x;
0347     }
0348 // XXX: Port
0349 //    if (!m_rubberband) {
0350 //        m_rubberband = new QRubberBand(QRubberBand::Line, m_pCanvas);
0351 //        m_rubberband->setGeometry(m_iResizePos, 0, 2, m_pCanvas->height());
0352 //        m_rubberband->show();
0353 //    }
0354 //    m_rubberband->move(m_iResizePos, 0);
0355 
0356     QString tmpSize;
0357     double ww = m_pCanvas->zoomHandler()->unzoomItX((sheet->layoutDirection() == Qt::RightToLeft) ? x - m_iResizePos : m_iResizePos - x);
0358     double wu = m_pCanvas->doc()->unit().toUserValue(ww);
0359     if (wu > 0.01)
0360         tmpSize = i18n("Width: %1 %2", wu, m_pCanvas->doc()->unit().symbol());
0361     else
0362         tmpSize = i18n("Hide Column");
0363 
0364 // XXX: Port
0365 //    if (!m_lSize) {
0366 //        int screenNo = 0; // QApplication::desktop()->screenNumber(this);
0367 //        m_lSize = new QLabel(QApplication::desktop()->screen(screenNo) , Qt::ToolTip);
0368 //        m_lSize->setAlignment(Qt::AlignVCenter);
0369 //        m_lSize->setAutoFillBackground(true);
0370 //        m_lSize->setPalette(QToolTip::palette());
0371 //        m_lSize->setMargin(1 + style()->pixelMetric(QStyle::PM_ToolTipLabelFrameWidth, 0, m_lSize));
0372 //        m_lSize->setFrameShape(QFrame::Box);
0373 //        m_lSize->setIndent(1);
0374 //    }
0375 //
0376 //    m_lSize->setText(tmpSize);
0377 //    m_lSize->adjustSize();
0378 //    QPoint pos = (sheet->layoutDirection() == Qt::RightToLeft) ? QPoint((int) x - 3 - m_lSize->width(), 3) :
0379 //                 QPoint((int) x + 3, 3);
0380 //    pos -= QPoint(0, m_lSize->height());
0381 //    m_lSize->move(m_pCanvas->mapToGlobal(pos).x(), mapToGlobal(pos).y());
0382 //    m_lSize->show();
0383 }
0384 
0385 void ColumnHeaderItem::removeSizeIndicator()
0386 {
0387     // XXX TODO
0388 }
0389 
0390 void ColumnHeaderItem::updateColumns(int from, int to)
0391 {
0392     register Sheet * const sheet = m_pCanvas->activeSheet();
0393     if (!sheet)
0394         return;
0395 
0396     double x0 = m_pCanvas->zoomHandler()->zoomItX(sheet->columnPosition(from));
0397     double x1 = m_pCanvas->zoomHandler()->zoomItX(sheet->columnPosition(to + 1));
0398     QGraphicsItem::update((int) x0, 0, (int)(x1 - x0), boundingRect().height());
0399 }
0400 
0401 void ColumnHeaderItem::paint(QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget)
0402 {
0403     Q_UNUSED(widget);
0404     ColumnHeader::paint(painter, option->exposedRect);
0405 }
0406 
0407 
0408 void ColumnHeaderItem::focusOutEvent(QFocusEvent* _ev)
0409 {
0410     focusOut(_ev);
0411 }
0412 
0413 void ColumnHeaderItem::toolChanged(const QString& toolId)
0414 {
0415     doToolChanged(toolId);
0416 }
0417 
0418 void ColumnHeaderItem::scroll(qreal x, qreal y)
0419 {
0420     if (m_pCanvas->layoutDirection() == Qt::RightToLeft) {
0421         QGraphicsWidget::scroll(-x, y);
0422     } else {
0423         QGraphicsWidget::scroll(x, y);
0424     }
0425 }
0426 
0427 /****************************************************************
0428  *
0429  * SelectAllButtonItem
0430  *
0431  ****************************************************************/
0432 
0433 SelectAllButtonItem::SelectAllButtonItem(QGraphicsItem *_parent, CanvasBase* canvasBase)
0434         : QGraphicsWidget(_parent)
0435         , SelectAllButton(canvasBase)
0436 {
0437     connect(canvasBase->toolProxy(), SIGNAL(toolChanged(QString)),
0438             this, SLOT(toolChanged(QString)));
0439 }
0440 
0441 SelectAllButtonItem::~SelectAllButtonItem()
0442 {
0443 }
0444 
0445 void SelectAllButtonItem::paint(QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget)
0446 {
0447     Q_UNUSED(widget);
0448     SelectAllButton::paint(painter, option->exposedRect);
0449 }
0450 
0451 void SelectAllButtonItem::mousePressEvent(QGraphicsSceneMouseEvent* _ev)
0452 {
0453     KoPointerEvent pev(_ev, QPointF());
0454     mousePress(&pev);
0455 }
0456 
0457 void SelectAllButtonItem::mouseReleaseEvent(QGraphicsSceneMouseEvent* _ev)
0458 {
0459     KoPointerEvent pev(_ev, QPointF());
0460     mouseRelease(&pev);
0461 }
0462 
0463 void SelectAllButtonItem::wheelEvent(QGraphicsSceneWheelEvent* _ev)
0464 {
0465     Q_UNUSED(_ev);
0466     // TODO XXX
0467 }
0468 
0469 void SelectAllButtonItem::toolChanged(const QString& toolId)
0470 {
0471     doToolChanged(toolId);
0472 }