kspread

kspread_dlg_paperlayout.cc

00001 /* This file is part of the KDE project
00002    Copyright (C) 2005 Raphael Langerhorst <raphael.langerhorst@kdemail.net>
00003              (C) 2002-2003 Ariya Hidayat <ariya@kde.org>
00004              (C) 2002-2003 Norbert Andres <nandres@web.de>
00005              (C) 2002-2003 Philipp Mueller <philipp.mueller@gmx.de>
00006              (C) 2002 Laurent Montel <montel@kde.org>
00007 
00008    This library is free software; you can redistribute it and/or
00009    modify it under the terms of the GNU Library General Public
00010    License as published by the Free Software Foundation; either
00011    version 2 of the License, or (at your option) any later version.
00012 
00013    This library is distributed in the hope that it will be useful,
00014    but WITHOUT ANY WARRANTY; without even the implied warranty of
00015    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016    Library General Public License for more details.
00017 
00018    You should have received a copy of the GNU Library General Public License
00019    along with this library; see the file COPYING.LIB.  If not, write to
00020    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00021  * Boston, MA 02110-1301, USA.
00022 */
00023 
00024 #include "kspread_dlg_paperlayout.h"
00025 #include <kspread_doc.h>
00026 #include "kspread_map.h"
00027 #include "kspread_sheet.h"
00028 #include "kspread_sheetprint.h"
00029 #include <kspread_undo.h>
00030 #include <kspread_util.h>
00031 #include <kspread_view.h>
00032 #include <selection.h>
00033 
00034 #include <qcheckbox.h>
00035 #include <qlabel.h>
00036 #include <qlineedit.h>
00037 #include <qradiobutton.h>
00038 #include <qbuttongroup.h>
00039 #include <qcombobox.h>
00040 #include <qlayout.h>
00041 #include <qhgroupbox.h>
00042 
00043 #include <kapplication.h>
00044 #include <kdebug.h>
00045 #include <klocale.h>
00046 #include <kmessagebox.h>
00047 
00048 using namespace KSpread;
00049 
00050 PaperLayout::PaperLayout( QWidget * parent, const char * name,
00051                                         const KoPageLayout & layout,
00052                                         const KoHeadFoot & headfoot,
00053                                         int tabs, KoUnit::Unit unit,
00054                                         Sheet * sheet, View * view)
00055   : KoPageLayoutDia( parent, name, layout, headfoot, tabs, unit, false /*no modal*/),
00056     m_pSheet( sheet ),
00057     m_pView( view )
00058 {
00059     initTab();
00060     connect(view->selectionInfo(), SIGNAL(changed(const Region&)),
00061             this, SLOT(slotSelectionChanged()));
00062     qApp->installEventFilter( this );
00063     m_focus= 0L;
00064 }
00065 
00066 void PaperLayout::initTab()
00067 {
00068     SheetPrint* print = m_pSheet->print();
00069 
00070     QWidget *tab = addPage(i18n( "Options" ));
00071     QVBoxLayout *vbox = new QVBoxLayout( tab, KDialog::marginHint(), KDialog::spacingHint() );
00072 
00073     pApplyToAll = new QCheckBox ( i18n( "&Apply to all sheets" ), tab );
00074     pApplyToAll->setChecked( print->printGrid() );
00075     vbox->addWidget( pApplyToAll );
00076 
00077     //Range properties
00078     initGeneralOptions( tab, vbox );
00079 
00080     //Range properties
00081     initRanges( tab, vbox );
00082 
00083     //Scale properties
00084     initScaleOptions( tab, vbox );
00085 
00086     vbox->addStretch( 1 );
00087 }
00088 
00089 void PaperLayout::initGeneralOptions( QWidget * tab, QVBoxLayout * vbox )
00090 {
00091     SheetPrint* print = m_pSheet->print();
00092 
00093     QGroupBox *group = new QGroupBox( i18n("General Options"), tab );
00094     QGridLayout *l = new QGridLayout( group, 2, 3 );
00095 
00096     pPrintGrid = new QCheckBox ( i18n("Print &grid"), group );
00097     pPrintGrid->setChecked( print->printGrid() );
00098     l->addWidget( pPrintGrid, 0, 0 );
00099 
00100     pPrintCommentIndicator = new QCheckBox ( i18n("Print &comment indicator"), group );
00101     pPrintCommentIndicator->setChecked( print->printCommentIndicator() );
00102     l->addWidget( pPrintCommentIndicator, 0, 1 );
00103 
00104     pPrintFormulaIndicator = new QCheckBox ( i18n("Print &formula indicator"), group );
00105     pPrintFormulaIndicator->setChecked( print->printFormulaIndicator() );
00106     l->addWidget( pPrintFormulaIndicator, 0, 2 );
00107 
00108     pPrintObjects = new QCheckBox ( i18n("Print &objects"), group );
00109     pPrintObjects->setChecked( print->printObjects() );
00110     l->addWidget( pPrintObjects, 1, 0 );
00111 
00112     pPrintCharts = new QCheckBox ( i18n("Print &charts"), group );
00113     pPrintCharts->setChecked( print->printCharts() );
00114     l->addWidget( pPrintCharts, 1, 1 );
00115 
00116 //     Not used yet unless someone implement some kind of drawing object
00117 //     pPrintGraphics = new QCheckBox ( i18n("Print &drawings"), group );
00118 //     pPrintGraphics->setChecked( print->printGraphics() );
00119 //     l->addWidget( pPrintGraphics, 1, 2 );
00120 
00121     vbox->addWidget( group );
00122 }
00123 
00124 void PaperLayout::initRanges( QWidget * tab, QVBoxLayout * vbox )
00125 {
00126     SheetPrint* print = m_pSheet->print();
00127 
00128     QGroupBox *rangeGroup = new QGroupBox( i18n("Ranges"), tab );
00129     rangeGroup->setColumnLayout( 0, Qt::Vertical );
00130     rangeGroup->setMargin( KDialog::marginHint() );
00131     vbox->addWidget( rangeGroup );
00132 
00133     QGridLayout *grid = new QGridLayout( rangeGroup->layout(), 3, 2, KDialog::spacingHint() );
00134 
00135     QLabel *pPrintRange = new QLabel ( i18n("Print range:"), rangeGroup );
00136     grid->addWidget( pPrintRange, 0, 0 );
00137 
00138     ePrintRange = new QLineEdit( rangeGroup );
00139     ePrintRange->setText( util_rangeName( print->printRange() ) );
00140     grid->addWidget( ePrintRange, 0, 1 );
00141 
00142     QLabel *pRepeatCols = new QLabel ( i18n("Repeat columns on each page:"), rangeGroup );
00143     grid->addWidget( pRepeatCols, 1, 0 );
00144 
00145     eRepeatCols = new QLineEdit( rangeGroup );
00146     if ( print->printRepeatColumns().first != 0 )
00147         eRepeatCols->setText( Cell::columnName( print->printRepeatColumns().first ) +  ":" +
00148                               Cell::columnName( print->printRepeatColumns().second ) );
00149     grid->addWidget( eRepeatCols, 1, 1 );
00150 
00151     QLabel *pRepeatRows = new QLabel ( i18n("Repeat rows on each page:"), rangeGroup );
00152     grid->addWidget( pRepeatRows, 2, 0 );
00153 
00154     eRepeatRows = new QLineEdit( rangeGroup );
00155     if ( print->printRepeatRows().first != 0 )
00156         eRepeatRows->setText( QString().setNum( print->printRepeatRows().first ) +
00157                               ":" +
00158                               QString().setNum( print->printRepeatRows().second ) );
00159     grid->addWidget( eRepeatRows, 2, 1 );
00160 
00161     grid->addColSpacing( 0, pPrintRange->width() );
00162     grid->addColSpacing( 0, pRepeatRows->width() );
00163     grid->addColSpacing( 0, pRepeatCols->width() );
00164     grid->addColSpacing( 1, ePrintRange->width() );
00165     grid->addColSpacing( 1, eRepeatRows->width() );
00166     grid->addColSpacing( 1, eRepeatCols->width() );
00167 
00168     grid->addRowSpacing( 0, pPrintRange->height() );
00169     grid->addRowSpacing( 0, ePrintRange->height() );
00170     grid->addRowSpacing( 1, pRepeatRows->height() );
00171     grid->addRowSpacing( 1, eRepeatRows->height() );
00172     grid->addRowSpacing( 2, pRepeatCols->height() );
00173     grid->addRowSpacing( 2, eRepeatCols->height() );
00174 }
00175 
00176 void PaperLayout::initScaleOptions( QWidget * tab, QVBoxLayout * vbox )
00177 {
00178     SheetPrint* print = m_pSheet->print();
00179 
00180     QButtonGroup *zoomGroup = new QButtonGroup( i18n("Scale Printout"), tab );
00181     zoomGroup->setColumnLayout( 0, Qt::Vertical );
00182     zoomGroup->setMargin( KDialog::marginHint() );
00183     vbox->addWidget( zoomGroup );
00184 
00185     QGridLayout *grid = new QGridLayout( zoomGroup->layout(), 2, 6,
00186                                          KDialog::spacingHint() );
00187 
00188     m_rScalingZoom = new QRadioButton ( i18n("Zoom:"), zoomGroup );
00189     grid->addWidget( m_rScalingZoom, 0, 0 );
00190 
00191     m_cZoom = new QComboBox( true, zoomGroup, "Zoom" );
00192     grid->addMultiCellWidget( m_cZoom, 0, 0, 1, 5, Qt::AlignLeft );
00193 
00194     QStringList lst;
00195     for( int i = 5; i < 500; i += 5 )
00196     {
00197         lst.append( QString( i18n( "%1%" ) ).arg( i ) );
00198         if( qRound( print->zoom() * 100 ) > i &&
00199             qRound( print->zoom() * 100 ) < i + 5 )
00200         {
00201             lst.append( QString( i18n( "%1%" ) ).arg( qRound( print->zoom() * 100 ) ) );
00202         }
00203     }
00204     m_cZoom->insertStringList( lst );
00205 
00206     int number_of_entries = m_cZoom->count();
00207     QString string = QString( i18n( "%1%" ) ).arg( qRound( print->zoom() * 100 ) );
00208     for (int i = 0; i < number_of_entries ; i++)
00209     {
00210         if ( string == (QString) m_cZoom->text(i) )
00211         {
00212             m_cZoom->setCurrentItem( i );
00213             break;
00214         }
00215     }
00216 
00217     m_rScalingLimitPages = new QRadioButton ( i18n("Limit pages:"), zoomGroup );
00218     grid->addWidget( m_rScalingLimitPages, 1, 0 );
00219 
00220     QLabel *pLimitPagesX = new QLabel ( i18n("X:"), zoomGroup );
00221     grid->addWidget( pLimitPagesX, 1, 1 );
00222 
00223     m_cLimitPagesX = new QComboBox( true, zoomGroup, "pagesX" );
00224     grid->addWidget( m_cLimitPagesX, 1, 2 );
00225 
00226     QStringList lstX;
00227     lstX.append( i18n( "No Limit" ) );
00228     for( int i = 1; i <= 20; i += 1 )
00229     {
00230         lstX.append( QString( "%1" ).arg( i ) );
00231     }
00232     if( print->pageLimitX() > 20 )
00233     {
00234       lstX.append( QString( "%1" ).arg( print->pageLimitX() ) );
00235     }
00236     m_cLimitPagesX->insertStringList( lstX );
00237 
00238     if ( print->pageLimitX() <= 20 )
00239         m_cLimitPagesX->setCurrentItem( print->pageLimitX() );
00240     else
00241         m_cLimitPagesX->setCurrentItem( 21 );
00242 
00243     QLabel *pLimitPagesY = new QLabel ( i18n("Y:"), zoomGroup );
00244     grid->addWidget( pLimitPagesY, 1, 3 );
00245 
00246     m_cLimitPagesY = new QComboBox( true, zoomGroup, "pagesY" );
00247     grid->addWidget( m_cLimitPagesY, 1, 4 );
00248 
00249     QStringList lstY;
00250     lstY.append( i18n( "No Limit" ) );
00251     for( int i = 1; i <= 20; i += 1 )
00252     {
00253         lstY.append( QString( "%1" ).arg( i ) );
00254     }
00255     if( print->pageLimitY() > 20 )
00256     {
00257       lstY.append( QString( "%1" ).arg( print->pageLimitY() ) );
00258     }
00259     m_cLimitPagesY->insertStringList( lstY );
00260 
00261     if ( print->pageLimitY() <= 20 )
00262         m_cLimitPagesY->setCurrentItem( print->pageLimitY() );
00263     else
00264         m_cLimitPagesY->setCurrentItem( 21 );
00265 
00266     if ( print->pageLimitY() != 0 || print->pageLimitX() != 0 )
00267     {
00268         m_rScalingLimitPages->setChecked( true );
00269     }
00270     else
00271     {
00272         m_rScalingZoom->setChecked( true );
00273     }
00274 
00275     connect( m_cZoom, SIGNAL( activated( int ) ), this, SLOT( slotChooseZoom( int ) ) );
00276     connect( m_cLimitPagesX, SIGNAL( activated( int ) ), this, SLOT( slotChoosePageLimit( int ) ) );
00277     connect( m_cLimitPagesY, SIGNAL( activated( int ) ), this, SLOT( slotChoosePageLimit( int ) ) );
00278 }
00279 
00280 void PaperLayout::slotChooseZoom( int /*index*/ )
00281 {
00282     m_rScalingZoom->setChecked( true );
00283 }
00284 
00285 void PaperLayout::slotChoosePageLimit( int /*index*/ )
00286 {
00287     m_rScalingLimitPages->setChecked( true );
00288 }
00289 
00290 void PaperLayout::slotOk()
00291 {
00292     if ( !m_pSheet->doc()->undoLocked() )
00293     {
00294         UndoAction* undo = new UndoPaperLayout( m_pSheet->doc(), m_pSheet );
00295         m_pSheet->doc()->addCommand( undo );
00296     }
00297 
00298     // get new values for borders
00299     Map   * map   = 0;
00300     Sheet * sheet = 0;
00301 
00302     if ( pApplyToAll->isChecked() )
00303       map = m_pSheet->doc()->map();
00304 
00305     if ( map )
00306       sheet = map->firstSheet();
00307     else
00308       sheet = m_pSheet;
00309 
00310     m_pView->doc()->emitBeginOperation( false );
00311     while ( sheet )
00312     {
00313       SheetPrint *print = sheet->print();
00314 
00315       KoPageLayout pl = layout();
00316       KoHeadFoot hf = headFoot();
00317       KoUnit::Unit unit = sheet->doc()->unit();
00318       print->setPrintGrid( pPrintGrid->isChecked() );
00319       print->setPrintCommentIndicator( pPrintCommentIndicator->isChecked() );
00320       print->setPrintFormulaIndicator( pPrintFormulaIndicator->isChecked() );
00321       print->setPrintObjects( pPrintObjects->isChecked() );
00322       print->setPrintCharts( pPrintCharts->isChecked() );
00323 //       print->setPrintGraphics( pPrintGraphics->isChecked() );
00324       QString tmpPrintRange = ePrintRange->text();
00325       QString tmpRepeatCols = eRepeatCols->text();
00326       QString tmpRepeatRows = eRepeatRows->text();
00327       if ( tmpPrintRange.isEmpty() )
00328       {
00329         print->setPrintRange( QRect( QPoint( 1, 1 ), QPoint( KS_colMax, KS_rowMax ) ) );
00330       }
00331       else
00332       {
00333         bool error = true;
00334         int first = tmpPrintRange.find(":");
00335         if ( ( first != -1 ) && ( (int)tmpPrintRange.length() > first ) )
00336         {
00337             Point point1 ( tmpPrintRange.left( first ) );
00338             if ( point1.isValid() )
00339             {
00340                 Point point2 ( tmpPrintRange.mid( first+1 ) );
00341                 if ( point2.isValid() )
00342                 {
00343                     error = false;
00344                     print->setPrintRange ( QRect( QPoint( QMIN( point1.pos().x(), point2.pos().x() ),
00345                                                           QMIN( point1.pos().y(), point2.pos().y() ) ),
00346                                                   QPoint( QMAX( point1.pos().x(), point2.pos().x() ),
00347                                                           QMAX( point1.pos().y(), point2.pos().y() ) ) ) );
00348                 }
00349             }
00350         }
00351 
00352         if ( error ) KMessageBox::information( 0, i18n( "Print range wrong, changes are ignored." ) );
00353       }
00354 
00355       if ( tmpRepeatCols.isEmpty() )
00356       {
00357         print->setPrintRepeatColumns( qMakePair( 0, 0 ) );
00358       }
00359       else
00360       {
00361         bool error = true;
00362         int first = tmpRepeatCols.find(":");
00363         if ( ( first != -1 ) && ( (int)tmpRepeatCols.length() > first ) )
00364         {
00365             int col1 = util_decodeColumnLabelText( tmpRepeatCols.left( first ) );
00366             if ( col1 > 0 && col1 <= KS_colMax )
00367             {
00368                 int col2 = util_decodeColumnLabelText( tmpRepeatCols.mid( first+1 ) );
00369                 if ( col2 > 0 && col2 <= KS_colMax )
00370                 {
00371                     error = false;
00372                     print->setPrintRepeatColumns ( qMakePair( col1, col2 ) );
00373                 }
00374             }
00375         }
00376 
00377         if ( error )
00378           KMessageBox::information( 0, i18n( "Repeated columns range wrong, changes are ignored.\nMust be in format column:column (eg. B:C)" ) );
00379       }
00380 
00381       if ( tmpRepeatRows.isEmpty() )
00382       {
00383         print->setPrintRepeatRows ( qMakePair( 0, 0 ) );
00384       }
00385       else
00386       {
00387         bool error = true;
00388         int first = tmpRepeatRows.find(":");
00389         if ( ( first != -1 ) && ( (int)tmpRepeatRows.length() > first ) )
00390         {
00391             int row1 = tmpRepeatRows.left( first ).toInt();
00392             if ( row1 > 0 && row1 <= KS_rowMax )
00393             {
00394                 int row2 = tmpRepeatRows.mid( first+1 ).toInt();
00395                 if ( row2 > 0 && row2 <= KS_rowMax )
00396                 {
00397                     error = false;
00398                     print->setPrintRepeatRows ( qMakePair( row1, row2 ) );
00399                 }
00400             }
00401         }
00402 
00403         if ( error )
00404           KMessageBox::information( 0, i18n( "Repeated rows range wrong, changes are ignored.\nMust be in format row:row (eg. 2:3)" ) );
00405       }
00406 
00407       if ( m_rScalingZoom->isChecked() )
00408       {
00409         kdDebug() << "Zoom is selected" << endl;
00410         if( QString( "%1%" ).arg( qRound( print->zoom() * 100 ) ) != m_cZoom->currentText() )
00411         {
00412           kdDebug() << "New zoom is different than original: " << m_cZoom->currentText() << endl;
00413           QString zoomtext = m_cZoom->currentText();
00414           zoomtext.replace("%","");
00415           bool convertok = false;
00416           double zoomvalue = zoomtext.toDouble(&convertok);
00417           if (!convertok)
00418           {
00419             kdWarning() << "Could not convert zoom text to double value!!!" << endl;
00420           }
00421           else if( zoomvalue != 0.0 )
00422           {
00423             //reset page limits
00424             print->setPageLimitX(0);
00425             print->setPageLimitY(0);
00426             kdDebug() << "Setting print zoom: " << zoomvalue*0.01 << endl;
00427             print->setZoom( 0.01 * zoomvalue );
00428             kdDebug() << "New print zoom: " << print->zoom() << endl;
00429           }
00430           else
00431             kdDebug() << "Did not set print zoom" << endl;
00432         }
00433         else
00434           kdDebug() << "new zoom is same as original: " << m_cZoom->currentText() << endl;
00435       }
00436       else if (m_rScalingLimitPages->isChecked())
00437       {
00438         kdDebug() << "Limit pages is selected" << endl;
00439         kdDebug() << "Current zoom: " << print->zoom() << endl;
00440         
00441         //reset first, otherwise setting the first limit
00442         //would still check against the second limit and
00443         //possibly result in a smaller total zoom
00444         print->setPageLimitX( 0 );
00445         print->setPageLimitY( 0 );
00446         
00447         //start with at least 100%
00448         
00449         if (print->zoom() < 1.0)
00450         {
00451           kdDebug() << "Resetting zoom to 1.0" << endl;
00452           print->setZoom(1.0,false); //don't check page limits here
00453           kdDebug() << "Zoom is now: " << print->zoom() << endl;
00454         }
00455         
00456         bool convertok = false;
00457         
00458         int limitX = m_cLimitPagesX->currentText().toInt(&convertok);
00459         if (!convertok)  //THIS IS THE CASE WITH "No Limit"
00460           limitX = 0;  //0 means no limit
00461         
00462         convertok=false;
00463         int limitY = m_cLimitPagesY->currentText().toInt(&convertok);
00464         if (!convertok)  //THIS IS THE CASE WITH "No Limit"
00465           limitY=0;  //0 means no limit
00466 
00467         kdDebug() << "Zoom before setting limits: " << print->zoom() << endl;
00468         kdDebug() << "Chosen Limits: x: " << limitX << "; y: " << limitY << endl;
00469         print->setPageLimitX( limitX );
00470         kdDebug() << "Zoom after setting x limit: " << print->zoom() << endl;
00471         print->setPageLimitY( limitY );
00472         kdDebug() << "Zoom after setting y limit: " << print->zoom() << endl;
00473       }
00474       else
00475         kdWarning() << "ERROR: unknown zoom option selected" << endl;
00476 
00477       sheet->doc()->setModified( true );
00478 
00479       if ( pl.format == PG_CUSTOM )
00480       {
00481         print->setPaperWidth( qRound( POINT_TO_MM( pl.ptWidth ) *1000 ) / 1000 );
00482         print->setPaperHeight( qRound( POINT_TO_MM( pl.ptHeight ) *1000 ) / 1000 );
00483       }
00484 
00485       print->setPaperLayout( POINT_TO_MM(pl.ptLeft), POINT_TO_MM(pl.ptTop),
00486                              POINT_TO_MM(pl.ptRight), POINT_TO_MM(pl.ptBottom),
00487                              pl.format, pl.orientation );
00488 
00489       print->setHeadFootLine( print->delocalizeHeadFootLine( hf.headLeft  ),
00490                               print->delocalizeHeadFootLine( hf.headMid   ),
00491                               print->delocalizeHeadFootLine( hf.headRight ),
00492                               print->delocalizeHeadFootLine( hf.footLeft  ),
00493                               print->delocalizeHeadFootLine( hf.footMid   ),
00494                               print->delocalizeHeadFootLine( hf.footRight ) );
00495 
00496       sheet->doc()->setUnit( unit );
00497 
00498       if ( map )
00499         sheet = map->nextSheet();
00500       else
00501         sheet = 0;
00502     }
00503 
00504     m_pView->slotUpdateView( m_pView->activeSheet() );
00505     accept();
00506 }
00507 
00508 void PaperLayout::closeEvent ( QCloseEvent * )
00509 {
00510     delete this;
00511 }
00512 
00513 void PaperLayout::slotSelectionChanged()
00514 {
00515   // TODO Stefan: check for improvement
00516   if (!m_pView->selectionInfo()->isValid())
00517     return;
00518 
00519   QString area = util_rangeName( m_pView->selectionInfo()->lastRange() );
00520   if ( m_focus )
00521   {
00522       if ( m_focus == ePrintRange )
00523         area = util_rangeName( m_pView->selectionInfo()->lastRange() );
00524       else if ( m_focus == eRepeatRows )
00525         area = util_rangeRowName( m_pView->selectionInfo()->lastRange() );
00526       else if ( m_focus == eRepeatCols )
00527         area = util_rangeColumnName( m_pView->selectionInfo()->lastRange() );
00528       else
00529           return;
00530       m_focus->setText( area );
00531   }
00532 }
00533 
00534 void PaperLayout::slotCancel()
00535 {
00536   reject();
00537 }
00538 
00539 bool PaperLayout::eventFilter( QObject* obj, QEvent* ev )
00540 {
00541     if ( obj == ePrintRange && ev->type() == QEvent::FocusIn )
00542         m_focus = ePrintRange;
00543     else if ( obj == eRepeatCols && ev->type() == QEvent::FocusIn )
00544         m_focus = eRepeatCols;
00545     else if ( obj == eRepeatRows && ev->type() == QEvent::FocusIn )
00546         m_focus = eRepeatRows;
00547     else
00548         return false;
00549 
00550     return false;
00551 }
00552 
00553 
00554 #include "kspread_dlg_paperlayout.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys