KOffice – TDE office suite
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

734 lines
22KB

  1. /* This file is part of the KDE project
  2. Copyright 2006 Stefan Nikolaus <stefan.nikolaus@kdemail.net>
  3. Copyright 1999-2002,2004 Laurent Montel <montel@kde.org>
  4. Copyright 2002-2005 Ariya Hidayat <ariya@kde.org>
  5. Copyright 1999-2001,2003 David Faure <faure@kde.org>
  6. Copyright 2001-2003 Philipp Mueller <philipp.mueller@gmx.de>
  7. Copyright 2002-2003 Norbert Andres <nandres@web.de>
  8. Copyright 2000-2001 Werner Trobin <trobin@kde.org>
  9. Copyright 2002 Harri Porten <porten@kde.org>
  10. Copyright 2002 John Dailey <dailey@vt.edu>
  11. Copyright 1999-2000 Torben Weis <weis@kde.org>
  12. Copyright 2000 Wilco Greven <greven@kde.org>
  13. Copyright 1999 Boris Wedl <boris.wedl@kfunigraz.ac.at>
  14. Copyright 1999 Reginald Stadlbauer <reggie@kde.org>
  15. This library is free software; you can redistribute it and/or
  16. modify it under the terms of the GNU Library General Public
  17. License as published by the Free Software Foundation; either
  18. version 2 of the License, or (at your option) any later version.
  19. This library is distributed in the hope that it will be useful,
  20. but WITHOUT ANY WARRANTY; without even the implied warranty of
  21. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  22. Library General Public License for more details.
  23. You should have received a copy of the GNU Library General Public License
  24. along with this library; see the file COPYING.LIB. If not, write to
  25. the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  26. * Boston, MA 02110-1301, USA.
  27. */
  28. #ifndef KSPREAD_CANVAS
  29. #define KSPREAD_CANVAS
  30. #include <vector>
  31. #include <tqlineedit.h>
  32. #include <tqtooltip.h>
  33. #include <tqpen.h>
  34. #include <ksharedptr.h>
  35. #include <koffice_export.h>
  36. #include "kspread_util.h"
  37. #define YBORDER_WIDTH 50
  38. #define XBORDER_HEIGHT 20
  39. class TQWidget;
  40. class TQTimer;
  41. class TQButton;
  42. class TQPainter;
  43. class TQLabel;
  44. class TQScrollBar;
  45. class KoRect;
  46. class KoPoint;
  47. namespace KSpread
  48. {
  49. class Cell;
  50. class EditWidget;
  51. class Canvas;
  52. class HBorder;
  53. class VBorder;
  54. class Sheet;
  55. class Doc;
  56. class Point;
  57. class Range;
  58. class Region;
  59. class View;
  60. class Selection;
  61. class CellEditor;
  62. class LocationEditWidget;
  63. class ComboboxLocationEditWidget;
  64. class EmbeddedObject;
  65. /**
  66. * The canvas builds a part of the GUI of KSpread.
  67. * It contains the borders, scrollbars,
  68. * editwidget and of course it displays the sheet.
  69. * Especially most of the user interface logic is implemented here.
  70. * That means that this class knows what to do when a key is pressed
  71. * or if the mouse button was clicked.
  72. */
  73. class KSPREAD_EXPORT Canvas : public TQWidget
  74. {
  75. friend class HBorder;
  76. friend class VBorder;
  77. friend class View;
  78. Q_OBJECT
  79. public:
  80. /**
  81. * The current action associated with the mouse.
  82. * Default is 'NoAction'.
  83. */
  84. enum MouseActions
  85. {
  86. /** No mouse action (default) */
  87. NoAction,
  88. /** Marking action */
  89. Mark,
  90. /** Merging cell */
  91. ResizeCell,
  92. /** Autofilling */
  93. AutoFill,
  94. /** Resizing the selection */
  95. ResizeSelection
  96. };
  97. enum EditorType { CellEditor, EditWidget };
  98. Canvas (View *_view);
  99. ~Canvas( );
  100. View* view() const;
  101. Doc* doc() const;
  102. KSpread::EditWidget* editWidget() const;
  103. KSpread::CellEditor* editor() const;
  104. /**
  105. * @return the usual selection of cells
  106. */
  107. Selection* selectionInfo() const;
  108. /**
  109. * @return a selection of cells used in formulas
  110. */
  111. Selection* choice() const;
  112. /**
  113. * @deprecated use selectionInfo()
  114. * Selections are no longer contiguous in general.
  115. * @see Selection::lastRange()
  116. * @see Selection::activeElement()
  117. */
  118. TQRect selection() const;
  119. /**
  120. * convenience function.
  121. * @return selection's marker
  122. * @see Selection::marker()
  123. */
  124. TQPoint marker() const;
  125. /**
  126. * convenience function.
  127. * @return selection's marker's column
  128. * @see Selection::marker()
  129. */
  130. int markerColumn() const;
  131. /**
  132. * convenience function.
  133. * @return selection's marker's row
  134. * @see Selection::marker()
  135. */
  136. int markerRow() const;
  137. /**
  138. * @return the pen, the default grid is painted with (light gray)
  139. */
  140. const TQPen& defaultGridPen() const;
  141. /**
  142. * convenience function
  143. * @see View::zoom()
  144. */
  145. double zoom() const;
  146. /**
  147. * @return the width of the columns before the current screen
  148. */
  149. double xOffset() const;
  150. /**
  151. * @return the height of the rows before the current screen
  152. */
  153. double yOffset() const;
  154. /**
  155. * Sets the width of the columns before the current screen
  156. */
  157. void setXOffset( double _xOffset );
  158. /**
  159. * Sets the height of the rows before the current screen
  160. */
  161. void setYOffset( double _yOffset );
  162. /**
  163. * @return a rect indicating which cell range is currently visible onscreen
  164. */
  165. TQRect visibleCells() const;
  166. /**
  167. * @return a pointer to the active sheet
  168. */
  169. Sheet* activeSheet() const;
  170. /**
  171. * convenience function
  172. * @see Map::findSheet()
  173. */
  174. Sheet* findSheet( const TQString& _name ) const;
  175. /**
  176. * Validates the selected cell.
  177. */
  178. void validateSelection();
  179. /**
  180. * Paint all visible cells that have a paint dirty flag set
  181. */
  182. void paintUpdates();
  183. /**
  184. * Makes sure a cell is visible onscreen by scrolling up/down and left/right
  185. *
  186. * @param location the cell coordinates to scroll to
  187. */
  188. void scrollToCell(TQPoint location) const;
  189. /**
  190. * Chooses the correct EditorType by looking at
  191. * the current cells value. By default CellEditor is chosen.
  192. */
  193. void createEditor( bool captureArrowKeys=false );
  194. bool createEditor( EditorType type, bool addFocus = true, bool captureArrowKeys=false );
  195. /**
  196. * Deletes the current cell editor.
  197. *
  198. * @see #createEditor
  199. * @see #editor
  200. * @param saveChanges if true, the edited text is stored in the cell.
  201. * if false, the changes are discarded.
  202. * @param array if true, array formula was entered
  203. */
  204. void deleteEditor(bool saveChanges, bool array = false);
  205. /**
  206. * Called from @ref EditWidget and CellEditor
  207. * if they loose the focus because the user started a "choose selection".
  208. * This is done because the editor wants to get its focus back afterwards.
  209. * But somehow Canvas must know whether the EditWidget or the CellEditor
  210. * lost the focus when the user clicked on the canvas.
  211. */
  212. void setLastEditorWithFocus( EditorType type );
  213. /**
  214. * Switches to choose mode and sets the initial selection to the
  215. * position returned by marker().
  216. * Clears the choice.
  217. */
  218. void startChoose();
  219. /**
  220. * Switches to choose mode and sets the initial @p selection.
  221. */
  222. void startChoose( const TQRect& selection );
  223. /**
  224. * Switches to selection mode.
  225. * Clear the choice.
  226. */
  227. void endChoose();
  228. /**
  229. * Switches the choose mode on and off.
  230. * Does not clear the choice.
  231. */
  232. void setChooseMode(bool state);
  233. /**
  234. * @return @c true if choose mode is enabled, @c false otherwise
  235. */
  236. bool chooseMode() const;
  237. void equalizeRow();
  238. void equalizeColumn();
  239. /**
  240. * Updates the position widget.
  241. */
  242. void updatePosWidget();
  243. /**
  244. * Close the cell editor and saves changes.
  245. * @see deleteEditor()
  246. */
  247. void closeEditor();
  248. // Created by the view since it's layout is managed there,
  249. // but is in fact a sibling of the canvas, which needs to know about it.
  250. void setEditWidget( KSpread::EditWidget * ew );
  251. virtual bool focusNextPrevChild( bool );
  252. /**
  253. * Depending on the offset in "zoomed" screen pixels
  254. * for the horizontal direction,
  255. * the function returns the steps in unzoomed points
  256. * for the autoscroll acceleration
  257. */
  258. double autoScrollAccelerationX( int offset );
  259. /**
  260. * Depending on the offset in "zoomed" screen pixels
  261. * for the vertical direction,
  262. * the function returns the steps in unzoomed points
  263. * for the autoscroll acceleration
  264. */
  265. double autoScrollAccelerationY( int offset );
  266. //TODO: These embedded-object related methods need API documentation!
  267. EmbeddedObject* getObject( const TQPoint &pos, Sheet *_sheet );
  268. void selectAllObjects();
  269. void deselectAllObjects();
  270. void selectObject( EmbeddedObject* );
  271. void deselectObject( EmbeddedObject* );
  272. void setMouseSelectedObject(bool b);
  273. bool isObjectSelected();
  274. /**
  275. * @brief Move object by mouse
  276. *
  277. * @param pos The position of the mouse
  278. * @param keepXorYunchanged if true keep x or y position unchanged
  279. */
  280. void moveObjectsByMouse( KoPoint &pos, bool keepXorYunchanged );
  281. //---- stuff needed for resizing ----
  282. /// resize the m_resizeObject
  283. void resizeObject( ModifyType _modType, const KoPoint & point, bool keepRatio );
  284. /// create KPrResizeCmd
  285. void finishResizeObject( const TQString &name, bool layout = true );
  286. /**
  287. * @brief Display object above the other objects in editiong mode
  288. *
  289. * This is used to bring a single slected object to front, so it is easier
  290. * to modify.
  291. *
  292. * @param object which should be displayed above the other objects
  293. */
  294. void raiseObject( EmbeddedObject *object );
  295. /**
  296. * @brief Don't display an object above the others
  297. */
  298. void lowerObject();
  299. /**
  300. * @brief Get the list of objects in the order they should be displayed.
  301. *
  302. * This takes into acount the object set in raiseObject so that it is
  303. * the last one in the list returned (the one that is displayed above all
  304. * the others).
  305. *
  306. * @return List of objects
  307. */
  308. void displayObjectList( TQPtrList<EmbeddedObject> &list );
  309. KoRect objectRect( bool all ) const;
  310. void repaintObject( EmbeddedObject *obj );
  311. /**
  312. * This is intended to copy the selected objects to the clipboard so that they can be pasted into other
  313. * applications. However, until at least KWord, KSpread, KPresenter, KChart and KFormula have consistant
  314. * support for copying and pasting of OASIS objects the selected objects will just be copied in the form
  315. * of raster graphics
  316. */
  317. void copyOasisObjects();
  318. //void insertOasisData();
  319. public slots:
  320. void slotScrollVert( int _value );
  321. void slotScrollHorz( int _value );
  322. void slotMaxColumn( int _max_column );
  323. void slotMaxRow( int _max_row );
  324. signals:
  325. void objectSelectedChanged();
  326. void objectSizeChanged();
  327. protected:
  328. virtual void keyPressEvent ( TQKeyEvent* _ev );
  329. virtual void paintEvent ( TQPaintEvent* _ev );
  330. virtual void mousePressEvent( TQMouseEvent* _ev );
  331. virtual void mouseReleaseEvent( TQMouseEvent* _ev );
  332. virtual void mouseMoveEvent( TQMouseEvent* _ev );
  333. virtual void mouseDoubleClickEvent( TQMouseEvent* );
  334. virtual void wheelEvent( TQWheelEvent* );
  335. virtual void focusInEvent( TQFocusEvent* );
  336. virtual void focusOutEvent( TQFocusEvent* );
  337. virtual void resizeEvent( TQResizeEvent * _ev );
  338. virtual void dragMoveEvent(TQDragMoveEvent * _ev);
  339. virtual void dropEvent(TQDropEvent * _ev);
  340. virtual void dragLeaveEvent(TQDragLeaveEvent * _ev);
  341. /**
  342. * Checks to see if there is a size grip for a highlight range at a given position.
  343. * Note that both X and Y coordinates are UNZOOMED. To translate from a zoomed coordinate (eg. position of a mouse event) to
  344. * an unzoomed coordinate, use Doc::unzoomItX and Doc::unzoomItY. The document object
  345. * can be accessed via view()->doc()
  346. * @param x Unzoomed x coordinate to check
  347. * @param y Unzoomed y coordinate to check
  348. * @return @c true if there is a size grip at the specified position, @c false otherwise.
  349. */
  350. bool highlightRangeSizeGripAt(double x, double y);
  351. private slots:
  352. /**
  353. * Scroll canvas when receiving this signal
  354. */
  355. void slotAutoScroll(const TQPoint &scrollDist);
  356. void doAutoScroll();
  357. void speakCell(TQWidget* w, const TQPoint& p, uint flags);
  358. private:
  359. virtual bool eventFilter( TQObject *o, TQEvent *e );
  360. HBorder* hBorderWidget() const;
  361. VBorder* vBorderWidget() const;
  362. TQScrollBar* horzScrollBar() const;
  363. TQScrollBar* vertScrollBar() const;
  364. /**
  365. * Returns the area of the document currently visible in a painter's
  366. * window, calculated by taking the painter's window() property and
  367. * translating it by the current x and y offset of the Canvas (taking
  368. * the zoom level into account)
  369. */
  370. TQRect painterWindowGeometry( const TQPainter& painter ) const;
  371. /**
  372. * Enables clipping and removes the areas on the canvas widget occupied by embedded objects from
  373. * the clip region. This ensures that subsequent drawing operations using the given painter
  374. * don't paint over the area occupied by embedded objects
  375. */
  376. void clipoutChildren( TQPainter& painter ) const;
  377. /**
  378. * Returns the range of cells which appear in the specified area of the Canvas widget
  379. * For example, cellsInArea( TQRect(0,0,width(),height()) ) returns a range containing all visible cells
  380. *
  381. * @param area The area (in pixels) on the Canvas widget
  382. */
  383. TQRect cellsInArea( const TQRect area ) const;
  384. /**
  385. * Paints the children
  386. */
  387. void paintChildren( TQPainter& painter, TQWMatrix& matrix );
  388. /**
  389. * @see #setLastEditorWithFocus
  390. */
  391. EditorType lastEditorWithFocus() const;
  392. private:
  393. void moveObject( int x, int y, bool key );
  394. void startTheDrag();
  395. /* helpers for the paintUpdates function */
  396. void paintNormalMarker(TQPainter& painter, const KoRect &viewRect);
  397. /**
  398. * Paint the highlighted ranges of cells. When the user is editing a formula in a text box, cells and ranges referenced
  399. * in the formula are highlighted on the canvas.
  400. * @param painter The painter on which to draw the highlighted ranges
  401. * @param viewRect The area currently visible on the canvas
  402. */
  403. void paintHighlightedRanges(TQPainter& painter, const KoRect& viewRect);
  404. /**
  405. * Calculates the visible region on the canvas occupied by a range of cells on the currently active sheet.
  406. * This is used for drawing the thick border around the current selection or highlights around cell range
  407. * references.
  408. * The results do not take into account the current zoom factor of the sheet,
  409. * use Doc::zoomRect on @p visibleRect after calling this function to get a new rectangle taking
  410. * the zoom level into account.
  411. * @param sheetArea The range of cells on the current sheet
  412. * @param visibleRect This is set to the visible region occupied by the given range of cells
  413. *
  414. */
  415. void sheetAreaToVisibleRect( const TQRect& sheetArea,
  416. KoRect& visibleRect );
  417. /**
  418. * Calculates the physical region on the canvas widget occupied by a range of cells on
  419. * the currently active sheet.
  420. * Unlike @see sheetAreaToVisibleRect , scrolling the view does not affect sheetAreaToRect.
  421. *
  422. * @param sheetArea The range of cells on the current sheet
  423. * @param visibleRect This is set to the physical region occupied by the given range of cells
  424. */
  425. void sheetAreaToRect( const TQRect& sheetArea, KoRect& rect );
  426. /**
  427. * helper function in drawing the marker and choose marker.
  428. * @param marker the rectangle that represents the marker being drawn
  429. * (cell coordinates)
  430. * @param viewRect the visible area on the canvas
  431. * @param positions output parameter where the viewable left, top, right, and
  432. * bottom of the marker will be. They are stored in the array
  433. * in that order, and take into account cropping due to part
  434. * of the marker being off screen. This array should have
  435. * at least a size of 4 pre-allocated.
  436. * @param paintSides booleans indicating whether a particular side is visible.
  437. * Again, these are in the order left, top, right, bottom.
  438. * This should be preallocated with a size of at least 4.
  439. */
  440. void retrieveMarkerInfo( const TQRect &marker, const KoRect &viewRect,
  441. double positions[], bool paintSides[] );
  442. bool formatKeyPress( TQKeyEvent * _ev );
  443. /** helper method for formatKeyPress */
  444. bool formatCellByKey(Cell *cell, int key, const TQRect &rect);
  445. void processClickSelectionHandle(TQMouseEvent *event);
  446. void processLeftClickAnchor();
  447. /** current cursor position, be it marker or choose marker */
  448. TQPoint cursorPos();
  449. /**
  450. * returns the rect that needs to be redrawn
  451. */
  452. TQRect moveDirection(KSpread::MoveTo direction, bool extendSelection);
  453. void processEnterKey(TQKeyEvent *event);
  454. void processArrowKey(TQKeyEvent *event);
  455. void processEscapeKey(TQKeyEvent *event);
  456. bool processHomeKey(TQKeyEvent *event);
  457. bool processEndKey(TQKeyEvent *event);
  458. bool processPriorKey(TQKeyEvent *event);
  459. bool processNextKey(TQKeyEvent *event);
  460. void processDeleteKey(TQKeyEvent *event);
  461. void processF2Key(TQKeyEvent *event);
  462. void processF4Key(TQKeyEvent *event);
  463. void processOtherKey(TQKeyEvent *event);
  464. bool processControlArrowKey(TQKeyEvent *event);
  465. void processIMEvent( TQIMEvent * event );
  466. /**
  467. * Used in choose mode. Shows/hides the editor depending on the selected
  468. * sheet. Triggers an update of the regions shown in the CellEditor.
  469. * @see CellEditor::updateChoice()
  470. */
  471. void updateEditor();
  472. /**
  473. * This function sets the paint dirty flag for a @p changedRegion in a
  474. * @p sheet .
  475. * The calculation which cells really should look different with the new
  476. * selection rather than repainting the entire area has to be done before.
  477. * @param sheet the sheet, which contains the cells
  478. * @param changedRegion the cell region to be set as dirty
  479. */
  480. void setSelectionChangePaintDirty(Sheet* sheet, const Region& changedRegion);
  481. private:
  482. class Private;
  483. Private* d;
  484. };
  485. /**
  486. * HBorder
  487. */
  488. class HBorder : public TQWidget
  489. {
  490. Q_OBJECT
  491. public:
  492. HBorder( TQWidget *_parent, Canvas *_canvas, View *_view );
  493. ~HBorder();
  494. int markerColumn() const { return m_iSelectionAnchor; }
  495. void equalizeColumn( double resize );
  496. void updateColumns( int from, int to );
  497. TQSize sizeHint() const;
  498. private slots:
  499. void doAutoScroll();
  500. protected:
  501. virtual void paintEvent ( TQPaintEvent* _ev );
  502. virtual void mousePressEvent( TQMouseEvent* _ev );
  503. virtual void mouseReleaseEvent( TQMouseEvent* _ev );
  504. virtual void mouseDoubleClickEvent( TQMouseEvent* _ev );
  505. virtual void mouseMoveEvent( TQMouseEvent* _ev );
  506. virtual void wheelEvent( TQWheelEvent* );
  507. virtual void focusOutEvent( TQFocusEvent* ev );
  508. virtual void resizeEvent( TQResizeEvent * _ev );
  509. void paintSizeIndicator( int mouseX, bool firstTime );
  510. private:
  511. Canvas *m_pCanvas;
  512. View *m_pView;
  513. TQTimer * m_scrollTimer;
  514. /**
  515. * Flag that inidicates whether the user wants to mark columns.
  516. * The user may mark columns by dragging the mouse around in th XBorder widget.
  517. * If he is doing that right now, this flag is true. Mention that the user may
  518. * also resize columns by dragging the mouse. This case is not covered by this flag.
  519. */
  520. bool m_bSelection;
  521. /**
  522. * The column over which the user pressed the mouse button.
  523. * If the user marks columns in the XBorder widget, then this is the initial
  524. * column on which he pressed the mouse button.
  525. */
  526. int m_iSelectionAnchor;
  527. /**
  528. * Flag that indicates whether the user resizes a column
  529. * The user may resize columns by dragging the mouse around in the HBorder widget.
  530. * If he is doing that right now, this flag is true.
  531. */
  532. bool m_bResize;
  533. /**
  534. * The column over which the user pressed the mouse button.
  535. * The user may resize columns by dragging the mouse around the XBorder widget.
  536. * This is the column over which he pressed the mouse button. This column is going
  537. * to be resized.
  538. */
  539. int m_iResizedColumn;
  540. /**
  541. * Last position of the mouse, when resizing.
  542. */
  543. int m_iResizePos;
  544. /**
  545. * The label used for showing the current size, when resizing
  546. */
  547. TQLabel *m_lSize;
  548. /**
  549. * True when the mouse button is pressed
  550. */
  551. bool m_bMousePressed;
  552. private:
  553. };
  554. /**
  555. * VBorder
  556. */
  557. class VBorder : public TQWidget
  558. {
  559. Q_OBJECT
  560. public:
  561. VBorder( TQWidget *_parent, Canvas *_canvas, View *_view );
  562. ~VBorder();
  563. int markerRow() const { return m_iSelectionAnchor; }
  564. void equalizeRow( double resize );
  565. void updateRows( int from, int to );
  566. TQSize sizeHint() const;
  567. private slots:
  568. void doAutoScroll();
  569. protected:
  570. virtual void paintEvent ( TQPaintEvent* _ev );
  571. virtual void mousePressEvent( TQMouseEvent* _ev );
  572. virtual void mouseReleaseEvent( TQMouseEvent* _ev );
  573. virtual void mouseMoveEvent( TQMouseEvent* _ev );
  574. virtual void mouseDoubleClickEvent( TQMouseEvent* _ev );
  575. virtual void wheelEvent( TQWheelEvent* );
  576. virtual void focusOutEvent( TQFocusEvent* ev );
  577. void paintSizeIndicator( int mouseY, bool firstTime );
  578. private:
  579. Canvas *m_pCanvas;
  580. View *m_pView;
  581. TQTimer * m_scrollTimer;
  582. bool m_bSelection;
  583. int m_iSelectionAnchor;
  584. bool m_bResize;
  585. int m_iResizedRow;
  586. int m_iResizePos;
  587. /**
  588. * The label used for showing the current size, when resizing
  589. */
  590. TQLabel *m_lSize;
  591. /**
  592. * True when the mouse button is pressed
  593. */
  594. bool m_bMousePressed;
  595. };
  596. /**
  597. * Tooltip, which displays the comment and cell content, when it's too short
  598. */
  599. class ToolTip : public TQToolTip
  600. {
  601. public:
  602. ToolTip( Canvas* canvas );
  603. protected:
  604. /**
  605. * @reimp
  606. */
  607. void maybeTip( const TQPoint& p );
  608. private:
  609. Canvas* m_canvas;
  610. };
  611. } // namespace KSpread
  612. #endif // KSPREAD_CANVAS