kspread

manipulator.cpp
1/* This file is part of the KDE project
2 Copyright (C) 2005 Stefan Nikolaus <stefan.nikolaus@kdemail.net>
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 Boston, MA 02110-1301, USA.
18*/
19
20#include <float.h>
21
22#include <tqcolor.h>
23
24#include <kdebug.h>
25#include <tdelocale.h>
26#include <tdemessagebox.h>
27#include <kstaticdeleter.h>
28
29#include "kspread_canvas.h"
30#include "kspread_cell.h"
31#include "kspread_doc.h"
32#include "kspread_map.h"
33#include "kspread_sheet.h"
34#include "kspread_style.h"
35#include "kspread_style_manager.h"
36#include "kspread_undo.h"
37#include "kspread_view.h"
38
39#include "manipulator.h"
40
41using namespace KSpread;
42
43//BEGIN Non-contiguous selection adaption todos
44// TODO Stefan: InsertColumn
45// TODO Stefan: InsertRow
46// TODO Stefan: DeleteColumn
47// TODO Stefan: DeleteRow
48
49// TODO Stefan: SortInc
50// TODO Stefan: SortDec
51// TODO Stefan: FillSelection ?
52
53// TODO Stefan: RemoveComment (works, but not a manipulator yet)
54// TODO Stefan: ClearText (works, but not a manipulator yet)
55// TODO Stefan: ClearValidity (works, but not a manipulator yet)
56// TODO Stefan: Validity (works, but not a manipulator yet)
57// TODO Stefan: Conditional (works, but not a manipulator yet)
58// TODO Stefan: Copy (works, but not a manipulator yet)
59// TODO Stefan: Delete (works, but not a manipulator yet)
60// TODO Stefan: Cut (works, but not a manipulator yet)
61// TODO Stefan: Paste (works, but not a manipulator yet)
62// TODO Stefan: Paste Special (works, but not a manipulator yet)
63// TODO Stefan: Paste with insertion (works, but not a manipulator yet)
64
65// TODO Stefan: more ????
66//END
67
68
69//BEGIN NOTE Stefan: some words on operations
70//
71// 1. SubTotal
72// a) Makes no sense to extend to non-contiguous selections (NCS) as
73// it refers to a change in one column.
74// b) No special undo command available yet.
75//
76// 2. AutoSum
77// a) should insert cell at the end of the selection, if the last
78// is not empty
79// b) opens an editor, if the user's intention is fuzzy -> hard to
80// convert to NCS
81//END
82
83/***************************************************************************
84 class Manipulator
85****************************************************************************/
86
87Manipulator::Manipulator()
88 : Region(),
89 KCommand(),
90 m_sheet(0),
91 m_creation(true),
92 m_reverse(false),
93 m_firstrun(true),
94 m_format(true),
95 m_register(true)
96{
97}
98
99Manipulator::~Manipulator()
100{
101}
102
103void Manipulator::execute()
104{
105 if (!m_sheet)
106 {
107 kdWarning() << "Manipulator::execute(): No explicit m_sheet is set. "
108 << "Manipulating all sheets of the region." << endl;
109 }
110
111 bool successfully = true;
112 successfully = preProcessing();
113 if (!successfully)
114 {
115 kdWarning() << "Manipulator::execute(): preprocessing was not successful!" << endl;
116 return; // do nothing if pre-processing fails
117 }
118
119 m_sheet->doc()->setModified(true);
120 m_sheet->doc()->undoLock ();
121 m_sheet->doc()->emitBeginOperation();
122
123 successfully = true;
124 Region::Iterator endOfList(cells().end());
125 for (Region::Iterator it = cells().begin(); it != endOfList; ++it)
126 {
127 successfully = successfully && process(*it);
128 }
129
130 if (!successfully)
131 {
132 kdWarning() << "Manipulator::execute(): processing was not successful!" << endl;
133 }
134
135 successfully = true;
136 successfully = postProcessing();
137 if (!successfully)
138 {
139 kdWarning() << "Manipulator::execute(): postprocessing was not successful!" << endl;
140 }
141
142 m_sheet->setRegionPaintDirty( *this );
143 m_sheet->doc()->emitEndOperation();
144 m_sheet->doc()->undoUnlock ();
145
146 // add me to undo if needed
147 if (m_firstrun && m_register)
148 {
149 // addCommand itself checks for undo lock
150 m_sheet->doc()->addCommand (this);
151 // if we add something to undo, then the document surely is modified ...
152 m_sheet->doc()->setModified (true);
153 }
154 m_firstrun = false;
155}
156
157void Manipulator::unexecute()
158{
159 m_reverse = !m_reverse;
160 execute();
161 m_reverse = !m_reverse;
162}
163
164bool Manipulator::process(Element* element)
165{
166 Sheet* sheet = m_sheet; // TODO Stefan: element->sheet();
167 if (m_sheet && sheet != m_sheet)
168 {
169 return true;
170 }
171
172 TQRect range = element->rect().normalize();
173 if (m_format && element->isColumn())
174 {
175 for (int col = range.left(); col <= range.right(); ++col)
176 {
177 kdDebug() << "Processing column " << col << "." << endl;
178 ColumnFormat* format = sheet->nonDefaultColumnFormat(col);
179 process(format);
180 // TODO Stefan: process cells with this property
181 }
182 }
183 else if (m_format && element->isRow())
184 {
185 for (int row = range.top(); row <= range.bottom(); ++row)
186 {
187 kdDebug() << "Processing row " << row << "." << endl;
188 RowFormat* format = sheet->nonDefaultRowFormat(row);
189 process(format);
190 // TODO Stefan: process cells with this property
191 }
192 }
193 else
194 {
195 kdDebug() << "Processing cell(s) at " << range << "." << endl;
196 for (int col = range.left(); col <= range.right(); ++col)
197 {
198 sheet->enableScrollBarUpdates(false);
199 for (int row = range.top(); row <= range.bottom(); ++row)
200 {
201 Cell* cell = sheet->cellAt(col, row);
202/* (Tomas) don't force working on obscurring cells - most manipulators don't want this, and those that do can do that manually ... Plus I think that no manipulator should do it anyway ...
203 if ( cell->isPartOfMerged() )
204 {
205 cell = cell->obscuringCells().first();
206 }
207*/
208 //if (testCondition(cell))
209 {
210 if (cell == sheet->defaultCell() && m_creation)
211 {
212 Style* style = sheet->doc()->styleManager()->defaultStyle();
213 cell = new Cell(sheet, style, col, row);
214 sheet->insertCell(cell);
215 }
216
217 if (!process(cell))
218 {
219 return false;
220 }
221 }
222 }
223 sheet->enableScrollBarUpdates(true);
224 sheet->checkRangeVBorder(range.bottom());
225 }
226 sheet->checkRangeHBorder(range.right());
227 }
228 return true;
229}
230
231
232
233/***************************************************************************
234 class FormatManipulator
235****************************************************************************/
236
237FormatManipulator::FormatManipulator()
238{
239 m_properties = 0;
240 // initialize pens with invalid color
241 m_topBorderPen = TQPen(TQColor(), 0, TQt::NoPen);
242 m_bottomBorderPen = TQPen(TQColor(), 0, TQt::NoPen);
243 m_leftBorderPen = TQPen(TQColor(), 0, TQt::NoPen);
244 m_rightBorderPen = TQPen(TQColor(), 0, TQt::NoPen);
245 m_horizontalPen = TQPen(TQColor(), 0, TQt::NoPen);
246 m_verticalPen = TQPen(TQColor(), 0, TQt::NoPen);
247 m_fallDiagonalPen = TQPen(TQColor(), 0, TQt::NoPen);
248 m_goUpDiagonalPen = TQPen(TQColor(), 0, TQt::NoPen);
249}
250
251FormatManipulator::~FormatManipulator()
252{
253 TQValueList<layoutCell>::Iterator it2;
254 for ( it2 = m_lstFormats.begin(); it2 != m_lstFormats.end(); ++it2 )
255 {
256 delete (*it2).l;
257 }
258 m_lstFormats.clear();
259
260 for ( it2 = m_lstRedoFormats.begin(); it2 != m_lstRedoFormats.end(); ++it2 )
261 {
262 delete (*it2).l;
263 }
264 m_lstRedoFormats.clear();
265
266 TQValueList<layoutColumn>::Iterator it3;
267 for ( it3 = m_lstColFormats.begin(); it3 != m_lstColFormats.end(); ++it3 )
268 {
269 delete (*it3).l;
270 }
271 m_lstColFormats.clear();
272
273 for ( it3 = m_lstRedoColFormats.begin(); it3 != m_lstRedoColFormats.end(); ++it3 )
274 {
275 delete (*it3).l;
276 }
277 m_lstRedoColFormats.clear();
278
279 TQValueList<layoutRow>::Iterator it4;
280 for ( it4 = m_lstRowFormats.begin(); it4 != m_lstRowFormats.end(); ++it4 )
281 {
282 delete (*it4).l;
283 }
284 m_lstRowFormats.clear();
285
286 for ( it4 = m_lstRedoRowFormats.begin(); it4 != m_lstRedoRowFormats.end(); ++it4 )
287 {
288 delete (*it4).l;
289 }
290 m_lstRedoRowFormats.clear();
291}
292
293bool FormatManipulator::preProcessing ()
294{
295 if (m_reverse)
296 copyFormat (m_lstRedoFormats, m_lstRedoColFormats, m_lstRedoRowFormats);
297 else
298 copyFormat (m_lstFormats, m_lstColFormats, m_lstRowFormats);
299 return true;
300}
301
302bool FormatManipulator::process (Element *element)
303{
304 // see what is selected; if nothing, take marker position
305 TQRect range = element->rect().normalize();
306
307 if (!m_reverse) {
308
309 int top = range.top();
310 int left = range.left();
311 int bottom = range.bottom();
312 int right = range.right();
313
314 // create cells in rows if complete columns selected
315 Cell * cell;
316 if ( element->isColumn() )
317 {
318 for ( RowFormat * row = m_sheet->firstRow(); row; row = row->next() )
319 {
320 if ( !row->isDefault() )
321 {
322 for ( int col = left; col <= right; ++col )
323 {
324 cell = m_sheet->nonDefaultCell( col, row->row() );
325 }
326 }
327 }
328 }
329
330 // complete rows selected ?
331 if ( element->isRow() )
332 {
333 for ( int row = top; row <= bottom; ++row )
334 {
335 cell = m_sheet->getFirstCellRow( row );
336 while ( cell )
337 {
338 prepareCell( cell );
339 cell = m_sheet->getNextCellRight( cell->column(), row );
340 }
341 RowFormat * rowFormat = m_sheet->nonDefaultRowFormat(row);
342 doWork(rowFormat, row==top, row==bottom, false, false);
343 }
344 }
345 // complete columns selected ?
346 else if ( element->isColumn() )
347 {
348 for ( int col = left; col <= right; ++col )
349 {
350 cell = m_sheet->getFirstCellColumn( col );
351 while ( cell )
352 {
353 prepareCell( cell );
354 cell = m_sheet->getNextCellDown( col, cell->row() );
355 }
356 ColumnFormat * colFormat = m_sheet->nonDefaultColumnFormat( col );
357 doWork(colFormat, false, false, col==left, col==right);
358 }
359
360 for ( RowFormat * rowFormat = m_sheet->firstRow(); rowFormat; rowFormat = rowFormat->next() )
361 {
362 if ( !rowFormat->isDefault() && testCondition( rowFormat ) )
363 {
364 for ( int col = left; col <= right; ++col )
365 {
366 cell = m_sheet->nonDefaultCell(col, rowFormat->row() );
367 doWork(cell->format(), false, false, col==left, col==right );
368 }
369 }
370 }
371 }
372 // cell region selected
373 else
374 {
375 for ( int col = left; col <= right; ++col )
376 {
377 for ( int row = top; row <= bottom; ++row )
378 {
379 cell = m_sheet->nonDefaultCell(col,row);
380 if ( !cell->isPartOfMerged() )
381 {
382 cell->setDisplayDirtyFlag();
383 doWork(cell->format(), row==top, row==bottom, col==left, col==right);
384 cell->clearDisplayDirtyFlag();
385 }
386 }
387 }
388 }
389 }
390 else
391 { // undoing
392 if( element->isColumn() )
393 {
394 TQValueList<layoutColumn>::Iterator it2;
395 for ( it2 = m_lstColFormats.begin(); it2 != m_lstColFormats.end(); ++it2 )
396 {
397 ColumnFormat * col = m_sheet->nonDefaultColumnFormat( (*it2).col );
398 col->copy( *(*it2).l );
399 }
400 }
401 else if( element->isRow() )
402 {
403 TQValueList<layoutRow>::Iterator it2;
404 for ( it2 = m_lstRowFormats.begin(); it2 != m_lstRowFormats.end(); ++it2 )
405 {
406 RowFormat * row = m_sheet->nonDefaultRowFormat( (*it2).row );
407 row->copy( *(*it2).l );
408 }
409 }
410
411 TQValueList<layoutCell>::Iterator it2;
412 for ( it2 = m_lstFormats.begin(); it2 != m_lstFormats.end(); ++it2 )
413 {
414 Cell *cell = m_sheet->nonDefaultCell( (*it2).col,(*it2).row );
415 cell->format()->copy( *(*it2).l );
416 cell->setLayoutDirtyFlag();
417 cell->setDisplayDirtyFlag();
418 m_sheet->updateCell( cell, (*it2).col, (*it2).row );
419 }
420 }
421 return true;
422}
423
424void FormatManipulator::copyFormat(TQValueList<layoutCell> & list,
425 TQValueList<layoutColumn> & listCol,
426 TQValueList<layoutRow> & listRow)
427{
428 TQValueList<layoutCell>::Iterator end = list.end();
429 for (TQValueList<layoutCell>::Iterator it2 = list.begin(); it2 != end; ++it2)
430 {
431 delete (*it2).l;
432 }
433 list.clear();
434
435 Cell * cell;
436 Region::ConstIterator endOfList(cells().constEnd());
437 for (Region::ConstIterator it = cells().constBegin(); it != endOfList; ++it)
438 {
439 TQRect range = (*it)->rect().normalize();
440 int bottom = range.bottom();
441 int right = range.right();
442
443 if ( (*it)->isColumn() )
444 {
445 /* Don't need to go through the loop twice...
446 for (int i = range.left(); i <= right; ++i)
447 {
448 layoutColumn tmplayout;
449 tmplayout.col = i;
450 tmplayout.l = new ColumnFormat( m_sheet, i );
451 tmplayout.l->copy( *(m_sheet->columnFormat( i )) );
452 listCol.append(tmplayout);
453 }
454 */
455 for ( int col = range.left(); col <= right; ++col )
456 {
457 layoutColumn tmplayout;
458 tmplayout.col = col;
459 tmplayout.l = new ColumnFormat( m_sheet, col );
460 tmplayout.l->copy( *(m_sheet->columnFormat( col )) );
461 listCol.append(tmplayout);
462
463 cell = m_sheet->getFirstCellColumn( col );
464 while ( cell )
465 {
466 if ( cell->isPartOfMerged() )
467 {
468 cell = m_sheet->getNextCellDown( col, cell->row() );
469 continue;
470 }
471
472 layoutCell tmplayout;
473 tmplayout.col = col;
474 tmplayout.row = cell->row();
475 tmplayout.l = new Format( m_sheet, 0 );
476 tmplayout.l->copy( *(m_sheet->cellAt( tmplayout.col, tmplayout.row )->format()) );
477 list.append(tmplayout);
478
479 cell = m_sheet->getNextCellDown( col, cell->row() );
480 }
481 }
482 /*
483 Cell * cell = m_sheet->firstCell();
484 for( ; cell; cell = cell->nextCell() )
485 {
486 int col = cell->column();
487 if ( range.left() <= col && right >= col
488 && !cell->isPartOfMerged())
489 {
490 layoutCell tmplayout;
491 tmplayout.col = cell->column();
492 tmplayout.row = cell->row();
493 tmplayout.l = new Format( m_sheet, 0 );
494 tmplayout.l->copy( *(m_sheet->cellAt( tmplayout.col, tmplayout.row )) );
495 list.append(tmplayout);
496 }
497 }
498 */
499 }
500 else if ((*it)->isRow())
501 {
502 for ( int row = range.top(); row <= bottom; ++row )
503 {
504 layoutRow tmplayout;
505 tmplayout.row = row;
506 tmplayout.l = new RowFormat( m_sheet, row );
507 tmplayout.l->copy( *(m_sheet->rowFormat( row )) );
508 listRow.append(tmplayout);
509
510 cell = m_sheet->getFirstCellRow( row );
511 while ( cell )
512 {
513 if ( cell->isPartOfMerged() )
514 {
515 cell = m_sheet->getNextCellRight( cell->column(), row );
516 continue;
517 }
518 layoutCell tmplayout;
519 tmplayout.col = cell->column();
520 tmplayout.row = row;
521 tmplayout.l = new Format( m_sheet, 0 );
522 tmplayout.l->copy( *(m_sheet->cellAt( cell->column(), row )->format()) );
523 list.append(tmplayout);
524
525 cell = m_sheet->getNextCellRight( cell->column(), row );
526 }
527 }
528 /*
529 Cell * cell = m_sheet->firstCell();
530 for( ; cell; cell = cell->nextCell() )
531 {
532 int row = cell->row();
533 if ( range.top() <= row && bottom >= row
534 && !cell->isPartOfMerged())
535 {
536 layoutCell tmplayout;
537 tmplayout.col = cell->column();
538 tmplayout.row = cell->row();
539 tmplayout.l = new Format( m_sheet, 0 );
540 tmplayout.l->copy( *(m_sheet->cellAt( tmplayout.col, tmplayout.row )) );
541 list.append(tmplayout);
542 }
543 }
544 */
545 }
546 else
547 {
548 for ( int row = range.top(); row <= bottom; ++row )
549 for ( int col = range.left(); col <= right; ++col )
550 {
551 Cell * cell = m_sheet->nonDefaultCell( col, row );
552 if ( !cell->isPartOfMerged() )
553 {
554 layoutCell tmplayout;
555 tmplayout.col = col;
556 tmplayout.row = row;
557 tmplayout.l = new Format( m_sheet, 0 );
558 tmplayout.l->copy( *(m_sheet->cellAt( col, row )->format()) );
559 list.append(tmplayout);
560 }
561 }
562 }
563 }
564}
565
566bool FormatManipulator::testCondition(RowFormat* row)
567{
568 for (TQ_UINT32 property = Format::PAlign;
569 property <= Format::PHideFormula;
570 property *= 2)
571 {
572 if (m_properties & property)
573 {
574 return ( row->hasProperty((Format::Properties) property) );
575 }
576 }
577 return false;
578}
579
580void FormatManipulator::doWork(Format* format,
581 bool isTop, bool isBottom,
582 bool isLeft, bool isRight)
583{
584 // SetSelectionFontWorker
585 // SetSelectionSizeWorker
586 if (m_properties & Format::PFont)
587 {
588 if ( !m_font.isEmpty() )
589 format->setTextFontFamily( m_font );
590 if ( m_size > 0 )
591 format->setTextFontSize( m_size );
592 if ( m_italic >= 0 )
593 format->setTextFontItalic( (bool)m_italic );
594 if ( m_bold >= 0 )
595 format->setTextFontBold( (bool)m_bold );
596 if ( m_underline >= 0 )
597 format->setTextFontUnderline( (bool)m_underline );
598 if ( m_strike >= 0 )
599 format->setTextFontStrike( (bool)m_strike );
600 }
601 // SetSelectionAngleWorker
602 if (m_properties & Format::PAngle)
603 {
604 format->setAngle( m_angle );
605 }
606 // SetSelectionTextColorWorker
607 if (m_properties & Format::PTextPen)
608 {
609 format->setTextColor( m_textColor );
610 }
611 // SetSelectionBgColorWorker
612 if (m_properties & Format::PBackgroundColor)
613 {
614 format->setBgColor( m_backgroundColor );
615 }
616 // SetSelectionBorderAllWorker
617 if (m_properties & Format::PLeftBorder)
618 {
619 if (isLeft)
620 {
621 if (m_leftBorderPen.color().isValid())
622 {
623 format->setLeftBorderPen(m_leftBorderPen);
624 }
625 }
626 else
627 {
628 if (m_verticalPen.color().isValid())
629 {
630 format->setLeftBorderPen(m_verticalPen);
631 }
632 }
633 }
634 if (m_properties & Format::PRightBorder)
635 {
636 if (isRight)
637 {
638 if (m_rightBorderPen.color().isValid())
639 {
640 format->setRightBorderPen(m_rightBorderPen);
641 }
642 }
643 else
644 {
645 if (m_verticalPen.color().isValid())
646 {
647 format->setRightBorderPen(m_verticalPen);
648 }
649 }
650 }
651 if (m_properties & Format::PTopBorder)
652 {
653 if (isTop)
654 {
655 if (m_topBorderPen.color().isValid())
656 {
657 format->setTopBorderPen(m_topBorderPen);
658 }
659 }
660 else
661 {
662 if (m_horizontalPen.color().isValid())
663 {
664 format->setTopBorderPen(m_horizontalPen);
665 }
666 }
667 }
668 if (m_properties & Format::PBottomBorder)
669 {
670 if (isBottom)
671 {
672 if (m_bottomBorderPen.color().isValid())
673 {
674 format->setBottomBorderPen(m_bottomBorderPen);
675 }
676 }
677 else
678 {
679 if (m_horizontalPen.color().isValid())
680 {
681 format->setBottomBorderPen(m_horizontalPen);
682 }
683 }
684 }
685 if (m_properties & Format::PFallDiagonal)
686 {
687 format->setFallDiagonalPen(m_fallDiagonalPen);
688 }
689 if (m_properties & Format::PGoUpDiagonal)
690 {
691 format->setGoUpDiagonalPen(m_goUpDiagonalPen);
692 }
693 // SetSelectionAlignWorker
694 if (m_properties & Format::PAlign)
695 {
696 format->setAlign( m_horAlign );
697 }
698 // SetSelectionAlignYWorker
699 if (m_properties & Format::PAlignY)
700 {
701 format->setAlignY( m_verAlign );
702 }
703 if (m_properties & Format::PPrefix)
704 {
705 format->setPrefix(m_prefix);
706 }
707 if (m_properties & Format::PPostfix)
708 {
709 format->setPostfix(m_postfix);
710 }
711 if (m_properties & Format::PBackgroundBrush)
712 {
713 format->setBackGroundBrush(m_backgroundBrush);
714 }
715 if (m_properties & Format::PFloatFormat)
716 {
717 format->setFloatFormat(m_floatFormat);
718 }
719 if (m_properties & Format::PFloatColor)
720 {
721 format->setFloatColor(m_floatColor);
722 }
723 if (m_properties & Format::PMultiRow)
724 {
725 format->setMultiRow(m_multiRow);
726 }
727 if (m_properties & Format::PVerticalText)
728 {
729 format->setVerticalText(m_verticalText);
730 }
731 if (m_properties & Format::PPrecision)
732 {
733 format->setPrecision(m_precision);
734 }
735 if (m_properties & Format::PFormatType)
736 {
737 format->setFormatType(m_formatType);
738 if (m_formatType == Money_format)
739 {
740 format->setCurrency(m_currencyType, m_currencySymbol);
741 }
742 }
743 if (m_properties & Format::PComment)
744 {
745 format->setComment(m_comment);
746 }
747 if (m_properties & Format::PIndent)
748 {
749 format->setIndent(m_indent);
750 }
751 if (m_properties & Format::PDontPrintText)
752 {
753 format->setDontPrintText(m_dontPrintText);
754 }
755 if (m_properties & Format::PCustomFormat)
756 {
757 //TODO
758 }
759 if (m_properties & Format::PNotProtected)
760 {
761 format->setNotProtected(m_notProtected);
762 }
763 if (m_properties & Format::PHideAll)
764 {
765 format->setHideAll(m_hideAll);
766 }
767 if (m_properties & Format::PHideFormula)
768 {
769 format->setHideFormula(m_hideFormula);
770 }
771}
772
773void FormatManipulator::prepareCell(Cell* cell)
774{
775 for (TQ_UINT32 property = Format::PAlign;
776 property <= Format::PHideFormula;
777 property *= 2)
778 {
779 if (m_properties & property)
780 {
781 cell->format()->clearProperty((Format::Properties) property);
782 cell->format()->clearNoFallBackProperties((Format::Properties) property);
783 }
784 }
785}
786
787
788
789/***************************************************************************
790 class MergeManipulator
791****************************************************************************/
792
793MergeManipulator::MergeManipulator()
794 : Manipulator(),
795 m_merge(true),
796 m_mergeHorizontal(false),
797 m_mergeVertical(false),
798 m_unmerger(0)
799{
800}
801
802MergeManipulator::~MergeManipulator()
803{
804 delete m_unmerger;
805}
806
807bool MergeManipulator::process(Element* element)
808{
809 if (element->type() != Element::Range || element->isRow() || element->isColumn())
810 {
811 // TODO Stefan: remove these elements?!
812 return true;
813 }
814
815 // sanity check
816 if( m_sheet->isProtected() || m_sheet->workbook()->isProtected() )
817 {
818 return false;
819 }
820
821 TQRect range = element->rect().normalize();
822 int left = range.left();
823 int right = range.right();
824 int top = range.top();
825 int bottom = range.bottom();
826 int height = range.height();
827 int width = range.width();
828
829 bool doMerge = m_reverse ? (!m_merge) : m_merge;
830
831 if (doMerge)
832 {
833 if (m_mergeHorizontal)
834 {
835 for (int row = top; row <= bottom; ++row)
836 {
837 int rows = 0;
838 for (int col = left; col <= right; ++col)
839 {
840 Cell *cell = m_sheet->cellAt( col, row );
841 if (cell->doesMergeCells())
842 {
843 rows = TQMAX(rows, cell->mergedYCells());
844 cell->mergeCells( col, row, 0, 0 );
845 }
846 }
847 Cell *cell = m_sheet->nonDefaultCell( left, row );
848 if (!cell->isPartOfMerged())
849 {
850 cell->mergeCells( left, row, width - 1, rows );
851 }
852 }
853 }
854 else if (m_mergeVertical)
855 {
856 for (int col = left; col <= right; ++col)
857 {
858 int cols = 0;
859 for (int row = top; row <= bottom; ++row)
860 {
861 Cell *cell = m_sheet->cellAt( col, row );
862 if (cell->doesMergeCells())
863 {
864 cols = TQMAX(cols, cell->mergedXCells());
865 cell->mergeCells( col, row, 0, 0 );
866 }
867 }
868 Cell *cell = m_sheet->nonDefaultCell( col, top );
869 if (!cell->isPartOfMerged())
870 {
871 cell->mergeCells( col, top, cols, height - 1);
872 }
873 }
874 }
875 else
876 {
877 Cell *cell = m_sheet->nonDefaultCell( left, top );
878 cell->mergeCells( left, top, width - 1, height - 1);
879 }
880 }
881 else // dissociate
882 {
883 for (int col = left; col <= right; ++col)
884 {
885 for (int row = top; row <= bottom; ++row)
886 {
887 Cell *cell = m_sheet->cellAt( col, row );
888 if (!cell->doesMergeCells())
889 {
890 continue;
891 }
892 cell->mergeCells( col, row, 0, 0 );
893 }
894 }
895 }
896
897 return true;
898}
899
900TQString MergeManipulator::name() const
901{
902 if (m_merge) // MergeManipulator
903 {
904 if (m_mergeHorizontal)
905 {
906 return i18n("Merge Cells Horizontally");
907 }
908 else if (m_mergeVertical)
909 {
910 return i18n("Merge Cells Vertically");
911 }
912 else
913 {
914 return i18n("Merge Cells");
915 }
916 }
917 return i18n("Dissociate Cells");
918}
919
920bool MergeManipulator::preProcessing()
921{
923 {
924 KMessageBox::information( 0, i18n( "Merging of columns or rows is not supported." ) );
925 return false;
926 }
927
928 if (m_firstrun)
929 {
930 // reduce the region to the region occupied by merged cells
931 Region mergedCells;
932 ConstIterator endOfList = constEnd();
933 for (ConstIterator it = constBegin(); it != endOfList; ++it)
934 {
935 Element* element = *it;
936 TQRect range = element->rect().normalize();
937 int right = range.right();
938 int bottom = range.bottom();
939 for (int row = range.top(); row <= bottom; ++row)
940 {
941 for (int col = range.left(); col <= right; ++col)
942 {
943 Cell *cell = m_sheet->cellAt(col, row);
944 if (cell->doesMergeCells())
945 {
946 TQRect rect(col, row, cell->mergedXCells() + 1, cell->mergedYCells() + 1);
947 mergedCells.add(rect);
948 }
949 }
950 }
951 }
952
953 if (m_merge) // MergeManipulator
954 {
955 // we're in the manipulator's first execution
956 // initialize the undo manipulator
957 m_unmerger = new MergeManipulator();
958 if (!m_mergeHorizontal && !m_mergeVertical)
959 {
960 m_unmerger->setReverse(true);
961 }
962 m_unmerger->setSheet(m_sheet);
963 m_unmerger->setRegisterUndo(false);
964 m_unmerger->add(mergedCells);
965 }
966 else // DissociateManipulator
967 {
968 clear();
969 add(mergedCells);
970 }
971 }
972
973 if (m_merge) // MergeManipulator
974 {
975 if (m_reverse) // dissociate
976 {
977 }
978 else // merge
979 {
980 // Dissociate cells before merging the whole region.
981 // For horizontal/vertical merging the cells stay
982 // as they are. E.g. the region contains a merged cell
983 // occupying two rows. Then the horizontal merge should
984 // keep the height of two rows and extend the merging to the
985 // region's width. In this case the unmerging is done while
986 // processing each region element.
987 if (!m_mergeHorizontal && !m_mergeVertical)
988 {
989 m_unmerger->execute();
990 }
991 }
992 }
993 return true;
994}
995
996bool MergeManipulator::postProcessing()
997{
998 if (m_merge) // MergeManipulator
999 {
1000 if (m_reverse) // dissociate
1001 {
1002 // restore the old merge status
1003 if (m_mergeHorizontal || m_mergeVertical)
1004 {
1005 m_unmerger->execute();
1006 }
1007 else
1008 {
1009 m_unmerger->unexecute();
1010 }
1011 }
1012 }
1013
1014 if (!m_reverse)
1015 {
1016 if (m_sheet->getAutoCalc())
1017 {
1018 m_sheet->recalc();
1019 }
1020 }
1021 else
1022 {
1023 m_sheet->refreshMergedCell();
1024 }
1025 return true;
1026}
1027
1028
1029
1030/***************************************************************************
1031 class DilationManipulator
1032****************************************************************************/
1033
1034DilationManipulator::DilationManipulator()
1035 : Manipulator()
1036{
1037}
1038
1039DilationManipulator::~DilationManipulator()
1040{
1041}
1042
1043void DilationManipulator::execute()
1044{
1045 Region extendedRegion;
1046 ConstIterator end(cells().constEnd());
1047 for (ConstIterator it = cells().constBegin(); it != end; ++it)
1048 {
1049 Element* element = *it;
1050 TQRect area = element->rect().normalize();
1051
1052 ColumnFormat *col;
1053 RowFormat *rl;
1054 //look at if column is hiding.
1055 //if it's hiding refreshing column+1 (or column -1 )
1056 int left = area.left();
1057 int right = area.right();
1058 int top = area.top();
1059 int bottom = area.bottom();
1060
1061 // a merged cells is selected
1062 if (element->type() == Region::Element::Point)
1063 {
1064 Cell* cell = m_sheet->cellAt(left, top);
1065 if (cell->doesMergeCells())
1066 {
1067 // extend to the merged region
1068 // prevents artefacts of the selection rectangle
1069 right += cell->mergedXCells();
1070 bottom += cell->mergedYCells();
1071 }
1072 }
1073
1074 if ( right < KS_colMax )
1075 {
1076 do
1077 {
1078 right++;
1079 col = m_sheet->columnFormat( right );
1080 } while ( col->isHide() && right != KS_colMax );
1081 }
1082 if ( left > 1 )
1083 {
1084 do
1085 {
1086 left--;
1087 col = m_sheet->columnFormat( left );
1088 } while ( col->isHide() && left != 1);
1089 }
1090
1091 if ( bottom < KS_rowMax )
1092 {
1093 do
1094 {
1095 bottom++;
1096 rl = m_sheet->rowFormat( bottom );
1097 } while ( rl->isHide() && bottom != KS_rowMax );
1098 }
1099
1100 if ( top > 1 )
1101 {
1102 do
1103 {
1104 top--;
1105 rl = m_sheet->rowFormat( top );
1106 } while ( rl->isHide() && top != 1);
1107 }
1108
1109 area.setLeft(left);
1110 area.setRight(right);
1111 area.setTop(top);
1112 area.setBottom(bottom);
1113
1114 extendedRegion.add(area, element->sheet());
1115 }
1116 clear();
1117 add(extendedRegion);
1118}
1119
1120void DilationManipulator::unexecute()
1121{
1122 kdError() << "DilationManipulator::unexecute(): "
1123 << "An undo of dilating a region is not possible." << endl;
1124}
1125
1126
1127
1128/***************************************************************************
1129 class ResizeColumnManipulator
1130****************************************************************************/
1131
1132ResizeColumnManipulator::ResizeColumnManipulator()
1133{
1134}
1135
1136ResizeColumnManipulator::~ResizeColumnManipulator()
1137{
1138}
1139
1140bool ResizeColumnManipulator::process(Element* element)
1141{
1142 TQRect range = element->rect().normalize();
1143 for (int col = range.right(); col >= range.left(); --col)
1144 {
1145 ColumnFormat *format = m_sheet->nonDefaultColumnFormat( col );
1146 format->setDblWidth( TQMAX( 2.0, m_reverse ? m_oldSize : m_newSize ) );
1147 }
1148 return true;
1149}
1150
1151
1152
1153/***************************************************************************
1154 class ResizeRowManipulator
1155****************************************************************************/
1156
1157ResizeRowManipulator::ResizeRowManipulator()
1158{
1159}
1160
1161ResizeRowManipulator::~ResizeRowManipulator()
1162{
1163}
1164
1165bool ResizeRowManipulator::process(Element* element)
1166{
1167 TQRect range = element->rect().normalize();
1168 for (int row = range.bottom(); row >= range.top(); --row)
1169 {
1170 RowFormat* rl = m_sheet->nonDefaultRowFormat( row );
1171 rl->setDblHeight( TQMAX( 2.0, m_reverse ? m_oldSize : m_newSize ) );
1172 }
1173 return true;
1174}
1175
1176
1177
1178/***************************************************************************
1179 class AdjustColumnRowManipulator
1180****************************************************************************/
1181
1182AdjustColumnRowManipulator::AdjustColumnRowManipulator()
1183 : Manipulator(),
1184 m_adjustColumn(false),
1185 m_adjustRow(false)
1186{
1187}
1188
1189AdjustColumnRowManipulator::~AdjustColumnRowManipulator()
1190{
1191}
1192
1193bool AdjustColumnRowManipulator::process(Element* element)
1194{
1195 Sheet* sheet = m_sheet; // TODO Stefan: element->sheet();
1196 if (m_sheet && sheet != m_sheet)
1197 {
1198 return true;
1199 }
1200
1201 TQMap<int,double> heights;
1202 TQMap<int,double> widths;
1203 if (m_reverse)
1204 {
1205 heights = m_oldHeights;
1206 widths = m_oldWidths;
1207 }
1208 else
1209 {
1210 heights = m_newHeights;
1211 widths = m_newWidths;
1212 }
1213
1214 TQRect range = element->rect().normalize();
1215 if (m_adjustColumn)
1216 {
1217 if (element->isRow())
1218 {
1219 for (int row = range.top(); row <= range.bottom(); ++row)
1220 {
1221 Cell* cell = sheet->getFirstCellRow( row );
1222 while ( cell )
1223 {
1224 int col = cell->column();
1225 if ( !cell->isEmpty() && !cell->isObscured())
1226 {
1227 if (widths.contains(col) && widths[col] != -1.0)
1228 {
1229 ColumnFormat* format = sheet->nonDefaultColumnFormat(col);
1230 if ( kAbs(format->dblWidth() - widths[col] ) > DBL_EPSILON )
1231 {
1232 format->setDblWidth( TQMAX( 2.0, widths[col] ) );
1233 }
1234 }
1235 }
1236 cell = sheet->getNextCellRight(col, row);
1237 }
1238 }
1239 }
1240 else
1241 {
1242 for (int col = range.left(); col <= range.right(); ++col)
1243 {
1244 if (widths.contains(col) && widths[col] != -1.0)
1245 {
1246 ColumnFormat* format = sheet->nonDefaultColumnFormat(col);
1247 if ( kAbs(format->dblWidth() - widths[col] ) > DBL_EPSILON )
1248 {
1249 format->setDblWidth( TQMAX( 2.0, widths[col] ) );
1250 }
1251 }
1252 }
1253 }
1254 }
1255 if (m_adjustRow)
1256 {
1257 if (element->isColumn())
1258 {
1259 for (int col = range.left(); col <= range.right(); ++col)
1260 {
1261 Cell* cell = sheet->getFirstCellColumn( col );
1262 while ( cell )
1263 {
1264 int row = cell->row();
1265 if ( !cell->isEmpty() && !cell->isObscured())
1266 {
1267 if (heights.contains(row) && heights[row] != -1.0)
1268 {
1269 RowFormat* format = sheet->nonDefaultRowFormat(row);
1270 if ( kAbs(format->dblHeight() - heights[row] ) > DBL_EPSILON )
1271 {
1272 format->setDblHeight( TQMAX( 2.0, heights[row] ) );
1273 }
1274 }
1275 }
1276 cell = sheet->getNextCellDown( col, row );
1277 }
1278 }
1279 }
1280 else
1281 {
1282 for (int row = range.top(); row <= range.bottom(); ++row)
1283 {
1284 if (heights.contains(row) && heights[row] != -1.0)
1285 {
1286 RowFormat* format = sheet->nonDefaultRowFormat(row);
1287 if ( kAbs(format->dblHeight() - heights[row] ) > DBL_EPSILON )
1288 {
1289 format->setDblHeight( TQMAX( 2.0, heights[row] ) );
1290 }
1291 }
1292 }
1293 }
1294 }
1295 return true;
1296}
1297
1298bool AdjustColumnRowManipulator::preProcessing()
1299{
1300 if (m_reverse)
1301 {
1302 }
1303 else
1304 {
1305 if (!m_newHeights.isEmpty() || !m_newWidths.isEmpty())
1306 {
1307 return true;
1308 }
1309// createUndo();
1310
1311 ConstIterator endOfList(cells().end());
1312 for (ConstIterator it = cells().begin(); it != endOfList; ++it)
1313 {
1314 Element* element = *it;
1315 TQRect range = element->rect().normalize();
1316 if (element->isColumn())
1317 {
1318 for (int col = range.left(); col <= range.right(); ++col)
1319 {
1320 Cell* cell = m_sheet->getFirstCellColumn( col );
1321 while ( cell )
1322 {
1323 int row = cell->row();
1324 if (m_adjustColumn)
1325 {
1326 if (!m_newWidths.contains(col))
1327 {
1328 m_newWidths[col] = -1.0;
1329 ColumnFormat* format = m_sheet->columnFormat(col);
1330 m_oldWidths[col] = format->dblWidth();
1331 }
1332 if (!cell->isEmpty() && !cell->isObscured())
1333 {
1334 m_newWidths[col] = TQMAX(adjustColumnHelper(cell, col, row),
1335 m_newWidths[col] );
1336 }
1337 }
1338 if (m_adjustRow)
1339 {
1340 if (!m_newHeights.contains(row))
1341 {
1342 m_newHeights[row] = -1.0;
1343 RowFormat* format = m_sheet->rowFormat(row);
1344 m_oldHeights[row] = format->dblHeight();
1345 }
1346 if (!cell->isEmpty() && !cell->isObscured())
1347 {
1348 m_newHeights[row] = TQMAX(adjustRowHelper(cell, col, row),
1349 m_newHeights[row]);
1350 }
1351 }
1352 cell = m_sheet->getNextCellDown( col, row );
1353 }
1354 }
1355 }
1356 else if (element->isRow())
1357 {
1358 for (int row = range.top(); row <= range.bottom(); ++row)
1359 {
1360 Cell* cell = m_sheet->getFirstCellRow( row );
1361 while ( cell )
1362 {
1363 int col = cell->column();
1364 if (m_adjustColumn)
1365 {
1366 if (!m_newWidths.contains(col))
1367 {
1368 m_newWidths[col] = -1.0;
1369 ColumnFormat* format = m_sheet->columnFormat(col);
1370 m_oldWidths[col] = format->dblWidth();
1371 }
1372 if (cell != m_sheet->defaultCell() && !cell->isEmpty() && !cell->isObscured())
1373 {
1374 m_newWidths[col] = TQMAX(adjustColumnHelper(cell, col, row),
1375 m_newWidths[col] );
1376 }
1377 }
1378 if (m_adjustRow)
1379 {
1380 if (!m_newHeights.contains(row))
1381 {
1382 m_newHeights[row] = -1.0;
1383 RowFormat* format = m_sheet->rowFormat(row);
1384 m_oldHeights[row] = format->dblHeight();
1385 }
1386 if (cell != m_sheet->defaultCell() && !cell->isEmpty() && !cell->isObscured())
1387 {
1388 m_newHeights[row] = TQMAX(adjustRowHelper(cell, col, row),
1389 m_newHeights[row]);
1390 }
1391 }
1392 cell = m_sheet->getNextCellRight(col, row);
1393 }
1394 }
1395 }
1396 else
1397 {
1398 Cell* cell;
1399 for (int col = range.left(); col <= range.right(); ++col)
1400 {
1401 for ( int row = range.top(); row <= range.bottom(); ++row )
1402 {
1403 cell = m_sheet->cellAt( col, row );
1404 if (m_adjustColumn)
1405 {
1406 if (!m_newWidths.contains(col))
1407 {
1408 m_newWidths[col] = -1.0;
1409 ColumnFormat* format = m_sheet->columnFormat(col);
1410 m_oldWidths[col] = format->dblWidth();
1411 }
1412 if (cell != m_sheet->defaultCell() && !cell->isEmpty() && !cell->isObscured())
1413 {
1414 m_newWidths[col] = TQMAX(adjustColumnHelper(cell, col, row),
1415 m_newWidths[col] );
1416 }
1417 }
1418 if (m_adjustRow)
1419 {
1420 if (!m_newHeights.contains(row))
1421 {
1422 m_newHeights[row] = -1.0;
1423 RowFormat* format = m_sheet->rowFormat(row);
1424 m_oldHeights[row] = format->dblHeight();
1425 }
1426 if (cell != m_sheet->defaultCell() && !cell->isEmpty() && !cell->isObscured())
1427 {
1428 m_newHeights[row] = TQMAX(adjustRowHelper(cell, col, row),
1429 m_newHeights[row]);
1430 }
1431 }
1432 }
1433 }
1434 }
1435 }
1436 }
1437 return true;
1438}
1439
1440double AdjustColumnRowManipulator::adjustColumnHelper(Cell* cell, int col, int row )
1441{
1442 double long_max = 0.0;
1443 cell->calculateTextParameters( m_sheet->painter(), col, row );
1444 if ( cell->textWidth() > long_max )
1445 {
1446 double indent = 0.0;
1447 Format::Align alignment = cell->format()->align(cell->column(), cell->row());
1448 if (alignment == Format::Undefined)
1449 {
1450 if (cell->value().isNumber() || cell->isDate() || cell->isTime())
1451 {
1452 alignment = Format::Right;
1453 }
1454 else
1455 {
1456 alignment = Format::Left;
1457 }
1458 }
1459
1460 if (alignment == Format::Left)
1461 {
1462 indent = cell->format()->getIndent( cell->column(), cell->row() );
1463 }
1464 long_max = indent + cell->textWidth()
1465 + cell->format()->leftBorderWidth( cell->column(), cell->row() )
1466 + cell->format()->rightBorderWidth( cell->column(), cell->row() );
1467 }
1468
1469 // add 4 because long_max is the length of the text
1470 // but column has borders
1471 if ( long_max == 0.0 )
1472 {
1473 return -1.0;
1474 }
1475 else
1476 {
1477 return long_max + 4;
1478 }
1479}
1480
1481double AdjustColumnRowManipulator::adjustRowHelper(Cell* cell, int col, int row)
1482{
1483 double long_max = 0.0;
1484 cell->calculateTextParameters( m_sheet->painter(), col, row);
1485 if ( cell->textHeight() > long_max )
1486 {
1487 long_max = cell->textHeight()
1488 + cell->format()->topBorderWidth(col, row)
1489 + cell->format()->bottomBorderWidth(col, row);
1490 }
1491
1492 // add 1 because long_max is the height of the text
1493 // but row has borders
1494 if ( long_max == 0.0 )
1495 {
1496 return -1.0;
1497 }
1498 else
1499 {
1500 return long_max + 1;
1501 }
1502}
1503
1504TQString AdjustColumnRowManipulator::name() const
1505{
1506 if (m_adjustColumn && m_adjustRow)
1507 {
1508 return i18n("Adjust Columns/Rows");
1509 }
1510 else if (m_adjustColumn)
1511 {
1512 return i18n("Adjust Columns");
1513 }
1514 else
1515 {
1516 return i18n("Adjust Rows");
1517 }
1518}
1519
1520
1521
1522/***************************************************************************
1523 class HideShowManipulator
1524****************************************************************************/
1525
1526HideShowManipulator::HideShowManipulator()
1527 : m_manipulateColumns(false),
1528 m_manipulateRows(false)
1529{
1530}
1531
1532HideShowManipulator::~HideShowManipulator()
1533{
1534}
1535
1536bool HideShowManipulator::process(Element* element)
1537{
1538 TQRect range = element->rect().normalize();
1539 if (m_manipulateColumns)
1540 {
1541 for (int col = range.left(); col <= range.right(); ++col)
1542 {
1543 ColumnFormat* format = m_sheet->nonDefaultColumnFormat(col);
1544 format->setHide(!m_reverse);
1545 }
1546 }
1547 if (m_manipulateRows)
1548 {
1549 for (int row = range.top(); row <= range.bottom(); ++row)
1550 {
1551 RowFormat* format = m_sheet->nonDefaultRowFormat(row);
1552 format->setHide(!m_reverse);
1553 }
1554 }
1555 return true;
1556}
1557
1558bool HideShowManipulator::preProcessing()
1559{
1560 Region region;
1561 ConstIterator endOfList = cells().constEnd();
1562 for (ConstIterator it = cells().constBegin(); it != endOfList; ++it)
1563 {
1564 if (m_reverse)
1565 {
1566 TQRect range = (*it)->rect().normalize();
1567 if (m_manipulateColumns)
1568 {
1569 if (range.left() > 1)
1570 {
1571 int col;
1572 for (col = 1; col < range.left(); ++col)
1573 {
1574 ColumnFormat* format = m_sheet->columnFormat(col);
1575 if (!format->isHide())
1576 {
1577 break;
1578 }
1579 }
1580 if (col == range.left())
1581 {
1582 region.add(TQRect(1, 1, range.left()-1, KS_rowMax));
1583 }
1584 }
1585 for (int col = range.left(); col <= range.right(); ++col)
1586 {
1587 ColumnFormat* format = m_sheet->columnFormat(col);
1588 if (format->isHide())
1589 {
1590 region.add(TQRect(col, 1, 1, KS_rowMax));
1591 }
1592 }
1593 }
1594 if (m_manipulateRows)
1595 {
1596 if (range.top() > 1)
1597 {
1598 int row;
1599 for (row = 1; row < range.top(); ++row)
1600 {
1601 RowFormat* format = m_sheet->rowFormat(row);
1602 if (!format->isHide())
1603 {
1604 break;
1605 }
1606 }
1607 if (row == range.top())
1608 {
1609 region.add(TQRect(1, 1, KS_colMax, range.top()-1));
1610 }
1611 }
1612 for (int row = range.top(); row <= range.bottom(); ++row)
1613 {
1614 RowFormat* format = m_sheet->rowFormat(row);
1615 if (format->isHide())
1616 {
1617 region.add(TQRect(1, row, KS_colMax, 1));
1618 }
1619 }
1620 }
1621 }
1622
1623 if (((*it)->isRow() && m_manipulateColumns) ||
1624 ((*it)->isColumn() && m_manipulateRows))
1625 {
1626/* KMessageBox::error( this, i18n( "Area is too large." ) );*/
1627 return false;
1628 }
1629 }
1630
1631 if (m_reverse)
1632 {
1633 clear();
1634 add(region);
1635 }
1636
1637 return true;
1638}
1639
1640bool HideShowManipulator::postProcessing()
1641{
1642 if (m_manipulateColumns)
1643 {
1644 m_sheet->emitHideColumn();
1645 }
1646 if (m_manipulateRows)
1647 {
1648 m_sheet->emitHideRow();
1649 }
1650
1651 return true;
1652}
1653
1654TQString HideShowManipulator::name() const
1655{
1656 TQString name;
1657 if (m_reverse)
1658 {
1659 name = "Show ";
1660 }
1661 else
1662 {
1663 name = "Hide ";
1664 }
1665 if (m_manipulateColumns)
1666 {
1667 name += "Columns";
1668 }
1669 if (m_manipulateColumns && m_manipulateRows)
1670 {
1671 name += "/";
1672 }
1673 if (m_manipulateRows)
1674 {
1675 name += "Rows";
1676 }
1677 return name;
1678}
1679
1680
1681
1682
1683/***************************************************************************
1684 class ManipulatorManager
1685****************************************************************************/
1686
1687ManipulatorManager* ManipulatorManager::m_self = 0;
1688static KStaticDeleter<ManipulatorManager> staticManipulatorManagerDeleter;
1689
1690ManipulatorManager* ManipulatorManager::self()
1691{
1692 if (!m_self)
1693 {
1694 staticManipulatorManagerDeleter.setObject(m_self, new ManipulatorManager());
1695 }
1696 return m_self;
1697}
1698
1699ManipulatorManager::ManipulatorManager()
1700{
1701}
1702
1703ManipulatorManager::~ManipulatorManager()
1704{
1705}
1706
1707Manipulator* ManipulatorManager::create(const TQString& type)
1708{
1709 if (type == "bgcolor")
1710 {
1711 kdDebug() << "Background color manipulator created." << endl;
1712// return new FontColorManipulator();
1713 }
1714 else if (type == "textcolor")
1715 {
1716 kdDebug() << "Text color manipulator created." << endl;
1717// return new FontColorManipulator();
1718 }
1719
1720 // no manipulator of this type found
1721 kdError() << "Unknown manipulator!" << endl;
1722 return 0;
1723}
For every cell in the spread sheet there is a Cell object.
void setLayoutDirtyFlag(bool format=false)
Causes the format to be recalculated when the cell is drawn next time.
int row() const
Returns the cell's row.
const Value value() const
Returns the value that this cell holds.
bool isObscured() const
bool doesMergeCells() const
int column() const
Returns the cell's column.
double textHeight() const
return height of the text
bool isEmpty() const
Returns true if this cell has no content, i.e no text and no formula.
void calculateTextParameters(TQPainter &painter, int _col, int _row)
Calculates the text parameters stored in cell Applies font to use to painter.
int mergedXCells() const
Format * format() const
Returns the format object of this cell.
void mergeCells(int _col, int _row, int _x, int _y)
Merge a number of cells, i.e.
bool isPartOfMerged() const
If this cell is part of a merged cell, then the marker may never reside on this cell.
bool isDate() const
returns true, if cell format is of date type or content is a date
bool isTime() const
returns true, if cell format is of time type or content is a time
int mergedYCells() const
double textWidth() const
return width of the text
ManipulatorManager.
bool format()
Is this a formatting manipulator ?
Definition manipulator.h:81
Base class for region elements, which can be points or ranges.
Definition region.h:325
The one for all class for points and ranges.
Definition region.h:44
Element * add(const TQPoint &point, Sheet *sheet=0)
Adds the point point to this region.
Definition region.cpp:245
virtual void clear()
Deletes all elements of the region.
Definition region.cpp:600
TQValueList< Element * > & cells() const
Definition region.cpp:649
Region()
Constructor.
Definition region.cpp:54
bool isColumnOrRowSelected() const
Definition region.cpp:557
bool isNumber() const
Returns true if the type of this value is either integer or floating-point.
@ Format
Format only.
The KSpread namespace.
Definition commands.h:39