kspread

kspread_dlg_paperlayout.cpp
1/* This file is part of the KDE project
2 Copyright (C) 2005 Raphael Langerhorst <raphael.langerhorst@kdemail.net>
3 (C) 2002-2003 Ariya Hidayat <ariya@kde.org>
4 (C) 2002-2003 Norbert Andres <nandres@web.de>
5 (C) 2002-2003 Philipp Mueller <philipp.mueller@gmx.de>
6 (C) 2002 Laurent Montel <montel@kde.org>
7
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Library General Public
10 License as published by the Free Software Foundation; either
11 version 2 of the License, or (at your option) any later version.
12
13 This library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Library General Public License for more details.
17
18 You should have received a copy of the GNU Library General Public License
19 along with this library; see the file COPYING.LIB. If not, write to
20 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
22*/
23
24#include "kspread_dlg_paperlayout.h"
25#include <kspread_doc.h>
26#include "kspread_map.h"
27#include "kspread_sheet.h"
28#include "kspread_sheetprint.h"
29#include <kspread_undo.h>
30#include <kspread_util.h>
31#include <kspread_view.h>
32#include <selection.h>
33
34#include <tqcheckbox.h>
35#include <tqlabel.h>
36#include <tqlineedit.h>
37#include <tqradiobutton.h>
38#include <tqbuttongroup.h>
39#include <tqcombobox.h>
40#include <tqlayout.h>
41#include <tqhgroupbox.h>
42
43#include <tdeapplication.h>
44#include <kdebug.h>
45#include <tdelocale.h>
46#include <tdemessagebox.h>
47
48using namespace KSpread;
49
50PaperLayout::PaperLayout( TQWidget * parent, const char * name,
51 const KoPageLayout & layout,
52 const KoHeadFoot & headfoot,
53 int tabs, KoUnit::Unit unit,
54 Sheet * sheet, View * view)
55 : KoPageLayoutDia( parent, name, layout, headfoot, tabs, unit, false /*no modal*/),
56 m_pSheet( sheet ),
57 m_pView( view )
58{
59 initTab();
60 connect(view->selectionInfo(), TQ_SIGNAL(changed(const Region&)),
61 this, TQ_SLOT(slotSelectionChanged()));
62 tqApp->installEventFilter( this );
63 m_focus= 0L;
64}
65
66void PaperLayout::initTab()
67{
68 SheetPrint* print = m_pSheet->print();
69
70 TQWidget *tab = addPage(i18n( "Options" ));
71 TQVBoxLayout *vbox = new TQVBoxLayout( tab, KDialog::marginHint(), KDialog::spacingHint() );
72
73 pApplyToAll = new TQCheckBox ( i18n( "&Apply to all sheets" ), tab );
74 pApplyToAll->setChecked( print->printGrid() );
75 vbox->addWidget( pApplyToAll );
76
77 //Range properties
78 initGeneralOptions( tab, vbox );
79
80 //Range properties
81 initRanges( tab, vbox );
82
83 //Scale properties
84 initScaleOptions( tab, vbox );
85
86 vbox->addStretch( 1 );
87}
88
89void PaperLayout::initGeneralOptions( TQWidget * tab, TQVBoxLayout * vbox )
90{
91 SheetPrint* print = m_pSheet->print();
92
93 TQGroupBox *group = new TQGroupBox( i18n("General Options"), tab );
94 TQGridLayout *l = new TQGridLayout( group, 2, 3 );
95
96 pPrintGrid = new TQCheckBox ( i18n("Print &grid"), group );
97 pPrintGrid->setChecked( print->printGrid() );
98 l->addWidget( pPrintGrid, 0, 0 );
99
100 pPrintCommentIndicator = new TQCheckBox ( i18n("Print &comment indicator"), group );
101 pPrintCommentIndicator->setChecked( print->printCommentIndicator() );
102 l->addWidget( pPrintCommentIndicator, 0, 1 );
103
104 pPrintFormulaIndicator = new TQCheckBox ( i18n("Print &formula indicator"), group );
105 pPrintFormulaIndicator->setChecked( print->printFormulaIndicator() );
106 l->addWidget( pPrintFormulaIndicator, 0, 2 );
107
108 pPrintObjects = new TQCheckBox ( i18n("Print &objects"), group );
109 pPrintObjects->setChecked( print->printObjects() );
110 l->addWidget( pPrintObjects, 1, 0 );
111
112 pPrintCharts = new TQCheckBox ( i18n("Print &charts"), group );
113 pPrintCharts->setChecked( print->printCharts() );
114 l->addWidget( pPrintCharts, 1, 1 );
115
116// Not used yet unless someone implement some kind of drawing object
117// pPrintGraphics = new TQCheckBox ( i18n("Print &drawings"), group );
118// pPrintGraphics->setChecked( print->printGraphics() );
119// l->addWidget( pPrintGraphics, 1, 2 );
120
121 vbox->addWidget( group );
122}
123
124void PaperLayout::initRanges( TQWidget * tab, TQVBoxLayout * vbox )
125{
126 SheetPrint* print = m_pSheet->print();
127
128 TQGroupBox *rangeGroup = new TQGroupBox( i18n("Ranges"), tab );
129 rangeGroup->setColumnLayout( 0, TQt::Vertical );
130 rangeGroup->setMargin( KDialog::marginHint() );
131 vbox->addWidget( rangeGroup );
132
133 TQGridLayout *grid = new TQGridLayout( rangeGroup->layout(), 3, 2, KDialog::spacingHint() );
134
135 TQLabel *pPrintRange = new TQLabel ( i18n("Print range:"), rangeGroup );
136 grid->addWidget( pPrintRange, 0, 0 );
137
138 ePrintRange = new TQLineEdit( rangeGroup );
139 ePrintRange->setText( util_rangeName( print->printRange() ) );
140 grid->addWidget( ePrintRange, 0, 1 );
141
142 TQLabel *pRepeatCols = new TQLabel ( i18n("Repeat columns on each page:"), rangeGroup );
143 grid->addWidget( pRepeatCols, 1, 0 );
144
145 eRepeatCols = new TQLineEdit( rangeGroup );
146 if ( print->printRepeatColumns().first != 0 )
147 eRepeatCols->setText( Cell::columnName( print->printRepeatColumns().first ) + ":" +
148 Cell::columnName( print->printRepeatColumns().second ) );
149 grid->addWidget( eRepeatCols, 1, 1 );
150
151 TQLabel *pRepeatRows = new TQLabel ( i18n("Repeat rows on each page:"), rangeGroup );
152 grid->addWidget( pRepeatRows, 2, 0 );
153
154 eRepeatRows = new TQLineEdit( rangeGroup );
155 if ( print->printRepeatRows().first != 0 )
156 eRepeatRows->setText( TQString().setNum( print->printRepeatRows().first ) +
157 ":" +
158 TQString().setNum( print->printRepeatRows().second ) );
159 grid->addWidget( eRepeatRows, 2, 1 );
160
161 grid->addColSpacing( 0, pPrintRange->width() );
162 grid->addColSpacing( 0, pRepeatRows->width() );
163 grid->addColSpacing( 0, pRepeatCols->width() );
164 grid->addColSpacing( 1, ePrintRange->width() );
165 grid->addColSpacing( 1, eRepeatRows->width() );
166 grid->addColSpacing( 1, eRepeatCols->width() );
167
168 grid->addRowSpacing( 0, pPrintRange->height() );
169 grid->addRowSpacing( 0, ePrintRange->height() );
170 grid->addRowSpacing( 1, pRepeatRows->height() );
171 grid->addRowSpacing( 1, eRepeatRows->height() );
172 grid->addRowSpacing( 2, pRepeatCols->height() );
173 grid->addRowSpacing( 2, eRepeatCols->height() );
174}
175
176void PaperLayout::initScaleOptions( TQWidget * tab, TQVBoxLayout * vbox )
177{
178 SheetPrint* print = m_pSheet->print();
179
180 TQButtonGroup *zoomGroup = new TQButtonGroup( i18n("Scale Printout"), tab );
181 zoomGroup->setColumnLayout( 0, TQt::Vertical );
182 zoomGroup->setMargin( KDialog::marginHint() );
183 vbox->addWidget( zoomGroup );
184
185 TQGridLayout *grid = new TQGridLayout( zoomGroup->layout(), 2, 6,
186 KDialog::spacingHint() );
187
188 m_rScalingZoom = new TQRadioButton ( i18n("Zoom:"), zoomGroup );
189 grid->addWidget( m_rScalingZoom, 0, 0 );
190
191 m_cZoom = new TQComboBox( true, zoomGroup, "Zoom" );
192 grid->addMultiCellWidget( m_cZoom, 0, 0, 1, 5, TQt::AlignLeft );
193
194 TQStringList lst;
195 for( int i = 5; i < 500; i += 5 )
196 {
197 lst.append( TQString( i18n( "%1%" ) ).arg( i ) );
198 if( tqRound( print->zoom() * 100 ) > i &&
199 tqRound( print->zoom() * 100 ) < i + 5 )
200 {
201 lst.append( TQString( i18n( "%1%" ) ).arg( tqRound( print->zoom() * 100 ) ) );
202 }
203 }
204 m_cZoom->insertStringList( lst );
205
206 int number_of_entries = m_cZoom->count();
207 TQString string = TQString( i18n( "%1%" ) ).arg( tqRound( print->zoom() * 100 ) );
208 for (int i = 0; i < number_of_entries ; i++)
209 {
210 if ( string == (TQString) m_cZoom->text(i) )
211 {
212 m_cZoom->setCurrentItem( i );
213 break;
214 }
215 }
216
217 m_rScalingLimitPages = new TQRadioButton ( i18n("Limit pages:"), zoomGroup );
218 grid->addWidget( m_rScalingLimitPages, 1, 0 );
219
220 TQLabel *pLimitPagesX = new TQLabel ( i18n("X:"), zoomGroup );
221 grid->addWidget( pLimitPagesX, 1, 1 );
222
223 m_cLimitPagesX = new TQComboBox( true, zoomGroup, "pagesX" );
224 grid->addWidget( m_cLimitPagesX, 1, 2 );
225
226 TQStringList lstX;
227 lstX.append( i18n( "No Limit" ) );
228 for( int i = 1; i <= 20; i += 1 )
229 {
230 lstX.append( TQString( "%1" ).arg( i ) );
231 }
232 if( print->pageLimitX() > 20 )
233 {
234 lstX.append( TQString( "%1" ).arg( print->pageLimitX() ) );
235 }
236 m_cLimitPagesX->insertStringList( lstX );
237
238 if ( print->pageLimitX() <= 20 )
239 m_cLimitPagesX->setCurrentItem( print->pageLimitX() );
240 else
241 m_cLimitPagesX->setCurrentItem( 21 );
242
243 TQLabel *pLimitPagesY = new TQLabel ( i18n("Y:"), zoomGroup );
244 grid->addWidget( pLimitPagesY, 1, 3 );
245
246 m_cLimitPagesY = new TQComboBox( true, zoomGroup, "pagesY" );
247 grid->addWidget( m_cLimitPagesY, 1, 4 );
248
249 TQStringList lstY;
250 lstY.append( i18n( "No Limit" ) );
251 for( int i = 1; i <= 20; i += 1 )
252 {
253 lstY.append( TQString( "%1" ).arg( i ) );
254 }
255 if( print->pageLimitY() > 20 )
256 {
257 lstY.append( TQString( "%1" ).arg( print->pageLimitY() ) );
258 }
259 m_cLimitPagesY->insertStringList( lstY );
260
261 if ( print->pageLimitY() <= 20 )
262 m_cLimitPagesY->setCurrentItem( print->pageLimitY() );
263 else
264 m_cLimitPagesY->setCurrentItem( 21 );
265
266 if ( print->pageLimitY() != 0 || print->pageLimitX() != 0 )
267 {
268 m_rScalingLimitPages->setChecked( true );
269 }
270 else
271 {
272 m_rScalingZoom->setChecked( true );
273 }
274
275 connect( m_cZoom, TQ_SIGNAL( activated( int ) ), this, TQ_SLOT( slotChooseZoom( int ) ) );
276 connect( m_cLimitPagesX, TQ_SIGNAL( activated( int ) ), this, TQ_SLOT( slotChoosePageLimit( int ) ) );
277 connect( m_cLimitPagesY, TQ_SIGNAL( activated( int ) ), this, TQ_SLOT( slotChoosePageLimit( int ) ) );
278}
279
280void PaperLayout::slotChooseZoom( int /*index*/ )
281{
282 m_rScalingZoom->setChecked( true );
283}
284
285void PaperLayout::slotChoosePageLimit( int /*index*/ )
286{
287 m_rScalingLimitPages->setChecked( true );
288}
289
290void PaperLayout::slotOk()
291{
292 if ( !m_pSheet->doc()->undoLocked() )
293 {
294 UndoAction* undo = new UndoPaperLayout( m_pSheet->doc(), m_pSheet );
295 m_pSheet->doc()->addCommand( undo );
296 }
297
298 // get new values for borders
299 Map * map = 0;
300 Sheet * sheet = 0;
301
302 if ( pApplyToAll->isChecked() )
303 map = m_pSheet->doc()->map();
304
305 if ( map )
306 sheet = map->firstSheet();
307 else
308 sheet = m_pSheet;
309
310 m_pView->doc()->emitBeginOperation( false );
311 while ( sheet )
312 {
313 SheetPrint *print = sheet->print();
314
315 KoPageLayout pl = layout();
316 KoHeadFoot hf = headFoot();
317 KoUnit::Unit unit = sheet->doc()->unit();
318 print->setPrintGrid( pPrintGrid->isChecked() );
319 print->setPrintCommentIndicator( pPrintCommentIndicator->isChecked() );
320 print->setPrintFormulaIndicator( pPrintFormulaIndicator->isChecked() );
321 print->setPrintObjects( pPrintObjects->isChecked() );
322 print->setPrintCharts( pPrintCharts->isChecked() );
323// print->setPrintGraphics( pPrintGraphics->isChecked() );
324 TQString tmpPrintRange = ePrintRange->text();
325 TQString tmpRepeatCols = eRepeatCols->text();
326 TQString tmpRepeatRows = eRepeatRows->text();
327 if ( tmpPrintRange.isEmpty() )
328 {
329 print->setPrintRange( TQRect( TQPoint( 1, 1 ), TQPoint( KS_colMax, KS_rowMax ) ) );
330 }
331 else
332 {
333 bool error = true;
334 int first = tmpPrintRange.find(":");
335 if ( ( first != -1 ) && ( (int)tmpPrintRange.length() > first ) )
336 {
337 Point point1 ( tmpPrintRange.left( first ) );
338 if ( point1.isValid() )
339 {
340 Point point2 ( tmpPrintRange.mid( first+1 ) );
341 if ( point2.isValid() )
342 {
343 error = false;
344 print->setPrintRange ( TQRect( TQPoint( TQMIN( point1.pos().x(), point2.pos().x() ),
345 TQMIN( point1.pos().y(), point2.pos().y() ) ),
346 TQPoint( TQMAX( point1.pos().x(), point2.pos().x() ),
347 TQMAX( point1.pos().y(), point2.pos().y() ) ) ) );
348 }
349 }
350 }
351
352 if ( error ) KMessageBox::information( 0, i18n( "Print range wrong, changes are ignored." ) );
353 }
354
355 if ( tmpRepeatCols.isEmpty() )
356 {
357 print->setPrintRepeatColumns( qMakePair( 0, 0 ) );
358 }
359 else
360 {
361 bool error = true;
362 int first = tmpRepeatCols.find(":");
363 if ( ( first != -1 ) && ( (int)tmpRepeatCols.length() > first ) )
364 {
365 int col1 = util_decodeColumnLabelText( tmpRepeatCols.left( first ) );
366 if ( col1 > 0 && col1 <= KS_colMax )
367 {
368 int col2 = util_decodeColumnLabelText( tmpRepeatCols.mid( first+1 ) );
369 if ( col2 > 0 && col2 <= KS_colMax )
370 {
371 error = false;
372 print->setPrintRepeatColumns ( qMakePair( col1, col2 ) );
373 }
374 }
375 }
376
377 if ( error )
378 KMessageBox::information( 0, i18n( "Repeated columns range wrong, changes are ignored.\nMust be in format column:column (eg. B:C)" ) );
379 }
380
381 if ( tmpRepeatRows.isEmpty() )
382 {
383 print->setPrintRepeatRows ( qMakePair( 0, 0 ) );
384 }
385 else
386 {
387 bool error = true;
388 int first = tmpRepeatRows.find(":");
389 if ( ( first != -1 ) && ( (int)tmpRepeatRows.length() > first ) )
390 {
391 int row1 = tmpRepeatRows.left( first ).toInt();
392 if ( row1 > 0 && row1 <= KS_rowMax )
393 {
394 int row2 = tmpRepeatRows.mid( first+1 ).toInt();
395 if ( row2 > 0 && row2 <= KS_rowMax )
396 {
397 error = false;
398 print->setPrintRepeatRows ( qMakePair( row1, row2 ) );
399 }
400 }
401 }
402
403 if ( error )
404 KMessageBox::information( 0, i18n( "Repeated rows range wrong, changes are ignored.\nMust be in format row:row (eg. 2:3)" ) );
405 }
406
407 if ( m_rScalingZoom->isChecked() )
408 {
409 kdDebug() << "Zoom is selected" << endl;
410 if( TQString( "%1%" ).arg( tqRound( print->zoom() * 100 ) ) != m_cZoom->currentText() )
411 {
412 kdDebug() << "New zoom is different than original: " << m_cZoom->currentText() << endl;
413 TQString zoomtext = m_cZoom->currentText();
414 zoomtext.replace("%","");
415 bool convertok = false;
416 double zoomvalue = zoomtext.toDouble(&convertok);
417 if (!convertok)
418 {
419 kdWarning() << "Could not convert zoom text to double value!!!" << endl;
420 }
421 else if( zoomvalue != 0.0 )
422 {
423 //reset page limits
424 print->setPageLimitX(0);
425 print->setPageLimitY(0);
426 kdDebug() << "Setting print zoom: " << zoomvalue*0.01 << endl;
427 print->setZoom( 0.01 * zoomvalue );
428 kdDebug() << "New print zoom: " << print->zoom() << endl;
429 }
430 else
431 kdDebug() << "Did not set print zoom" << endl;
432 }
433 else
434 kdDebug() << "new zoom is same as original: " << m_cZoom->currentText() << endl;
435 }
436 else if (m_rScalingLimitPages->isChecked())
437 {
438 kdDebug() << "Limit pages is selected" << endl;
439 kdDebug() << "Current zoom: " << print->zoom() << endl;
440
441 //reset first, otherwise setting the first limit
442 //would still check against the second limit and
443 //possibly result in a smaller total zoom
444 print->setPageLimitX( 0 );
445 print->setPageLimitY( 0 );
446
447 //start with at least 100%
448
449 if (print->zoom() < 1.0)
450 {
451 kdDebug() << "Resetting zoom to 1.0" << endl;
452 print->setZoom(1.0,false); //don't check page limits here
453 kdDebug() << "Zoom is now: " << print->zoom() << endl;
454 }
455
456 bool convertok = false;
457
458 int limitX = m_cLimitPagesX->currentText().toInt(&convertok);
459 if (!convertok) //THIS IS THE CASE WITH "No Limit"
460 limitX = 0; //0 means no limit
461
462 convertok=false;
463 int limitY = m_cLimitPagesY->currentText().toInt(&convertok);
464 if (!convertok) //THIS IS THE CASE WITH "No Limit"
465 limitY=0; //0 means no limit
466
467 kdDebug() << "Zoom before setting limits: " << print->zoom() << endl;
468 kdDebug() << "Chosen Limits: x: " << limitX << "; y: " << limitY << endl;
469 print->setPageLimitX( limitX );
470 kdDebug() << "Zoom after setting x limit: " << print->zoom() << endl;
471 print->setPageLimitY( limitY );
472 kdDebug() << "Zoom after setting y limit: " << print->zoom() << endl;
473 }
474 else
475 kdWarning() << "ERROR: unknown zoom option selected" << endl;
476
477 sheet->doc()->setModified( true );
478
479 if ( pl.format == PG_CUSTOM )
480 {
481 print->setPaperWidth( tqRound( POINT_TO_MM( pl.ptWidth ) *1000 ) / 1000 );
482 print->setPaperHeight( tqRound( POINT_TO_MM( pl.ptHeight ) *1000 ) / 1000 );
483 }
484
485 print->setPaperLayout( POINT_TO_MM(pl.ptLeft), POINT_TO_MM(pl.ptTop),
486 POINT_TO_MM(pl.ptRight), POINT_TO_MM(pl.ptBottom),
487 pl.format, pl.orientation );
488
489 print->setHeadFootLine( print->delocalizeHeadFootLine( hf.headLeft ),
490 print->delocalizeHeadFootLine( hf.headMid ),
491 print->delocalizeHeadFootLine( hf.headRight ),
492 print->delocalizeHeadFootLine( hf.footLeft ),
493 print->delocalizeHeadFootLine( hf.footMid ),
494 print->delocalizeHeadFootLine( hf.footRight ) );
495
496 sheet->doc()->setUnit( unit );
497
498 if ( map )
499 sheet = map->nextSheet();
500 else
501 sheet = 0;
502 }
503
504 m_pView->slotUpdateView( m_pView->activeSheet() );
505 accept();
506}
507
508void PaperLayout::closeEvent ( TQCloseEvent * )
509{
510 delete this;
511}
512
513void PaperLayout::slotSelectionChanged()
514{
515 // TODO Stefan: check for improvement
516 if (!m_pView->selectionInfo()->isValid())
517 return;
518
519 TQString area = util_rangeName( m_pView->selectionInfo()->lastRange() );
520 if ( m_focus )
521 {
522 if ( m_focus == ePrintRange )
523 area = util_rangeName( m_pView->selectionInfo()->lastRange() );
524 else if ( m_focus == eRepeatRows )
525 area = util_rangeRowName( m_pView->selectionInfo()->lastRange() );
526 else if ( m_focus == eRepeatCols )
527 area = util_rangeColumnName( m_pView->selectionInfo()->lastRange() );
528 else
529 return;
530 m_focus->setText( area );
531 }
532}
533
534void PaperLayout::slotCancel()
535{
536 reject();
537}
538
539bool PaperLayout::eventFilter( TQObject* obj, TQEvent* ev )
540{
541 if ( obj == ePrintRange && ev->type() == TQEvent::FocusIn )
542 m_focus = ePrintRange;
543 else if ( obj == eRepeatCols && ev->type() == TQEvent::FocusIn )
544 m_focus = eRepeatCols;
545 else if ( obj == eRepeatRows && ev->type() == TQEvent::FocusIn )
546 m_focus = eRepeatRows;
547 else
548 return false;
549
550 return false;
551}
552
553
554#include "kspread_dlg_paperlayout.moc"
TQString columnName() const
Returns the column name of the cell.
A map is a simple container for all sheets.
Definition kspread_map.h:59
Sheet * firstSheet()
Use the #nextSheet function to get all the other sheets.
Represents the position of a single cell in a workbook.
The one for all class for points and ranges.
Definition region.h:44
Abstract base class.
The View class displays a KSpread document.
The KSpread namespace.
Definition commands.h:39
KSPREAD_EXPORT int util_decodeColumnLabelText(const TQString &_col)
Call this function to decode the text of a column label to an integer i.e.