File indexing completed on 2024-05-12 16:35:46
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 "HeaderWidgets.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 0057 // KF5 0058 #include <KLocalizedString> 0059 0060 // Calligra 0061 #include <KoCanvasController.h> 0062 #include <KoToolProxy.h> 0063 #include <KoZoomHandler.h> 0064 #include <KoPointerEvent.h> 0065 #include <KoUnit.h> 0066 0067 // Sheets 0068 #include "Canvas.h" 0069 #include "Cell.h" 0070 #include "Doc.h" 0071 #include "calligra_sheets_limits.h" 0072 #include "RowColumnFormat.h" 0073 #include "Sheet.h" 0074 #include "View.h" 0075 0076 // commands 0077 #include "commands/RowColumnManipulators.h" 0078 0079 // ui 0080 #include "ui/Selection.h" 0081 0082 using namespace Calligra::Sheets; 0083 0084 /**************************************************************** 0085 * 0086 * RowHeaderWidget 0087 * 0088 ****************************************************************/ 0089 0090 RowHeaderWidget::RowHeaderWidget(QWidget *_parent, Canvas *_canvas, View *_view) 0091 : QWidget(_parent), RowHeader(_canvas), m_rubberband(0) 0092 { 0093 setAttribute(Qt::WA_StaticContents); 0094 setMouseTracking(true); 0095 0096 connect(_view, SIGNAL(autoScroll(QPoint)), 0097 this, SLOT(slotAutoScroll(QPoint))); 0098 connect(m_pCanvas->toolProxy(), SIGNAL(toolChanged(QString)), 0099 this, SLOT(toolChanged(QString))); 0100 } 0101 0102 0103 RowHeaderWidget::~RowHeaderWidget() 0104 { 0105 } 0106 0107 void RowHeaderWidget::mousePressEvent(QMouseEvent * _ev) 0108 { 0109 KoPointerEvent pev(_ev, QPointF()); 0110 mousePress(&pev); 0111 } 0112 0113 void RowHeaderWidget::mouseReleaseEvent(QMouseEvent * _ev) 0114 { 0115 KoPointerEvent pev(_ev, QPointF()); 0116 mouseRelease(&pev); 0117 } 0118 0119 void RowHeaderWidget::mouseDoubleClickEvent(QMouseEvent * _ev) 0120 { 0121 KoPointerEvent pev(_ev, QPointF()); 0122 mouseDoubleClick(&pev); 0123 } 0124 0125 void RowHeaderWidget::mouseMoveEvent(QMouseEvent * _ev) 0126 { 0127 KoPointerEvent pev(_ev, QPointF()); 0128 mouseMove(&pev); 0129 } 0130 0131 void RowHeaderWidget::slotAutoScroll(const QPoint& scrollDistance) 0132 { 0133 // NOTE Stefan: This slot is triggered by the same signal as 0134 // Canvas::slotAutoScroll and ColumnHeaderWidget::slotAutoScroll. 0135 // Therefore, nothing has to be done except the scrolling was 0136 // initiated in this header. 0137 if (!m_bMousePressed) 0138 return; 0139 if (scrollDistance.y() == 0) 0140 return; 0141 const QPoint offset = m_pCanvas->viewConverter()->documentToView(m_pCanvas->offset()).toPoint(); 0142 if (offset.y() + scrollDistance.y() < 0) 0143 return; 0144 m_pCanvas->setDocumentOffset(offset + QPoint(0, scrollDistance.y())); 0145 QMouseEvent event(QEvent::MouseMove, mapFromGlobal(QCursor::pos()), 0146 Qt::NoButton, Qt::NoButton, QApplication::keyboardModifiers()); 0147 QApplication::sendEvent(this, &event); 0148 m_pCanvas->update(); 0149 } 0150 0151 void RowHeaderWidget::wheelEvent(QWheelEvent* _ev) 0152 { 0153 QApplication::sendEvent(static_cast<Canvas*>(m_pCanvas), _ev); 0154 } 0155 0156 void RowHeaderWidget::paintSizeIndicator(int mouseY) 0157 { 0158 register Sheet * const sheet = m_pCanvas->activeSheet(); 0159 if (!sheet) 0160 return; 0161 0162 m_iResizePos = mouseY; 0163 0164 // Don't make the row have a height < 2 pixel. 0165 double y = m_pCanvas->zoomHandler()->zoomItY(sheet->rowPosition(m_iResizedRow) - m_pCanvas->yOffset()); 0166 if (m_iResizePos < y + 2) 0167 m_iResizePos = (int) y; 0168 0169 if (!m_rubberband) { 0170 m_rubberband = new QRubberBand(QRubberBand::Line, static_cast<Canvas*>(m_pCanvas)); 0171 m_rubberband->setGeometry(0, m_iResizePos, m_pCanvas->width(), 2); 0172 m_rubberband->show(); 0173 } 0174 m_rubberband->move(0, m_iResizePos); 0175 0176 QString tmpSize; 0177 double hh = m_pCanvas->zoomHandler()->unzoomItY(m_iResizePos - y); 0178 double hu = m_pCanvas->doc()->unit().toUserValue(hh); 0179 if (hu > 0.01) 0180 tmpSize = i18n("Height: %1 %2", hu, m_pCanvas->doc()->unit().symbol()); 0181 else 0182 tmpSize = i18n("Hide Row"); 0183 0184 if (!m_lSize) { 0185 int screenNo = QApplication::desktop()->screenNumber(this); 0186 m_lSize = new QLabel(QApplication::desktop()->screen(screenNo) , Qt::ToolTip); 0187 m_lSize->setAlignment(Qt::AlignVCenter); 0188 m_lSize->setAutoFillBackground(true); 0189 m_lSize->setPalette(QToolTip::palette()); 0190 m_lSize->setMargin(1 + style()->pixelMetric(QStyle::PM_ToolTipLabelFrameWidth, 0, m_lSize)); 0191 m_lSize->setFrameShape(QFrame::Box); 0192 m_lSize->setIndent(1); 0193 } 0194 0195 m_lSize->setText(tmpSize); 0196 m_lSize->adjustSize(); 0197 QPoint pos = (sheet->layoutDirection() == Qt::RightToLeft) ? QPoint(m_pCanvas->width() - m_lSize->width() - 3, (int)y + 3) : 0198 QPoint(3, (int)y + 3); 0199 pos -= QPoint(0, m_lSize->height()); 0200 m_lSize->move(m_pCanvas->mapToGlobal(pos).x(), m_pCanvas->mapToGlobal(pos).y()); 0201 m_lSize->show(); 0202 } 0203 0204 void RowHeaderWidget::removeSizeIndicator() 0205 { 0206 delete m_rubberband; 0207 m_rubberband = 0; 0208 } 0209 0210 void RowHeaderWidget::updateRows(int from, int to) 0211 { 0212 register Sheet * const sheet = m_pCanvas->activeSheet(); 0213 if (!sheet) 0214 return; 0215 0216 double y0 = m_pCanvas->zoomHandler()->zoomItY(sheet->rowPosition(from)); 0217 double y1 = m_pCanvas->zoomHandler()->zoomItY(sheet->rowPosition(to + 1)); 0218 QWidget::update(0, (int) y0, QWidget::width(), (int)(y1 - y0)); 0219 } 0220 0221 void RowHeaderWidget::paintEvent(QPaintEvent* event) 0222 { 0223 QPainter painter(this); 0224 paint(&painter, event->rect()); 0225 } 0226 0227 0228 void RowHeaderWidget::focusOutEvent(QFocusEvent * _ev) 0229 { 0230 focusOut(_ev); 0231 } 0232 0233 void RowHeaderWidget::toolChanged(const QString& toolId) 0234 { 0235 doToolChanged(toolId); 0236 } 0237 0238 /**************************************************************** 0239 * 0240 * ColumnHeaderWidget 0241 * 0242 ****************************************************************/ 0243 0244 ColumnHeaderWidget::ColumnHeaderWidget(QWidget *_parent, Canvas *_canvas, View *_view) 0245 : QWidget(_parent), ColumnHeader(_canvas), m_rubberband(0) 0246 { 0247 setAttribute(Qt::WA_StaticContents); 0248 setMouseTracking(true); 0249 0250 connect(_view, SIGNAL(autoScroll(QPoint)), 0251 this, SLOT(slotAutoScroll(QPoint))); 0252 connect(m_pCanvas->toolProxy(), SIGNAL(toolChanged(QString)), 0253 this, SLOT(toolChanged(QString))); 0254 } 0255 0256 0257 ColumnHeaderWidget::~ColumnHeaderWidget() 0258 { 0259 } 0260 0261 void ColumnHeaderWidget::mousePressEvent(QMouseEvent * _ev) 0262 { 0263 KoPointerEvent pev(_ev, QPointF()); 0264 mousePress(&pev); 0265 } 0266 0267 void ColumnHeaderWidget::mouseReleaseEvent(QMouseEvent * _ev) 0268 { 0269 KoPointerEvent pev(_ev, QPointF()); 0270 mouseRelease(&pev); 0271 } 0272 0273 void ColumnHeaderWidget::mouseDoubleClickEvent(QMouseEvent * _ev) 0274 { 0275 KoPointerEvent pev(_ev, QPointF()); 0276 mouseDoubleClick(&pev); 0277 } 0278 0279 void ColumnHeaderWidget::mouseMoveEvent(QMouseEvent * _ev) 0280 { 0281 KoPointerEvent pev(_ev, QPointF()); 0282 mouseMove(&pev); 0283 } 0284 0285 void ColumnHeaderWidget::slotAutoScroll(const QPoint& scrollDistance) 0286 { 0287 // NOTE Stefan: This slot is triggered by the same signal as 0288 // Canvas::slotAutoScroll and RowHeaderWidget::slotAutoScroll. 0289 // Therefore, nothing has to be done except the scrolling was 0290 // initiated in this header. 0291 if (!m_bMousePressed) 0292 return; 0293 if (scrollDistance.x() == 0) 0294 return; 0295 const QPoint offset = m_pCanvas->viewConverter()->documentToView(m_pCanvas->offset()).toPoint(); 0296 if (offset.x() + scrollDistance.x() < 0) 0297 return; 0298 m_pCanvas->setDocumentOffset(offset + QPoint(scrollDistance.x(), 0)); 0299 QMouseEvent event(QEvent::MouseMove, mapFromGlobal(QCursor::pos()), 0300 Qt::NoButton, Qt::NoButton, QApplication::keyboardModifiers()); 0301 QApplication::sendEvent(this, &event); 0302 m_pCanvas->update(); 0303 } 0304 0305 void ColumnHeaderWidget::wheelEvent(QWheelEvent* _ev) 0306 { 0307 QApplication::sendEvent(static_cast<Canvas*>(m_pCanvas), _ev); 0308 } 0309 0310 void ColumnHeaderWidget::resizeEvent(QResizeEvent* _ev) 0311 { 0312 ColumnHeader::resize(_ev->size(), _ev->oldSize()); 0313 } 0314 0315 void ColumnHeaderWidget::paintSizeIndicator(int mouseX) 0316 { 0317 register Sheet * const sheet = m_pCanvas->activeSheet(); 0318 if (!sheet) 0319 return; 0320 0321 if (sheet->layoutDirection() == Qt::RightToLeft) 0322 m_iResizePos = mouseX + m_pCanvas->width() - QWidget::width(); 0323 else 0324 m_iResizePos = mouseX; 0325 0326 // Don't make the column have a width < 2 pixels. 0327 double x = m_pCanvas->zoomHandler()->zoomItX(sheet->columnPosition(m_iResizedColumn) - m_pCanvas->xOffset()); 0328 0329 if (sheet->layoutDirection() == Qt::RightToLeft) { 0330 x = m_pCanvas->width() - x; 0331 0332 if (m_iResizePos > x - 2) 0333 m_iResizePos = (int) x; 0334 } else { 0335 if (m_iResizePos < x + 2) 0336 m_iResizePos = (int) x; 0337 } 0338 0339 if (!m_rubberband) { 0340 m_rubberband = new QRubberBand(QRubberBand::Line, static_cast<Canvas*>(m_pCanvas)); 0341 m_rubberband->setGeometry(m_iResizePos, 0, 2, m_pCanvas->height()); 0342 m_rubberband->show(); 0343 } 0344 m_rubberband->move(m_iResizePos, 0); 0345 0346 QString tmpSize; 0347 double ww = m_pCanvas->zoomHandler()->unzoomItX((sheet->layoutDirection() == Qt::RightToLeft) ? x - m_iResizePos : m_iResizePos - x); 0348 double wu = m_pCanvas->doc()->unit().toUserValue(ww); 0349 if (wu > 0.01) 0350 tmpSize = i18n("Width: %1 %2", wu, m_pCanvas->doc()->unit().symbol()); 0351 else 0352 tmpSize = i18n("Hide Column"); 0353 0354 if (!m_lSize) { 0355 int screenNo = QApplication::desktop()->screenNumber(this); 0356 m_lSize = new QLabel(QApplication::desktop()->screen(screenNo) , Qt::ToolTip); 0357 m_lSize->setAlignment(Qt::AlignVCenter); 0358 m_lSize->setAutoFillBackground(true); 0359 m_lSize->setPalette(QToolTip::palette()); 0360 m_lSize->setMargin(1 + style()->pixelMetric(QStyle::PM_ToolTipLabelFrameWidth, 0, m_lSize)); 0361 m_lSize->setFrameShape(QFrame::Box); 0362 m_lSize->setIndent(1); 0363 } 0364 0365 m_lSize->setText(tmpSize); 0366 m_lSize->adjustSize(); 0367 QPoint pos = (sheet->layoutDirection() == Qt::RightToLeft) ? QPoint((int) x - 3 - m_lSize->width(), 3) : 0368 QPoint((int) x + 3, 3); 0369 pos -= QPoint(0, m_lSize->height()); 0370 m_lSize->move(m_pCanvas->mapToGlobal(pos).x(), mapToGlobal(pos).y()); 0371 m_lSize->show(); 0372 } 0373 0374 void ColumnHeaderWidget::removeSizeIndicator() 0375 { 0376 delete m_rubberband; 0377 m_rubberband = 0; 0378 } 0379 0380 void ColumnHeaderWidget::updateColumns(int from, int to) 0381 { 0382 register Sheet * const sheet = m_pCanvas->activeSheet(); 0383 if (!sheet) 0384 return; 0385 0386 double x0 = m_pCanvas->zoomHandler()->zoomItX(sheet->columnPosition(from)); 0387 double x1 = m_pCanvas->zoomHandler()->zoomItX(sheet->columnPosition(to + 1)); 0388 QWidget::update((int) x0, 0, (int)(x1 - x0), QWidget::height()); 0389 } 0390 0391 void ColumnHeaderWidget::paintEvent(QPaintEvent* event) 0392 { 0393 QPainter painter(this); 0394 paint(&painter, event->rect()); 0395 } 0396 0397 0398 void ColumnHeaderWidget::focusOutEvent(QFocusEvent * _ev) 0399 { 0400 focusOut(_ev); 0401 } 0402 0403 void ColumnHeaderWidget::toolChanged(const QString& toolId) 0404 { 0405 doToolChanged(toolId); 0406 } 0407 0408 0409 /**************************************************************** 0410 * 0411 * SelectAllButtonWidget 0412 * 0413 ****************************************************************/ 0414 0415 SelectAllButtonWidget::SelectAllButtonWidget(CanvasBase* canvasBase) 0416 : QWidget(canvasBase->canvasWidget()) 0417 , SelectAllButton(canvasBase) 0418 { 0419 connect(canvasBase->toolProxy(), SIGNAL(toolChanged(QString)), 0420 this, SLOT(toolChanged(QString))); 0421 } 0422 0423 SelectAllButtonWidget::~SelectAllButtonWidget() 0424 { 0425 } 0426 0427 void SelectAllButtonWidget::paintEvent(QPaintEvent* event) 0428 { 0429 QPainter painter(this); 0430 paint(&painter, event->rect()); 0431 } 0432 0433 void SelectAllButtonWidget::mousePressEvent(QMouseEvent* _ev) 0434 { 0435 KoPointerEvent pev(_ev, QPointF()); 0436 mousePress(&pev); 0437 } 0438 0439 void SelectAllButtonWidget::mouseReleaseEvent(QMouseEvent* _ev) 0440 { 0441 KoPointerEvent pev(_ev, QPointF()); 0442 mouseRelease(&pev); 0443 } 0444 0445 void SelectAllButtonWidget::wheelEvent(QWheelEvent* _ev) 0446 { 0447 QApplication::sendEvent(static_cast<Canvas*>(m_canvasBase), _ev); 0448 } 0449 0450 void SelectAllButtonWidget::toolChanged(const QString& toolId) 0451 { 0452 doToolChanged(toolId); 0453 }