File indexing completed on 2024-05-12 16:36:10
0001 /* This file is part of the KDE project 0002 Copyright 2008 Stefan Nikolaus <stefan.nikolaus@kdemail.net> 0003 0004 This library is free software; you can redistribute it and/or 0005 modify it under the terms of the GNU Library General Public 0006 License as published by the Free Software Foundation; either 0007 version 2 of the License, or (at your option) any later version. 0008 0009 This library is distributed in the hope that it will be useful, 0010 but WITHOUT ANY WARRANTY; without even the implied warranty of 0011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0012 Library General Public License for more details. 0013 0014 You should have received a copy of the GNU Library General Public License 0015 along with this library; see the file COPYING.LIB. If not, write to 0016 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0017 Boston, MA 02110-1301, USA. 0018 */ 0019 0020 #include "SelectionStrategy.h" 0021 0022 #include "CellEditor.h" 0023 #include "CellToolBase.h" 0024 #include "calligra_sheets_limits.h" 0025 #include "Selection.h" 0026 #include "Sheet.h" 0027 0028 #include <KoCanvasBase.h> 0029 #include <KoSelection.h> 0030 #include <KoShapeManager.h> 0031 0032 using namespace Calligra::Sheets; 0033 0034 class Q_DECL_HIDDEN SelectionStrategy::Private 0035 { 0036 public: 0037 Cell startCell; 0038 }; 0039 0040 SelectionStrategy::SelectionStrategy(CellToolBase *cellTool, 0041 const QPointF &documentPos, Qt::KeyboardModifiers modifiers) 0042 : AbstractSelectionStrategy(cellTool, documentPos, modifiers) 0043 , d(new Private) 0044 { 0045 d->startCell = Cell(); 0046 0047 const QPointF position = documentPos; 0048 Sheet *const sheet = this->selection()->activeSheet(); 0049 Selection *const selection = this->selection(); 0050 0051 #if 0 // CALLIGRA_SHEETS_WIP_DRAG_REFERENCE_SELECTION 0052 // Check, if the selected area was hit. 0053 bool hitSelection = false; 0054 const Region::ConstIterator end(selection->constEnd()); 0055 for (Region::ConstIterator it(selection->constBegin()); it != end; ++it) { 0056 // Only process ranges on the active sheet. 0057 if (sheet != (*it)->sheet()) { 0058 continue; 0059 } 0060 const QRect range = (*it)->rect(); 0061 if (sheet->cellCoordinatesToDocument(range).contains(position)) { 0062 hitSelection = true; 0063 break; 0064 } 0065 } 0066 #endif // CALLIGRA_SHEETS_WIP_DRAG_REFERENCE_SELECTION 0067 0068 // In which cell did the user click? 0069 qreal xpos; 0070 qreal ypos; 0071 const int col = sheet->leftColumn(position.x(), xpos); 0072 const int row = sheet->topRow(position.y(), ypos); 0073 // Check boundaries. 0074 if (col > KS_colMax || row > KS_rowMax) { 0075 debugSheetsUI << "col or row is out of range:" << "col:" << col << " row:" << row; 0076 } else { 0077 d->startCell = Cell(sheet, col, row); 0078 if (selection->referenceSelectionMode()) { 0079 selection->emitRequestFocusEditor(); 0080 const bool sizeGripHit = hitTestReferenceSizeGrip(tool()->canvas(), selection, position); 0081 const bool shiftPressed = modifiers & Qt::ShiftModifier; 0082 if (sizeGripHit) { 0083 // FIXME The size grip is partly located in the adjacent cells. 0084 // Activate the selection's location/range. 0085 const int index = selection->setActiveElement(d->startCell); 0086 // If successful, activate the editor's location/range. 0087 if (index >= 0 && cellTool->editor()) { 0088 cellTool->editor()->setActiveSubRegion(index); 0089 } 0090 selection->update(QPoint(col, row)); 0091 } else if (shiftPressed) { 0092 selection->update(QPoint(col, row)); 0093 } else if (modifiers & Qt::ControlModifier) { 0094 // Extend selection, if control modifier is pressed. 0095 selection->extend(QPoint(col, row), sheet); 0096 #if 0 // CALLIGRA_SHEETS_WIP_DRAG_REFERENCE_SELECTION 0097 } else if (hitSelection) { 0098 // start cell is already set above 0099 // No change; the range will be moved 0100 #endif // CALLIGRA_SHEETS_WIP_DRAG_REFERENCE_SELECTION 0101 } else { 0102 selection->initialize(QPoint(col, row), sheet); 0103 } 0104 } else { 0105 selection->emitCloseEditor(true); 0106 if (modifiers & Qt::ControlModifier) { 0107 // Extend selection, if control modifier is pressed. 0108 selection->extend(QPoint(col, row), sheet); 0109 } else if (modifiers & Qt::ShiftModifier) { 0110 selection->update(QPoint(col, row)); 0111 } else { 0112 selection->initialize(QPoint(col, row), sheet); 0113 } 0114 } 0115 } 0116 tool()->repaintDecorations(); 0117 } 0118 0119 SelectionStrategy::~SelectionStrategy() 0120 { 0121 delete d; 0122 } 0123 0124 void SelectionStrategy::handleMouseMove(const QPointF &documentPos, 0125 Qt::KeyboardModifiers modifiers) 0126 { 0127 #if 0 // CALLIGRA_SHEETS_WIP_DRAG_REFERENCE_SELECTION 0128 Q_UNUSED(modifiers); 0129 //const KoShape* shape = tool()->canvas()->shapeManager()->selection()->firstSelectedShape(); 0130 const QPointF position = documentPos /*- (shape ? shape->position() : QPointF(0.0, 0.0))*/; 0131 Sheet *const sheet = selection()->activeSheet(); 0132 0133 if (selection()->referenceSelectionMode()) { 0134 // In which cell did the user move? 0135 double xpos; 0136 double ypos; 0137 const int col = sheet->leftColumn(position.x(), xpos); 0138 const int row = sheet->topRow(position.y(), ypos); 0139 // Check boundaries. 0140 if (col > KS_colMax || row > KS_rowMax) { 0141 debugSheetsUI << "col or row is out of range:" << "col:" << col << " row:" << row; 0142 } else if (!(d->startCell == Cell(sheet, col, row))) { 0143 const QRect range = selection()->activeElement()->rect(); 0144 const QPoint offset = d->startCell.cellPosition() - range.topLeft(); 0145 const QPoint topLeft = QPoint(col, row) + offset; 0146 selection()->initialize(QRect(topLeft, range.size()), sheet); 0147 return; 0148 } 0149 } 0150 #endif // CALLIGRA_SHEETS_WIP_DRAG_REFERENCE_SELECTION 0151 AbstractSelectionStrategy::handleMouseMove(documentPos, modifiers); 0152 }