diff options
Diffstat (limited to 'vcl/source/window/printdlg.cxx')
-rw-r--r-- | vcl/source/window/printdlg.cxx | 2489 |
1 files changed, 2489 insertions, 0 deletions
diff --git a/vcl/source/window/printdlg.cxx b/vcl/source/window/printdlg.cxx new file mode 100644 index 000000000000..649ca21a32b8 --- /dev/null +++ b/vcl/source/window/printdlg.cxx @@ -0,0 +1,2489 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: printdlg.cxx,v $ + * $Revision: 1.1.2.7 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "precompiled_vcl.hxx" + +#include "vcl/print.hxx" +#include "vcl/prndlg.hxx" +#include "vcl/dialog.hxx" +#include "vcl/button.hxx" +#include "vcl/svdata.hxx" +#include "vcl/svids.hrc" +#include "vcl/wall.hxx" +#include "vcl/jobset.h" +#include "vcl/status.hxx" +#include "vcl/decoview.hxx" +#include "vcl/arrange.hxx" +#include "vcl/configsettings.hxx" +#include "vcl/help.hxx" +#include "vcl/decoview.hxx" +#include "vcl/svapp.hxx" + +#include "unotools/localedatawrapper.hxx" + +#include "rtl/ustrbuf.hxx" + +#include "com/sun/star/awt/Size.hpp" + +using namespace vcl; +using namespace com::sun::star; +using namespace com::sun::star::uno; +using namespace com::sun::star::beans; + +#define HELPID_PREFIX ".HelpId:vcl:PrintDialog" +#define SMHID2( a, b ) SetSmartHelpId( SmartId( String( RTL_CONSTASCII_USTRINGPARAM( HELPID_PREFIX ":" a ":" b ) ), HID_PRINTDLG ) ) +#define SMHID1( a ) SetSmartHelpId( SmartId( String( RTL_CONSTASCII_USTRINGPARAM( HELPID_PREFIX ":" a ) ), HID_PRINTDLG ) ) + +PrintDialog::PrintPreviewWindow::PrintPreviewWindow( Window* i_pParent, const ResId& i_rId ) + : Window( i_pParent, i_rId ) + , maOrigSize( 10, 10 ) + , maPageVDev( *this ) + , maToolTipString( String( VclResId( SV_PRINT_PRINTPREVIEW_TXT ) ) ) +{ + SetPaintTransparent( TRUE ); + SetBackground(); + if( GetSettings().GetStyleSettings().GetHighContrastMode() ) + maPageVDev.SetBackground( GetSettings().GetStyleSettings().GetWindowColor() ); + else + maPageVDev.SetBackground( Color( COL_WHITE ) ); +} + +PrintDialog::PrintPreviewWindow::~PrintPreviewWindow() +{ +} + +void PrintDialog::PrintPreviewWindow::DataChanged( const DataChangedEvent& i_rDCEvt ) +{ + // react on settings changed + if( i_rDCEvt.GetType() == DATACHANGED_SETTINGS ) + { + if( GetSettings().GetStyleSettings().GetHighContrastMode() ) + maPageVDev.SetBackground( GetSettings().GetStyleSettings().GetWindowColor() ); + else + maPageVDev.SetBackground( Color( COL_WHITE ) ); + } + Window::DataChanged( i_rDCEvt ); +} + +void PrintDialog::PrintPreviewWindow::Resize() +{ + Size aNewSize( GetSizePixel() ); + // leave small space for decoration + aNewSize.Width() -= 2; + aNewSize.Height() -= 2; + Size aScaledSize; + double fScale = 1.0; + + // #i106435# catch corner case of Size(0,0) + Size aOrigSize( maOrigSize ); + if( aOrigSize.Width() < 1 ) + aOrigSize.Width() = aNewSize.Width(); + if( aOrigSize.Height() < 1 ) + aOrigSize.Height() = aNewSize.Height(); + if( aOrigSize.Width() > aOrigSize.Height() ) + { + aScaledSize = Size( aNewSize.Width(), aNewSize.Width() * aOrigSize.Height() / aOrigSize.Width() ); + if( aScaledSize.Height() > aNewSize.Height() ) + fScale = double(aNewSize.Height())/double(aScaledSize.Height()); + } + else + { + aScaledSize = Size( aNewSize.Height() * aOrigSize.Width() / aOrigSize.Height(), aNewSize.Height() ); + if( aScaledSize.Width() > aNewSize.Width() ) + fScale = double(aNewSize.Width())/double(aScaledSize.Width()); + } + aScaledSize.Width() = long(aScaledSize.Width()*fScale); + aScaledSize.Height() = long(aScaledSize.Height()*fScale); + maPageVDev.SetOutputSizePixel( aScaledSize, FALSE ); +} + +void PrintDialog::PrintPreviewWindow::Paint( const Rectangle& ) +{ + Size aSize( GetSizePixel() ); + if( maReplacementString.getLength() != 0 ) + { + // replacement is active + Push(); + Rectangle aTextRect( Point( 0, 0 ), aSize ); + Font aFont( GetSettings().GetStyleSettings().GetFieldFont() ); + aFont.SetSize( Size( 0, aSize.Height()/12 ) ); + SetFont( aFont ); + DrawText( aTextRect, maReplacementString, + TEXT_DRAW_CENTER | TEXT_DRAW_VCENTER | TEXT_DRAW_WORDBREAK | TEXT_DRAW_MULTILINE + ); + Pop(); + } + else + { + GDIMetaFile aMtf( maMtf ); + + Size aPreviewSize = maPageVDev.GetOutputSizePixel(); + Point aOffset( (aSize.Width() - aPreviewSize.Width()) / 2, + (aSize.Height() - aPreviewSize.Height()) / 2 ); + + const Size aLogicSize( maPageVDev.PixelToLogic( aPreviewSize, MapMode( MAP_100TH_MM ) ) ); + Size aOrigSize( maOrigSize ); + if( aOrigSize.Width() < 1 ) + aOrigSize.Width() = aLogicSize.Width(); + if( aOrigSize.Height() < 1 ) + aOrigSize.Height() = aLogicSize.Height(); + double fScale = double(aLogicSize.Width())/double(aOrigSize.Width()); + + + maPageVDev.Erase(); + maPageVDev.Push(); + maPageVDev.SetMapMode( MAP_100TH_MM ); + aMtf.WindStart(); + aMtf.Scale( fScale, fScale ); + aMtf.WindStart(); + aMtf.Play( &maPageVDev, Point( 0, 0 ), aLogicSize ); + maPageVDev.Pop(); + + SetMapMode( MAP_PIXEL ); + maPageVDev.SetMapMode( MAP_PIXEL ); + DrawOutDev( aOffset, aPreviewSize, Point( 0, 0 ), aPreviewSize, maPageVDev ); + + DecorationView aVw( this ); + aOffset.X() -= 1; aOffset.Y() -=1; aPreviewSize.Width() += 2; aPreviewSize.Height() += 2; + aVw.DrawFrame( Rectangle( aOffset, aPreviewSize ), FRAME_DRAW_GROUP ); + } +} + +void PrintDialog::PrintPreviewWindow::Command( const CommandEvent& rEvt ) +{ + if( rEvt.GetCommand() == COMMAND_WHEEL ) + { + const CommandWheelData* pWheelData = rEvt.GetWheelData(); + PrintDialog* pDlg = dynamic_cast<PrintDialog*>(GetParent()); + if( pDlg ) + { + if( pWheelData->GetDelta() > 0 ) + pDlg->previewForward(); + else if( pWheelData->GetDelta() < 0 ) + pDlg->previewBackward(); + /* + else + huh ? + */ + } + } +} + +void PrintDialog::PrintPreviewWindow::setPreview( const GDIMetaFile& i_rNewPreview, + const Size& i_rOrigSize, + const rtl::OUString& i_rReplacement, + sal_Int32 i_nDPIX, + sal_Int32 i_nDPIY + ) +{ + rtl::OUStringBuffer aBuf( 256 ); + aBuf.append( maToolTipString ); + #if OSL_DEBUG_LEVEL > 0 + aBuf.appendAscii( "\n---\nPageSize: " ); + aBuf.append( sal_Int32( i_rOrigSize.Width()/100) ); + aBuf.appendAscii( "mm x " ); + aBuf.append( sal_Int32( i_rOrigSize.Height()/100) ); + aBuf.appendAscii( "mm" ); + #endif + SetQuickHelpText( aBuf.makeStringAndClear() ); + maMtf = i_rNewPreview; + if( GetSettings().GetStyleSettings().GetHighContrastMode() && + GetSettings().GetStyleSettings().GetWindowColor().IsDark() + ) + { + maMtf.ReplaceColors( Color( COL_BLACK ), Color( COL_WHITE ), 30 ); + } + + maOrigSize = i_rOrigSize; + maReplacementString = i_rReplacement; + maPageVDev.SetReferenceDevice( i_nDPIX, i_nDPIY ); + maPageVDev.EnableOutput( TRUE ); + Resize(); + Invalidate(); +} + +PrintDialog::ShowNupOrderWindow::ShowNupOrderWindow( Window* i_pParent ) + : Window( i_pParent, WB_NOBORDER ) + , mnOrderMode( 0 ) + , mnRows( 1 ) + , mnColumns( 1 ) +{ + ImplInitSettings(); +} + +PrintDialog::ShowNupOrderWindow::~ShowNupOrderWindow() +{ +} + +void PrintDialog::ShowNupOrderWindow::ImplInitSettings() +{ + SetBackground( Wallpaper( GetSettings().GetStyleSettings().GetFieldColor() ) ); +} + +void PrintDialog::ShowNupOrderWindow::Paint( const Rectangle& i_rRect ) +{ + Window::Paint( i_rRect ); + SetMapMode( MAP_PIXEL ); + SetTextColor( GetSettings().GetStyleSettings().GetFieldTextColor() ); + + int nPages = mnRows * mnColumns; + Font aFont( GetSettings().GetStyleSettings().GetFieldFont() ); + aFont.SetSize( Size( 0, 24 ) ); + SetFont( aFont ); + Size aSampleTextSize( GetTextWidth( rtl::OUString::valueOf( sal_Int32(nPages+1) ) ), GetTextHeight() ); + + Size aOutSize( GetOutputSizePixel() ); + Size aSubSize( aOutSize.Width() / mnColumns, aOutSize.Height() / mnRows ); + // calculate font size: shrink the sample text so it fits + double fX = double(aSubSize.Width())/double(aSampleTextSize.Width()); + double fY = double(aSubSize.Height())/double(aSampleTextSize.Height()); + double fScale = (fX < fY) ? fX : fY; + long nFontHeight = long(24.0*fScale) - 3; + if( nFontHeight < 5 ) + nFontHeight = 5; + aFont.SetSize( Size( 0, nFontHeight ) ); + SetFont( aFont ); + long nTextHeight = GetTextHeight(); + for( int i = 0; i < nPages; i++ ) + { + rtl::OUString aPageText( rtl::OUString::valueOf( sal_Int32(i+1) ) ); + int nX = 0, nY = 0; + switch( mnOrderMode ) + { + case SV_PRINT_PRT_NUP_ORDER_LRTD: + nX = (i % mnColumns); nY = (i / mnColumns); + break; + case SV_PRINT_PRT_NUP_ORDER_TDLR: + nX = (i / mnRows); nY = (i % mnRows); + break; + } + Size aTextSize( GetTextWidth( aPageText ), nTextHeight ); + int nDeltaX = (aSubSize.Width() - aTextSize.Width()) / 2; + int nDeltaY = (aSubSize.Height() - aTextSize.Height()) / 2; + DrawText( Point( nX * aSubSize.Width() + nDeltaX, + nY * aSubSize.Height() + nDeltaY ), + aPageText ); + } + DecorationView aVw( this ); + aVw.DrawFrame( Rectangle( Point( 0, 0), aOutSize ), FRAME_DRAW_GROUP ); +} + +PrintDialog::NUpTabPage::NUpTabPage( Window* i_pParent, const ResId& rResId ) + : TabPage( i_pParent, rResId ) + , maNupLine( this, VclResId( SV_PRINT_PRT_NUP_LAYOUT_FL ) ) + , maPagesBtn( this, VclResId( SV_PRINT_PRT_NUP_PAGES_BTN ) ) + , maBrochureBtn( this, VclResId( SV_PRINT_PRT_NUP_BROCHURE_BTN ) ) + , maPagesBoxTitleTxt( this, 0 ) + , maNupPagesBox( this, VclResId( SV_PRINT_PRT_NUP_PAGES_BOX ) ) + , maNupNumPagesTxt( this, VclResId( SV_PRINT_PRT_NUP_NUM_PAGES_TXT ) ) + , maNupColEdt( this, VclResId( SV_PRINT_PRT_NUP_COLS_EDT ) ) + , maNupTimesTxt( this, VclResId( SV_PRINT_PRT_NUP_TIMES_TXT ) ) + , maNupRowsEdt( this, VclResId( SV_PRINT_PRT_NUP_ROWS_EDT ) ) + , maPageMarginTxt1( this, VclResId( SV_PRINT_PRT_NUP_MARGINS_PAGES_1_TXT ) ) + , maPageMarginEdt( this, VclResId( SV_PRINT_PRT_NUP_MARGINS_PAGES_EDT ) ) + , maPageMarginTxt2( this, VclResId( SV_PRINT_PRT_NUP_MARGINS_PAGES_2_TXT ) ) + , maSheetMarginTxt1( this, VclResId( SV_PRINT_PRT_NUP_MARGINS_SHEET_1_TXT ) ) + , maSheetMarginEdt( this, VclResId( SV_PRINT_PRT_NUP_MARGINS_SHEET_EDT ) ) + , maSheetMarginTxt2( this, VclResId( SV_PRINT_PRT_NUP_MARGINS_SHEET_2_TXT ) ) + , maNupOrientationTxt( this, VclResId( SV_PRINT_PRT_NUP_ORIENTATION_TXT ) ) + , maNupOrientationBox( this, VclResId( SV_PRINT_PRT_NUP_ORIENTATION_BOX ) ) + , maNupOrderTxt( this, VclResId( SV_PRINT_PRT_NUP_ORDER_TXT ) ) + , maNupOrderBox( this, VclResId( SV_PRINT_PRT_NUP_ORDER_BOX ) ) + , maNupOrderWin( this ) + , maBorderCB( this, VclResId( SV_PRINT_PRT_NUP_BORDER_CB ) ) +{ + FreeResource(); + + maNupOrderWin.Show(); + maPagesBtn.Check( TRUE ); + maBrochureBtn.Show( FALSE ); + + // setup field units for metric fields + const LocaleDataWrapper& rLocWrap( maPageMarginEdt.GetLocaleDataWrapper() ); + FieldUnit eUnit = FUNIT_MM; + USHORT nDigits = 0; + if( rLocWrap.getMeasurementSystemEnum() == MEASURE_US ) + { + eUnit = FUNIT_INCH; + nDigits = 2; + } + // set units + maPageMarginEdt.SetUnit( eUnit ); + maSheetMarginEdt.SetUnit( eUnit ); + + // set precision + maPageMarginEdt.SetDecimalDigits( nDigits ); + maSheetMarginEdt.SetDecimalDigits( nDigits ); + + SMHID1( "NUpPage" ); + maNupLine.SMHID2("NUpPage", "Layout"); + maBrochureBtn.SMHID2("NUpPage", "Brochure" ); + maPagesBtn.SMHID2( "NUpPage", "PagesPerSheet" ); + maPagesBoxTitleTxt.SMHID2( "NUpPage", "PagesPerSheetLabel" ); + maNupPagesBox.SMHID2( "NUpPage", "PagesPerSheetBox" ); + maNupNumPagesTxt.SMHID2( "NUpPage", "Columns" ); + maNupColEdt.SMHID2( "NUpPage", "ColumnsBox" ); + maNupTimesTxt.SMHID2( "NUpPage", "Rows" ); + maNupRowsEdt.SMHID2( "NUpPage", "RowsBox" ); + maPageMarginTxt1.SMHID2( "NUpPage", "PageMargin" ); + maPageMarginEdt.SMHID2( "NUpPage", "PageMarginBox" ); + maPageMarginTxt2.SMHID2( "NUpPage", "PageMarginCont" ); + maSheetMarginTxt1.SMHID2( "NUpPage", "SheetMargin" ); + maSheetMarginEdt.SMHID2( "NUpPage", "SheetMarginBox" ); + maSheetMarginTxt2.SMHID2( "NUpPage", "SheetMarginCont" ); + maNupOrientationTxt.SMHID2( "NUpPage", "Orientation" ); + maNupOrientationBox.SMHID2( "NUpPage", "OrientationBox" ); + maNupOrderTxt.SMHID2( "NUpPage", "Order" ); + maNupOrderBox.SMHID2( "NUpPage", "OrderBox" ); + maBorderCB.SMHID2( "NUpPage", "BorderBox" ); + + setupLayout(); +} + +PrintDialog::NUpTabPage::~NUpTabPage() +{ +} + +void PrintDialog::NUpTabPage::enableNupControls( bool bEnable ) +{ + maNupPagesBox.Enable( TRUE ); + maNupNumPagesTxt.Enable( bEnable ); + maNupColEdt.Enable( bEnable ); + maNupTimesTxt.Enable( bEnable ); + maNupRowsEdt.Enable( bEnable ); + maPageMarginTxt1.Enable( bEnable ); + maPageMarginEdt.Enable( bEnable ); + maPageMarginTxt2.Enable( bEnable ); + maSheetMarginTxt1.Enable( bEnable ); + maSheetMarginEdt.Enable( bEnable ); + maSheetMarginTxt2.Enable( bEnable ); + maNupOrientationTxt.Enable( bEnable ); + maNupOrientationBox.Enable( bEnable ); + maNupOrderTxt.Enable( bEnable ); + maNupOrderBox.Enable( bEnable ); + maNupOrderWin.Enable( bEnable ); + maBorderCB.Enable( bEnable ); +} + +void PrintDialog::NUpTabPage::showAdvancedControls( bool i_bShow ) +{ + maNupNumPagesTxt.Show( i_bShow ); + maNupColEdt.Show( i_bShow ); + maNupTimesTxt.Show( i_bShow ); + maNupRowsEdt.Show( i_bShow ); + maPageMarginTxt1.Show( i_bShow ); + maPageMarginEdt.Show( i_bShow ); + maPageMarginTxt2.Show( i_bShow ); + maSheetMarginTxt1.Show( i_bShow ); + maSheetMarginEdt.Show( i_bShow ); + maSheetMarginTxt2.Show( i_bShow ); + maNupOrientationTxt.Show( i_bShow ); + maNupOrientationBox.Show( i_bShow ); + maLayout.resize(); +} + +void PrintDialog::NUpTabPage::setupLayout() +{ + Size aBorder( LogicToPixel( Size( 5, 5 ), MapMode( MAP_APPFONT ) ) ); + long nIndent = 3*aBorder.Width(); + + maLayout.setParentWindow( this ); + maLayout.setOuterBorder( aBorder.Width() ); + + maLayout.addWindow( &maNupLine ); + boost::shared_ptr< vcl::RowOrColumn > xRow( new vcl::RowOrColumn( &maLayout, false ) ); + maLayout.addChild( xRow ); + boost::shared_ptr< vcl::Indenter > xIndent( new vcl::Indenter( xRow.get() ) ); + xRow->addChild( xIndent ); + + boost::shared_ptr< vcl::RowOrColumn > xShowNupCol( new vcl::RowOrColumn( xRow.get() ) ); + xRow->addChild( xShowNupCol, -1 ); + xShowNupCol->setMinimumSize( xShowNupCol->addWindow( &maNupOrderWin ), Size( 70, 70 ) ); + boost::shared_ptr< vcl::Spacer > xSpacer( new vcl::Spacer( xShowNupCol.get() ) ); + xShowNupCol->addChild( xSpacer ); + + boost::shared_ptr< vcl::LabelColumn > xMainCol( new vcl::LabelColumn( xIndent.get() ) ); + xIndent->setChild( xMainCol ); + + size_t nPagesIndex = xMainCol->addRow( &maPagesBtn, &maNupPagesBox ); + mxPagesBtnLabel = boost::dynamic_pointer_cast<vcl::LabeledElement>( xMainCol->getChild( nPagesIndex ) ); + + xRow.reset( new vcl::RowOrColumn( xMainCol.get(), false ) ); + xMainCol->addRow( &maNupNumPagesTxt, xRow, nIndent ); + xRow->addWindow( &maNupColEdt ); + xRow->addWindow( &maNupTimesTxt ); + xRow->addWindow( &maNupRowsEdt ); + + boost::shared_ptr< vcl::LabeledElement > xLab( new vcl::LabeledElement( xMainCol.get(), 2 ) ); + xLab->setLabel( &maPageMarginEdt ); + xLab->setElement( &maPageMarginTxt2 ); + xMainCol->addRow( &maPageMarginTxt1, xLab, nIndent ); + + xLab.reset( new vcl::LabeledElement( xMainCol.get(), 2 ) ); + xLab->setLabel( &maSheetMarginEdt ); + xLab->setElement( &maSheetMarginTxt2 ); + xMainCol->addRow( &maSheetMarginTxt1, xLab, nIndent ); + + xMainCol->addRow( &maNupOrientationTxt, &maNupOrientationBox, nIndent ); + xMainCol->addRow( &maNupOrderTxt, &maNupOrderBox, nIndent ); + xMainCol->setBorders( xMainCol->addWindow( &maBorderCB ), nIndent, 0, 0, 0 ); + + xSpacer.reset( new vcl::Spacer( xMainCol.get(), 0, Size( 10, aBorder.Width() ) ) ); + xMainCol->addChild( xSpacer ); + + xRow.reset( new vcl::RowOrColumn( xMainCol.get(), false ) ); + xMainCol->addRow( &maBrochureBtn, xRow ); + // remember brochure row for dependencies + mxBrochureDep = xRow; + + // initially advanced controls are not shown, rows=columns=1 + showAdvancedControls( false ); +} + +void PrintDialog::NUpTabPage::Resize() +{ + maLayout.setManagedArea( Rectangle( Point( 0, 0 ), GetOutputSizePixel() ) ); +} + +void PrintDialog::NUpTabPage::initFromMultiPageSetup( const vcl::PrinterController::MultiPageSetup& i_rMPS ) +{ + maSheetMarginEdt.SetValue( maSheetMarginEdt.Normalize( i_rMPS.nLeftMargin ), FUNIT_100TH_MM ); + maPageMarginEdt.SetValue( maPageMarginEdt.Normalize( i_rMPS.nHorizontalSpacing ), FUNIT_100TH_MM ); + maBorderCB.Check( i_rMPS.bDrawBorder ); + maNupRowsEdt.SetValue( i_rMPS.nRows ); + maNupColEdt.SetValue( i_rMPS.nColumns ); +} + +void PrintDialog::NUpTabPage::readFromSettings() +{ +} + +void PrintDialog::NUpTabPage::storeToSettings() +{ +} + +PrintDialog::JobTabPage::JobTabPage( Window* i_pParent, const ResId& rResId ) + : TabPage( i_pParent, rResId ) + , maPrinterFL( this, VclResId( SV_PRINT_PRINTERS_FL ) ) + , maPrinters( this, VclResId( SV_PRINT_PRINTERS ) ) + , maDetailsBtn( this, VclResId( SV_PRINT_DETAILS_BTN ) ) + , maStatusLabel( this, VclResId( SV_PRINT_STATUS_TXT ) ) + , maStatusTxt( this, 0 ) + , maLocationLabel( this, VclResId( SV_PRINT_LOCATION_TXT ) ) + , maLocationTxt( this, 0 ) + , maCommentLabel( this, VclResId( SV_PRINT_COMMENT_TXT ) ) + , maCommentTxt( this, 0 ) + , maSetupButton( this, VclResId( SV_PRINT_PRT_SETUP ) ) + , maCopies( this, VclResId( SV_PRINT_COPIES ) ) + , maCopySpacer( this, WB_VERT ) + , maCopyCount( this, VclResId( SV_PRINT_COPYCOUNT ) ) + , maCopyCountField( this, VclResId( SV_PRINT_COPYCOUNT_FIELD ) ) + , maCollateBox( this, VclResId( SV_PRINT_COLLATE ) ) + , maCollateImage( this, VclResId( SV_PRINT_COLLATE_IMAGE ) ) + , maCollateImg( VclResId( SV_PRINT_COLLATE_IMG ) ) + , maCollateHCImg( VclResId( SV_PRINT_COLLATE_HC_IMG ) ) + , maNoCollateImg( VclResId( SV_PRINT_NOCOLLATE_IMG ) ) + , maNoCollateHCImg( VclResId( SV_PRINT_NOCOLLATE_HC_IMG ) ) + , mnCollateUIMode( 0 ) + , maLayout( NULL, true ) +{ + FreeResource(); + + SMHID1( "JobPage" ); + maPrinterFL.SMHID2( "JobPage", "Printer" ); + maPrinters.SMHID2( "JobPage", "PrinterList" ); + maDetailsBtn.SMHID2( "JobPage", "DetailsBtn" ); + maStatusLabel.SMHID2( "JobPage", "StatusLabel" ); + maStatusTxt.SMHID2( "JobPage", "StatusText" ); + maLocationLabel.SMHID2( "JobPage", "LocationLabel" ); + maLocationTxt.SMHID2( "JobPage", "LocationText" ); + maCommentLabel.SMHID2( "JobPage", "CommentLabel" ); + maCommentTxt.SMHID2( "JobPage", "CommentText" ); + maSetupButton.SMHID2( "JobPage", "Properties" ); + maCopies.SMHID2( "JobPage", "CopiesLine" ); + maCopySpacer.SMHID2( "JobPage", "CopySpacer" ); + maCopyCount.SMHID2( "JobPage", "CopiesText" ); + maCopyCountField.SMHID2( "JobPage", "Copies" ); + maCollateBox.SMHID2( "JobPage", "Collate" ); + maCollateImage.SMHID2( "JobPage", "CollateImage" ); + + maCopySpacer.Show(); + maStatusTxt.Show(); + maCommentTxt.Show(); + maLocationTxt.Show(); + + setupLayout(); +} + +PrintDialog::JobTabPage::~JobTabPage() +{ +} + +void PrintDialog::JobTabPage::setupLayout() +{ + // HACK: this is not a dropdown box, but the dropdown line count + // sets the results of GetOptimalSize in a normal ListBox + maPrinters.SetDropDownLineCount( 4 ); + + Size aBorder( LogicToPixel( Size( 5, 5 ), MapMode( MAP_APPFONT ) ) ); + + maLayout.setParentWindow( this ); + maLayout.setOuterBorder( aBorder.Width() ); + + // add printer fixed line + maLayout.addWindow( &maPrinterFL ); + // add print LB + maLayout.addWindow( &maPrinters ); + + // create a row for details button/text and properties button + boost::shared_ptr< vcl::RowOrColumn > xDetRow( new vcl::RowOrColumn( &maLayout, false ) ); + maLayout.addChild( xDetRow ); + xDetRow->addWindow( &maDetailsBtn ); + xDetRow->addChild( new vcl::Spacer( xDetRow.get(), 2 ) ); + xDetRow->addWindow( &maSetupButton ); + + // create an indent for details + boost::shared_ptr< vcl::Indenter > xIndent( new vcl::Indenter( &maLayout ) ); + maLayout.addChild( xIndent ); + // remember details controls + mxDetails = xIndent; + // create a column for the details + boost::shared_ptr< vcl::LabelColumn > xLabelCol( new vcl::LabelColumn( xIndent.get(), aBorder.Height() ) ); + xIndent->setChild( xLabelCol ); + xLabelCol->addRow( &maStatusLabel, &maStatusTxt ); + xLabelCol->addRow( &maLocationLabel, &maLocationTxt ); + xLabelCol->addRow( &maCommentLabel, &maCommentTxt ); + + // add print range and copies columns + maLayout.addWindow( &maCopies ); + boost::shared_ptr< vcl::RowOrColumn > xRangeRow( new vcl::RowOrColumn( &maLayout, false, aBorder.Width() ) ); + maLayout.addChild( xRangeRow ); + + // create print range and add to range row + mxPrintRange.reset( new vcl::RowOrColumn( xRangeRow.get() ) ); + xRangeRow->addChild( mxPrintRange ); + xRangeRow->addWindow( &maCopySpacer ); + + boost::shared_ptr< vcl::RowOrColumn > xCopyCollateCol( new vcl::RowOrColumn( xRangeRow.get() ) ); + xRangeRow->addChild( xCopyCollateCol ); + + // add copies row to copy/collate column + boost::shared_ptr< vcl::LabeledElement > xCopiesRow( new vcl::LabeledElement( xCopyCollateCol.get(), 2 ) ); + xCopyCollateCol->addChild( xCopiesRow ); + xCopiesRow->setLabel( &maCopyCount ); + xCopiesRow->setElement( &maCopyCountField ); + boost::shared_ptr< vcl::LabeledElement > xCollateRow( new vcl::LabeledElement( xCopyCollateCol.get(), 2 ) ); + xCopyCollateCol->addChild( xCollateRow ); + xCollateRow->setLabel( &maCollateBox ); + xCollateRow->setElement( &maCollateImage ); + + // maDetailsBtn.SetStyle( maDetailsBtn.GetStyle() | (WB_SMALLSTYLE | WB_BEVELBUTTON) ); + mxDetails->show( false, false ); +} + +void PrintDialog::JobTabPage::readFromSettings() +{ + SettingsConfigItem* pItem = SettingsConfigItem::get(); + rtl::OUString aValue; + + #if 0 + // do not actually make copy count persistent + // the assumption is that this would lead to a lot of unwanted copies + aValue = pItem->getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintDialog" ) ), + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CopyCount" ) ) ); + sal_Int32 nVal = aValue.toInt32(); + maCopyCountField.SetValue( sal_Int64(nVal > 1 ? nVal : 1) ); + #endif + + aValue = pItem->getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintDialog" ) ), + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CollateBox" ) ) ); + if( aValue.equalsIgnoreAsciiCaseAscii( "alwaysoff" ) ) + { + mnCollateUIMode = 1; + maCollateBox.Check( FALSE ); + maCollateBox.Enable( FALSE ); + } + else + { + mnCollateUIMode = 0; + aValue = pItem->getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintDialog" ) ), + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Collate" ) ) ); + maCollateBox.Check( aValue.equalsIgnoreAsciiCaseAscii( "true" ) ); + } + Resize(); +} + +void PrintDialog::JobTabPage::storeToSettings() +{ + SettingsConfigItem* pItem = SettingsConfigItem::get(); + pItem->setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintDialog" ) ), + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CopyCount" ) ), + maCopyCountField.GetText() ); + pItem->setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintDialog" ) ), + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Collate" ) ), + rtl::OUString::createFromAscii( maCollateBox.IsChecked() ? "true" : "false" ) ); +} + +void PrintDialog::JobTabPage::Resize() +{ + maLayout.setManagedArea( Rectangle( Point( 0, 0 ), GetSizePixel() ) ); +} + +PrintDialog::OutputOptPage::OutputOptPage( Window* i_pParent, const ResId& i_rResId ) + : TabPage( i_pParent, i_rResId ) + , maOptionsLine( this, VclResId( SV_PRINT_OPT_PRINT_FL ) ) + , maToFileBox( this, VclResId( SV_PRINT_OPT_TOFILE ) ) + , maCollateSingleJobsBox( this, VclResId( SV_PRINT_OPT_SINGLEJOBS ) ) + , maReverseOrderBox( this, VclResId( SV_PRINT_OPT_REVERSE ) ) +{ + FreeResource(); + SMHID1( "OptPage" ); + maOptionsLine.SMHID2( "OptPage", "Options" ); + maToFileBox.SMHID2( "OptPage", "ToFile" ); + maCollateSingleJobsBox.SMHID2( "OptPage", "SingleJobs" ); + maReverseOrderBox.SMHID2( "OptPage", "Reverse" ); + + setupLayout(); +} + +PrintDialog::OutputOptPage::~OutputOptPage() +{ +} + +void PrintDialog::OutputOptPage::setupLayout() +{ + Size aBorder( LogicToPixel( Size( 5, 5 ), MapMode( MAP_APPFONT ) ) ); + + maLayout.setParentWindow( this ); + maLayout.setOuterBorder( aBorder.Width() ); + + maLayout.addWindow( &maOptionsLine ); + boost::shared_ptr<vcl::Indenter> xIndent( new vcl::Indenter( &maLayout, aBorder.Width() ) ); + maLayout.addChild( xIndent ); + boost::shared_ptr<vcl::RowOrColumn> xCol( new vcl::RowOrColumn( xIndent.get(), aBorder.Height() ) ); + xIndent->setChild( xCol ); + mxOptGroup = xCol; + xCol->addWindow( &maToFileBox ); + xCol->addWindow( &maCollateSingleJobsBox ); + xCol->addWindow( &maReverseOrderBox ); +} + +void PrintDialog::OutputOptPage::readFromSettings() +{ + #if 0 + SettingsConfigItem* pItem = SettingsConfigItem::get(); + rtl::OUString aValue; + + aValue = pItem->getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintDialog" ) ), + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ToFile" ) ) ); + maToFileBox.Check( aValue.equalsIgnoreAsciiCaseAscii( "true" ) ); + #endif +} + +void PrintDialog::OutputOptPage::storeToSettings() +{ + SettingsConfigItem* pItem = SettingsConfigItem::get(); + pItem->setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintDialog" ) ), + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ToFile" ) ), + rtl::OUString::createFromAscii( maToFileBox.IsChecked() ? "true" : "false" ) ); +} + +void PrintDialog::OutputOptPage::Resize() +{ + maLayout.setManagedArea( Rectangle( Point( 0, 0 ), GetSizePixel() ) ); +} + + +PrintDialog::PrintDialog( Window* i_pParent, const boost::shared_ptr<PrinterController>& i_rController ) + : ModalDialog( i_pParent, VclResId( SV_DLG_PRINT ) ) + , maOKButton( this, VclResId( SV_PRINT_OK ) ) + , maCancelButton( this, VclResId( SV_PRINT_CANCEL ) ) + , maHelpButton( this, VclResId( SV_PRINT_HELP ) ) + , maPreviewWindow( this, VclResId( SV_PRINT_PAGE_PREVIEW ) ) + , maPageEdit( this, VclResId( SV_PRINT_PAGE_EDIT ) ) + , maNumPagesText( this, VclResId( SV_PRINT_PAGE_TXT ) ) + , maBackwardBtn( this, VclResId( SV_PRINT_PAGE_BACKWARD ) ) + , maForwardBtn( this, VclResId( SV_PRINT_PAGE_FORWARD ) ) + , maTabCtrl( this, VclResId( SV_PRINT_TABCTRL ) ) + , maNUpPage( &maTabCtrl, VclResId( SV_PRINT_TAB_NUP ) ) + , maJobPage( &maTabCtrl, VclResId( SV_PRINT_TAB_JOB ) ) + , maOptionsPage( &maTabCtrl, VclResId( SV_PRINT_TAB_OPT ) ) + , maButtonLine( this, VclResId( SV_PRINT_BUTTONLINE ) ) + , maPController( i_rController ) + , maNoPageStr( String( VclResId( SV_PRINT_NOPAGES ) ) ) + , mnCurPage( 0 ) + , mnCachedPages( 0 ) + , maPrintToFileText( String( VclResId( SV_PRINT_TOFILE_TXT ) ) ) + , maDefPrtText( String( VclResId( SV_PRINT_DEFPRT_TXT ) ) ) + , mbShowLayoutPage( sal_True ) +{ + FreeResource(); + + // save printbutton text, gets exchanged occasionally with print to file + maPrintText = maOKButton.GetText(); + + // setup preview controls + maForwardBtn.SetStyle( maForwardBtn.GetStyle() | WB_BEVELBUTTON ); + maBackwardBtn.SetStyle( maBackwardBtn.GetStyle() | WB_BEVELBUTTON ); + + // insert the job (general) tab page first + maTabCtrl.InsertPage( SV_PRINT_TAB_JOB, maJobPage.GetText() ); + maTabCtrl.SetTabPage( SV_PRINT_TAB_JOB, &maJobPage ); + + // set symbols on forward and backward button + maBackwardBtn.SetSymbol( SYMBOL_PREV ); + maForwardBtn.SetSymbol( SYMBOL_NEXT ); + maBackwardBtn.ImplSetSmallSymbol( TRUE ); + maForwardBtn.ImplSetSmallSymbol( TRUE ); + + maPageStr = maNumPagesText.GetText(); + + // init reverse print + maOptionsPage.maReverseOrderBox.Check( maPController->getReversePrint() ); + + // get the first page + preparePreview( true, true ); + + // fill printer listbox + const std::vector< rtl::OUString >& rQueues( Printer::GetPrinterQueues() ); + for( std::vector< rtl::OUString >::const_iterator it = rQueues.begin(); + it != rQueues.end(); ++it ) + { + maJobPage.maPrinters.InsertEntry( *it ); + } + // select current printer + if( maJobPage.maPrinters.GetEntryPos( maPController->getPrinter()->GetName() ) != LISTBOX_ENTRY_NOTFOUND ) + { + maJobPage.maPrinters.SelectEntry( maPController->getPrinter()->GetName() ); + } + else + { + // fall back to last printer + SettingsConfigItem* pItem = SettingsConfigItem::get(); + String aValue( pItem->getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintDialog" ) ), + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LastPrinter" ) ) ) ); + if( maJobPage.maPrinters.GetEntryPos( aValue ) != LISTBOX_ENTRY_NOTFOUND ) + { + maJobPage.maPrinters.SelectEntry( aValue ); + maPController->setPrinter( boost::shared_ptr<Printer>( new Printer( aValue ) ) ); + } + else + { + // fall back to default printer + maJobPage.maPrinters.SelectEntry( Printer::GetDefaultPrinterName() ); + maPController->setPrinter( boost::shared_ptr<Printer>( new Printer( Printer::GetDefaultPrinterName() ) ) ); + } + } + // update the text fields for the printer + updatePrinterText(); + + // set a select handler + maJobPage.maPrinters.SetSelectHdl( LINK( this, PrintDialog, SelectHdl ) ); + + // setup sizes for N-Up + Size aNupSize( maPController->getPrinter()->PixelToLogic( + maPController->getPrinter()->GetPaperSizePixel(), MapMode( MAP_100TH_MM ) ) ); + if( maPController->getPrinter()->GetOrientation() == ORIENTATION_LANDSCAPE ) + { + maNupLandscapeSize = aNupSize; + maNupPortraitSize = Size( aNupSize.Height(), aNupSize.Width() ); + } + else + { + maNupPortraitSize = aNupSize; + maNupLandscapeSize = Size( aNupSize.Height(), aNupSize.Width() ); + } + maNUpPage.initFromMultiPageSetup( maPController->getMultipage() ); + + + // setup click handler on the various buttons + maOKButton.SetClickHdl( LINK( this, PrintDialog, ClickHdl ) ); + #if OSL_DEBUG_LEVEL > 1 + maCancelButton.SetClickHdl( LINK( this, PrintDialog, ClickHdl ) ); + #endif + maHelpButton.SetClickHdl( LINK( this, PrintDialog, ClickHdl ) ); + maForwardBtn.SetClickHdl( LINK( this, PrintDialog, ClickHdl ) ); + maBackwardBtn.SetClickHdl( LINK( this, PrintDialog, ClickHdl ) ); + maJobPage.maCollateBox.SetToggleHdl( LINK( this, PrintDialog, ClickHdl ) ); + maJobPage.maSetupButton.SetClickHdl( LINK( this, PrintDialog, ClickHdl ) ); + maJobPage.maDetailsBtn.SetToggleHdl( LINK( this, PrintDialog, ClickHdl ) ); + maNUpPage.maBorderCB.SetClickHdl( LINK( this, PrintDialog, ClickHdl ) ); + maOptionsPage.maToFileBox.SetToggleHdl( LINK( this, PrintDialog, ClickHdl ) ); + maOptionsPage.maReverseOrderBox.SetToggleHdl( LINK( this, PrintDialog, ClickHdl ) ); + maNUpPage.maPagesBtn.SetToggleHdl( LINK( this, PrintDialog, ClickHdl ) ); + + // setup modify hdl + maPageEdit.SetModifyHdl( LINK( this, PrintDialog, ModifyHdl ) ); + maJobPage.maCopyCountField.SetModifyHdl( LINK( this, PrintDialog, ModifyHdl ) ); + maNUpPage.maNupRowsEdt.SetModifyHdl( LINK( this, PrintDialog, ModifyHdl ) ); + maNUpPage.maNupColEdt.SetModifyHdl( LINK( this, PrintDialog, ModifyHdl ) ); + maNUpPage.maPageMarginEdt.SetModifyHdl( LINK( this, PrintDialog, ModifyHdl ) ); + maNUpPage.maSheetMarginEdt.SetModifyHdl( LINK( this, PrintDialog, ModifyHdl ) ); + + // setup select hdl + maNUpPage.maNupPagesBox.SetSelectHdl( LINK( this, PrintDialog, SelectHdl ) ); + maNUpPage.maNupOrientationBox.SetSelectHdl( LINK( this, PrintDialog, SelectHdl ) ); + maNUpPage.maNupOrderBox.SetSelectHdl( LINK( this, PrintDialog, SelectHdl ) ); + + // setup the layout + setupLayout(); + + // setup optional UI options set by application + setupOptionalUI(); + + // set change handler for UI options + maPController->setOptionChangeHdl( LINK( this, PrintDialog, UIOptionsChanged ) ); + + // set min size pixel to current size + Size aOutSize( GetOutputSizePixel() ); + SetMinOutputSizePixel( aOutSize ); + + // if there is space enough, enlarge the preview so it gets roughly as + // high as the tab control + if( aOutSize.Width() < 768 ) + { + Size aJobPageSize( getJobPageSize() ); + Size aTabSize( maTabCtrl.GetSizePixel() ); + if( aJobPageSize.Width() < 1 ) + aJobPageSize.Width() = aTabSize.Width(); + if( aJobPageSize.Height() < 1 ) + aJobPageSize.Height() = aTabSize.Height(); + long nOptPreviewWidth = aTabSize.Height() * aJobPageSize.Width() / aJobPageSize.Height(); + // add space for borders + nOptPreviewWidth += 15; + if( aOutSize.Width() - aTabSize.Width() < nOptPreviewWidth ) + { + aOutSize.Width() = aTabSize.Width() + nOptPreviewWidth; + if( aOutSize.Width() > 768 ) // don't enlarge the dialog too much + aOutSize.Width() = 768; + SetOutputSizePixel( aOutSize ); + } + } + + // set HelpIDs + SMHID1( "Dialog" ); + maOKButton.SMHID1( "OK" ); + maCancelButton.SMHID1( "Cancel" ); + maHelpButton.SMHID1( "Help" ); + maPreviewWindow.SMHID1( "Preview" ); + maNumPagesText.SMHID1( "NumPagesText" ); + maPageEdit.SMHID1( "PageEdit" ); + maForwardBtn.SMHID1( "ForwardBtn" ); + maBackwardBtn.SMHID1( "BackwardBtn" ); + maTabCtrl.SMHID1( "TabPages" ); + + // append further tab pages + if( mbShowLayoutPage ) + { + maTabCtrl.InsertPage( SV_PRINT_TAB_NUP, maNUpPage.GetText() ); + maTabCtrl.SetTabPage( SV_PRINT_TAB_NUP, &maNUpPage ); + } + maTabCtrl.InsertPage( SV_PRINT_TAB_OPT, maOptionsPage.GetText() ); + maTabCtrl.SetTabPage( SV_PRINT_TAB_OPT, &maOptionsPage ); + + // restore settings from last run + readFromSettings(); + + // setup dependencies + checkControlDependencies(); + +} + +PrintDialog::~PrintDialog() +{ + while( ! maControls.empty() ) + { + delete maControls.front(); + maControls.pop_front(); + } +} + +void PrintDialog::setupLayout() +{ + Size aBorder( LogicToPixel( Size( 5, 5 ), MapMode( MAP_APPFONT ) ) ); + + maLayout.setParentWindow( this ); + + boost::shared_ptr< vcl::RowOrColumn > xPreviewAndTab( new vcl::RowOrColumn( &maLayout, false ) ); + size_t nIndex = maLayout.addChild( xPreviewAndTab, 5 ); + maLayout.setBorders( nIndex, aBorder.Width(), aBorder.Width(), aBorder.Width(), 0 ); + + // setup column for preview and sub controls + boost::shared_ptr< vcl::RowOrColumn > xPreview( new vcl::RowOrColumn( xPreviewAndTab.get() ) ); + xPreviewAndTab->addChild( xPreview, 5 ); + xPreview->addWindow( &maPreviewWindow, 5 ); + // get a row for the preview controls + mxPreviewCtrls.reset( new vcl::RowOrColumn( xPreview.get(), false ) ); + nIndex = xPreview->addChild( mxPreviewCtrls ); + boost::shared_ptr< vcl::Spacer > xSpacer( new vcl::Spacer( mxPreviewCtrls.get(), 2 ) ); + mxPreviewCtrls->addChild( xSpacer ); + mxPreviewCtrls->addWindow( &maPageEdit ); + mxPreviewCtrls->addWindow( &maNumPagesText ); + xSpacer.reset( new vcl::Spacer( mxPreviewCtrls.get(), 2 ) ); + mxPreviewCtrls->addChild( xSpacer ); + mxPreviewCtrls->addWindow( &maBackwardBtn ); + mxPreviewCtrls->addWindow( &maForwardBtn ); + xSpacer.reset( new vcl::Spacer( mxPreviewCtrls.get(), 2 ) ); + mxPreviewCtrls->addChild( xSpacer ); + + // continue with the tab ctrl + xPreviewAndTab->addWindow( &maTabCtrl ); + + // add the button line + maLayout.addWindow( &maButtonLine ); + + // add the row for the buttons + boost::shared_ptr< vcl::RowOrColumn > xButtons( new vcl::RowOrColumn( &maLayout, false ) ); + nIndex = maLayout.addChild( xButtons ); + maLayout.setBorders( nIndex, aBorder.Width(), 0, aBorder.Width(), aBorder.Width() ); + + Size aMinSize( maCancelButton.GetSizePixel() ); + // insert help button + xButtons->setMinimumSize( xButtons->addWindow( &maHelpButton ), aMinSize ); + // insert a spacer, cancel and OK buttons are right aligned + xSpacer.reset( new vcl::Spacer( xButtons.get(), 2 ) ); + xButtons->addChild( xSpacer ); + xButtons->setMinimumSize( xButtons->addWindow( &maOKButton ), aMinSize ); + xButtons->setMinimumSize( xButtons->addWindow( &maCancelButton ), aMinSize ); +} + +void PrintDialog::readFromSettings() +{ + maJobPage.readFromSettings(); + maNUpPage.readFromSettings(); + maOptionsPage.readFromSettings(); + + // read last selected tab page; if it exists, actiavte it + SettingsConfigItem* pItem = SettingsConfigItem::get(); + rtl::OUString aValue = pItem->getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintDialog" ) ), + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LastPage" ) ) ); + USHORT nCount = maTabCtrl.GetPageCount(); + for( USHORT i = 0; i < nCount; i++ ) + { + USHORT nPageId = maTabCtrl.GetPageId( i ); + if( aValue.equals( maTabCtrl.GetPageText( nPageId ) ) ) + { + maTabCtrl.SelectTabPage( nPageId ); + break; + } + } + maOKButton.SetText( maOptionsPage.maToFileBox.IsChecked() ? maPrintToFileText : maPrintText ); +} + +void PrintDialog::storeToSettings() +{ + maJobPage.storeToSettings(); + maNUpPage.storeToSettings(); + maOptionsPage.storeToSettings(); + + // store last selected printer + SettingsConfigItem* pItem = SettingsConfigItem::get(); + pItem->setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintDialog" ) ), + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LastPrinter" ) ), + maJobPage.maPrinters.GetSelectEntry() ); + + pItem->setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintDialog" ) ), + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LastPage" ) ), + maTabCtrl.GetPageText( maTabCtrl.GetCurPageId() ) ); + pItem->Commit(); +} + +bool PrintDialog::isPrintToFile() +{ + return maOptionsPage.maToFileBox.IsChecked(); +} + +int PrintDialog::getCopyCount() +{ + return static_cast<int>(maJobPage.maCopyCountField.GetValue()); +} + +bool PrintDialog::isCollate() +{ + return maJobPage.maCopyCountField.GetValue() > 1 ? maJobPage.maCollateBox.IsChecked() : FALSE; +} + +static void setSmartId( Window* i_pWindow, const char* i_pType, sal_Int32 i_nId = -1, const rtl::OUString& i_rPropName = rtl::OUString() ) +{ + rtl::OUStringBuffer aBuf( 256 ); + aBuf.appendAscii( HELPID_PREFIX ); + if( i_rPropName.getLength() ) + { + aBuf.append( sal_Unicode( ':' ) ); + aBuf.append( i_rPropName ); + } + if( i_pType ) + { + aBuf.append( sal_Unicode( ':' ) ); + aBuf.appendAscii( i_pType ); + } + if( i_nId >= 0 ) + { + aBuf.append( sal_Unicode( ':' ) ); + aBuf.append( i_nId ); + } + i_pWindow->SetSmartHelpId( SmartId( aBuf.makeStringAndClear(), HID_PRINTDLG ) ); +} + +static void setHelpText( Window* i_pWindow, const Sequence< rtl::OUString >& i_rHelpTexts, sal_Int32 i_nIndex ) +{ + if( i_nIndex >= 0 && i_nIndex < i_rHelpTexts.getLength() ) + i_pWindow->SetHelpText( i_rHelpTexts.getConstArray()[i_nIndex] ); +} + +void updateMaxSize( const Size& i_rCheckSize, Size& o_rMaxSize ) +{ + if( i_rCheckSize.Width() > o_rMaxSize.Width() ) + o_rMaxSize.Width() = i_rCheckSize.Width(); + if( i_rCheckSize.Height() > o_rMaxSize.Height() ) + o_rMaxSize.Height() = i_rCheckSize.Height(); +} + +void PrintDialog::setupOptionalUI() +{ + Size aBorder( LogicToPixel( Size( 5, 5 ), MapMode( MAP_APPFONT ) ) ); + + std::vector<vcl::RowOrColumn*> aDynamicColumns; + vcl::RowOrColumn* pCurColumn = 0; + + Window* pCurParent = 0, *pDynamicPageParent = 0; + USHORT nOptPageId = 9, nCurSubGroup = 0; + bool bOnStaticPage = false; + bool bSubgroupOnStaticPage = false; + + std::multimap< rtl::OUString, vcl::RowOrColumn* > aPropertyToDependencyRowMap; + + const Sequence< PropertyValue >& rOptions( maPController->getUIOptions() ); + for( int i = 0; i < rOptions.getLength(); i++ ) + { + Sequence< beans::PropertyValue > aOptProp; + rOptions[i].Value >>= aOptProp; + + // extract ui element + bool bEnabled = true; + rtl::OUString aCtrlType; + rtl::OUString aText; + rtl::OUString aPropertyName; + Sequence< rtl::OUString > aChoices; + Sequence< rtl::OUString > aHelpTexts; + sal_Int64 nMinValue = 0, nMaxValue = 0; + sal_Int32 nCurHelpText = 0; + rtl::OUString aGroupingHint; + rtl::OUString aDependsOnName; + sal_Int32 nDependsOnValue = 0; + sal_Bool bUseDependencyRow = sal_False; + + for( int n = 0; n < aOptProp.getLength(); n++ ) + { + const beans::PropertyValue& rEntry( aOptProp[ n ] ); + if( rEntry.Name.equalsAscii( "Text" ) ) + { + rEntry.Value >>= aText; + } + else if( rEntry.Name.equalsAscii( "ControlType" ) ) + { + rEntry.Value >>= aCtrlType; + } + else if( rEntry.Name.equalsAscii( "Choices" ) ) + { + rEntry.Value >>= aChoices; + } + else if( rEntry.Name.equalsAscii( "Property" ) ) + { + PropertyValue aVal; + rEntry.Value >>= aVal; + aPropertyName = aVal.Name; + } + else if( rEntry.Name.equalsAscii( "Enabled" ) ) + { + sal_Bool bValue = sal_True; + rEntry.Value >>= bValue; + bEnabled = bValue; + } + else if( rEntry.Name.equalsAscii( "GroupingHint" ) ) + { + rEntry.Value >>= aGroupingHint; + } + else if( rEntry.Name.equalsAscii( "DependsOnName" ) ) + { + rEntry.Value >>= aDependsOnName; + } + else if( rEntry.Name.equalsAscii( "DependsOnEntry" ) ) + { + rEntry.Value >>= nDependsOnValue; + } + else if( rEntry.Name.equalsAscii( "AttachToDependency" ) ) + { + rEntry.Value >>= bUseDependencyRow; + } + else if( rEntry.Name.equalsAscii( "MinValue" ) ) + { + rEntry.Value >>= nMinValue; + } + else if( rEntry.Name.equalsAscii( "MaxValue" ) ) + { + rEntry.Value >>= nMaxValue; + } + else if( rEntry.Name.equalsAscii( "HelpText" ) ) + { + if( ! (rEntry.Value >>= aHelpTexts) ) + { + rtl::OUString aHelpText; + if( (rEntry.Value >>= aHelpText) ) + { + aHelpTexts.realloc( 1 ); + *aHelpTexts.getArray() = aHelpText; + } + } + } + else if( rEntry.Name.equalsAscii( "HintNoLayoutPage" ) ) + { + sal_Bool bNoLayoutPage = sal_False; + rEntry.Value >>= bNoLayoutPage; + mbShowLayoutPage = ! bNoLayoutPage; + } + } + + // bUseDependencyRow should only be true if a dependency exists + bUseDependencyRow = bUseDependencyRow && (aDependsOnName.getLength() != 0); + + // is it necessary to switch between static and dynamic pages ? + bool bSwitchPage = false; + if( aGroupingHint.getLength() ) + bSwitchPage = true; + else if( aCtrlType.equalsAscii( "Subgroup" ) || (bOnStaticPage && ! bSubgroupOnStaticPage ) ) + bSwitchPage = true; + if( bSwitchPage ) + { + // restore to dynamic + pCurParent = pDynamicPageParent; + pCurColumn = aDynamicColumns.empty() ? NULL : aDynamicColumns.back(); + bOnStaticPage = false; + bSubgroupOnStaticPage = false; + + if( aGroupingHint.equalsAscii( "PrintRange" ) ) + { + pCurColumn = maJobPage.mxPrintRange.get(); + pCurParent = &maJobPage; // set job page as current parent + bOnStaticPage = true; + } + else if( aGroupingHint.equalsAscii( "OptionsPage" ) ) + { + pCurColumn = &maOptionsPage.maLayout; + pCurParent = &maOptionsPage; // set options page as current parent + bOnStaticPage = true; + } + else if( aGroupingHint.equalsAscii( "OptionsPageOptGroup" ) ) + { + pCurColumn = maOptionsPage.mxOptGroup.get(); + pCurParent = &maOptionsPage; // set options page as current parent + bOnStaticPage = true; + } + else if( aGroupingHint.equalsAscii( "LayoutPage" ) ) + { + pCurColumn = &maNUpPage.maLayout; + pCurParent = &maNUpPage; // set layout page as current parent + bOnStaticPage = true; + } + else if( aGroupingHint.getLength() ) + { + pCurColumn = &maJobPage.maLayout; + pCurParent = &maJobPage; // set job page as current parent + bOnStaticPage = true; + } + } + + if( aCtrlType.equalsAscii( "Group" ) || + ( ! pCurParent && ! (bOnStaticPage || aGroupingHint.getLength() ) ) ) + { + // add new tab page + TabPage* pNewGroup = new TabPage( &maTabCtrl ); + maControls.push_front( pNewGroup ); + pDynamicPageParent = pCurParent = pNewGroup; + pNewGroup->SetText( aText ); + maTabCtrl.InsertPage( ++nOptPageId, aText ); + maTabCtrl.SetTabPage( nOptPageId, pNewGroup ); + + // set help id + setSmartId( pNewGroup, "TabPage", nOptPageId ); + // set help text + setHelpText( pNewGroup, aHelpTexts, 0 ); + + // reset subgroup counter + nCurSubGroup = 0; + + aDynamicColumns.push_back( new vcl::RowOrColumn( NULL, true, aBorder.Width() ) ); + pCurColumn = aDynamicColumns.back(); + pCurColumn->setParentWindow( pNewGroup ); + pCurColumn->setOuterBorder( aBorder.Width() ); + bSubgroupOnStaticPage = false; + bOnStaticPage = false; + } + else if( aCtrlType.equalsAscii( "Subgroup" ) && (pCurParent || aGroupingHint.getLength() ) ) + { + bSubgroupOnStaticPage = (aGroupingHint.getLength() != 0); + // create group FixedLine + if( ! aGroupingHint.equalsAscii( "PrintRange" ) || + ! pCurColumn->countElements() == 0 + ) + { + Window* pNewSub = NULL; + if( aGroupingHint.equalsAscii( "PrintRange" ) ) + pNewSub = new FixedText( pCurParent, WB_VCENTER ); + else + pNewSub = new FixedLine( pCurParent ); + maControls.push_front( pNewSub ); + pNewSub->SetText( aText ); + pNewSub->Show(); + + // set help id + setSmartId( pNewSub, "FixedLine", sal_Int32( nCurSubGroup++ ) ); + // set help text + setHelpText( pNewSub, aHelpTexts, 0 ); + // add group to current column + pCurColumn->addWindow( pNewSub ); + } + + // add an indent to the current column + vcl::Indenter* pIndent = new vcl::Indenter( pCurColumn, aBorder.Width() ); + pCurColumn->addChild( pIndent ); + // and create a column inside the indent + pCurColumn = new vcl::RowOrColumn( pIndent ); + pIndent->setChild( pCurColumn ); + } + // EVIL + else if( aCtrlType.equalsAscii( "Bool" ) && + aGroupingHint.equalsAscii( "LayoutPage" ) && + aPropertyName.equalsAscii( "PrintProspect" ) + ) + { + maNUpPage.maBrochureBtn.SetText( aText ); + maNUpPage.maBrochureBtn.Show(); + setHelpText( &maNUpPage.maBrochureBtn, aHelpTexts, 0 ); + + sal_Bool bVal = sal_False; + PropertyValue* pVal = maPController->getValue( aPropertyName ); + if( pVal ) + pVal->Value >>= bVal; + maNUpPage.maBrochureBtn.Check( bVal ); + maNUpPage.maBrochureBtn.Enable( maPController->isUIOptionEnabled( aPropertyName ) && pVal != NULL ); + maNUpPage.maBrochureBtn.SetToggleHdl( LINK( this, PrintDialog, ClickHdl ) ); + + maPropertyToWindowMap[ aPropertyName ].push_back( &maNUpPage.maBrochureBtn ); + maControlToPropertyMap[&maNUpPage.maBrochureBtn] = aPropertyName; + + aPropertyToDependencyRowMap.insert( std::pair< rtl::OUString, vcl::RowOrColumn* >( aPropertyName, maNUpPage.mxBrochureDep.get() ) ); + } + else + { + vcl::RowOrColumn* pSaveCurColumn = pCurColumn; + + if( bUseDependencyRow ) + { + // find the correct dependency row (if any) + std::pair< std::multimap< rtl::OUString, vcl::RowOrColumn* >::iterator, + std::multimap< rtl::OUString, vcl::RowOrColumn* >::iterator > aDepRange; + aDepRange = aPropertyToDependencyRowMap.equal_range( aDependsOnName ); + if( aDepRange.first != aDepRange.second ) + { + while( nDependsOnValue && aDepRange.first != aDepRange.second ) + { + nDependsOnValue--; + ++aDepRange.first; + } + if( aDepRange.first != aPropertyToDependencyRowMap.end() ) + { + pCurColumn = aDepRange.first->second; + maReverseDependencySet.insert( aPropertyName ); + } + } + } + if( aCtrlType.equalsAscii( "Bool" ) && pCurParent ) + { + // add a check box + CheckBox* pNewBox = new CheckBox( pCurParent ); + maControls.push_front( pNewBox ); + pNewBox->SetText( aText ); + pNewBox->Show(); + + sal_Bool bVal = sal_False; + PropertyValue* pVal = maPController->getValue( aPropertyName ); + if( pVal ) + pVal->Value >>= bVal; + pNewBox->Check( bVal ); + pNewBox->SetToggleHdl( LINK( this, PrintDialog, UIOption_CheckHdl ) ); + + maPropertyToWindowMap[ aPropertyName ].push_back( pNewBox ); + maControlToPropertyMap[pNewBox] = aPropertyName; + + // set help id + setSmartId( pNewBox, "CheckBox", -1, aPropertyName ); + // set help text + setHelpText( pNewBox, aHelpTexts, 0 ); + + vcl::RowOrColumn* pDependencyRow = new vcl::RowOrColumn( pCurColumn, false ); + pCurColumn->addChild( pDependencyRow ); + aPropertyToDependencyRowMap.insert( std::pair< rtl::OUString, vcl::RowOrColumn* >( aPropertyName, pDependencyRow ) ); + + // add checkbox to current column + pDependencyRow->addWindow( pNewBox ); + } + else if( aCtrlType.equalsAscii( "Radio" ) && pCurParent ) + { + vcl::RowOrColumn* pRadioColumn = pCurColumn; + if( aText.getLength() ) + { + // add a FixedText: + FixedText* pHeading = new FixedText( pCurParent ); + maControls.push_front( pHeading ); + pHeading->SetText( aText ); + pHeading->Show(); + + // set help id + setSmartId( pHeading, "FixedText", -1, aPropertyName ); + // set help text + setHelpText( pHeading, aHelpTexts, nCurHelpText++ ); + // add fixed text to current column + pCurColumn->addWindow( pHeading ); + // add an indent to the current column + vcl::Indenter* pIndent = new vcl::Indenter( pCurColumn, 15 ); + pCurColumn->addChild( pIndent ); + // and create a column inside the indent + pRadioColumn = new vcl::RowOrColumn( pIndent ); + pIndent->setChild( pRadioColumn ); + } + // iterate options + sal_Int32 nSelectVal = 0; + PropertyValue* pVal = maPController->getValue( aPropertyName ); + if( pVal && pVal->Value.hasValue() ) + pVal->Value >>= nSelectVal; + for( sal_Int32 m = 0; m < aChoices.getLength(); m++ ) + { + boost::shared_ptr<vcl::LabeledElement> pLabel( new vcl::LabeledElement( pRadioColumn, 1 ) ); + pRadioColumn->addChild( pLabel ); + boost::shared_ptr<vcl::RowOrColumn> pDependencyRow( new vcl::RowOrColumn( pLabel.get(), false ) ); + pLabel->setElement( pDependencyRow ); + aPropertyToDependencyRowMap.insert( std::pair< rtl::OUString, vcl::RowOrColumn* >( aPropertyName, pDependencyRow.get() ) ); + + RadioButton* pBtn = new RadioButton( pCurParent, m == 0 ? WB_GROUP : 0 ); + maControls.push_front( pBtn ); + pBtn->SetText( aChoices[m] ); + pBtn->Check( m == nSelectVal ); + pBtn->SetToggleHdl( LINK( this, PrintDialog, UIOption_RadioHdl ) ); + pBtn->Show(); + maPropertyToWindowMap[ aPropertyName ].push_back( pBtn ); + maControlToPropertyMap[pBtn] = aPropertyName; + maControlToNumValMap[pBtn] = m; + + // set help id + setSmartId( pBtn, "RadioButton", m, aPropertyName ); + // set help text + setHelpText( pBtn, aHelpTexts, nCurHelpText++ ); + // add the radio button to the column + pLabel->setLabel( pBtn ); + } + } + else if( ( aCtrlType.equalsAscii( "List" ) || + aCtrlType.equalsAscii( "Range" ) || + aCtrlType.equalsAscii( "Edit" ) + ) && pCurParent ) + { + // create a row in the current column + vcl::RowOrColumn* pFieldColumn = new vcl::RowOrColumn( pCurColumn, false ); + pCurColumn->addChild( pFieldColumn ); + aPropertyToDependencyRowMap.insert( std::pair< rtl::OUString, vcl::RowOrColumn* >( aPropertyName, pFieldColumn ) ); + + vcl::LabeledElement* pLabel = NULL; + if( aText.getLength() ) + { + // add a FixedText: + FixedText* pHeading = new FixedText( pCurParent, WB_VCENTER ); + maControls.push_front( pHeading ); + pHeading->SetText( aText ); + pHeading->Show(); + + // set help id + setSmartId( pHeading, "FixedText", -1, aPropertyName ); + + // add to row + pLabel = new vcl::LabeledElement( pFieldColumn, 2 ); + pFieldColumn->addChild( pLabel ); + pLabel->setLabel( pHeading ); + } + + if( aCtrlType.equalsAscii( "List" ) ) + { + ListBox* pList = new ListBox( pCurParent, WB_DROPDOWN | WB_BORDER ); + maControls.push_front( pList ); + + // iterate options + for( sal_Int32 m = 0; m < aChoices.getLength(); m++ ) + { + pList->InsertEntry( aChoices[m] ); + } + sal_Int32 nSelectVal = 0; + PropertyValue* pVal = maPController->getValue( aPropertyName ); + if( pVal && pVal->Value.hasValue() ) + pVal->Value >>= nSelectVal; + pList->SelectEntryPos( static_cast<USHORT>(nSelectVal) ); + pList->SetSelectHdl( LINK( this, PrintDialog, UIOption_SelectHdl ) ); + pList->SetDropDownLineCount( static_cast<USHORT>(aChoices.getLength()) ); + pList->Show(); + + // set help id + setSmartId( pList, "ListBox", -1, aPropertyName ); + // set help text + setHelpText( pList, aHelpTexts, 0 ); + + maPropertyToWindowMap[ aPropertyName ].push_back( pList ); + maControlToPropertyMap[pList] = aPropertyName; + + // finish the pair + if( pLabel ) + pLabel->setElement( pList ); + else + pFieldColumn->addWindow( pList ); + } + else if( aCtrlType.equalsAscii( "Range" ) ) + { + NumericField* pField = new NumericField( pCurParent, WB_BORDER | WB_SPIN ); + maControls.push_front( pField ); + + // set min/max and current value + if( nMinValue != nMaxValue ) + { + pField->SetMin( nMinValue ); + pField->SetMax( nMaxValue ); + } + sal_Int64 nCurVal = 0; + PropertyValue* pVal = maPController->getValue( aPropertyName ); + if( pVal && pVal->Value.hasValue() ) + pVal->Value >>= nCurVal; + pField->SetValue( nCurVal ); + pField->SetModifyHdl( LINK( this, PrintDialog, UIOption_ModifyHdl ) ); + pField->Show(); + + // set help id + setSmartId( pField, "NumericField", -1, aPropertyName ); + // set help text + setHelpText( pField, aHelpTexts, 0 ); + + maPropertyToWindowMap[ aPropertyName ].push_back( pField ); + maControlToPropertyMap[pField] = aPropertyName; + + // add to row + if( pLabel ) + pLabel->setElement( pField ); + else + pFieldColumn->addWindow( pField ); + } + else if( aCtrlType.equalsAscii( "Edit" ) ) + { + Edit* pField = new Edit( pCurParent, WB_BORDER ); + maControls.push_front( pField ); + + rtl::OUString aCurVal; + PropertyValue* pVal = maPController->getValue( aPropertyName ); + if( pVal && pVal->Value.hasValue() ) + pVal->Value >>= aCurVal; + pField->SetText( aCurVal ); + pField->SetModifyHdl( LINK( this, PrintDialog, UIOption_ModifyHdl ) ); + pField->Show(); + + // set help id + setSmartId( pField, "Edit", -1, aPropertyName ); + // set help text + setHelpText( pField, aHelpTexts, 0 ); + + maPropertyToWindowMap[ aPropertyName ].push_back( pField ); + maControlToPropertyMap[pField] = aPropertyName; + + // add to row + if( pLabel ) + pLabel->setElement( pField ); + else + pFieldColumn->addWindow( pField, 2 ); + } + } + else + { + DBG_ERROR( "Unsupported UI option" ); + } + + pCurColumn = pSaveCurColumn; + } + } + + // #i106506# if no brochure button, then the singular Pages radio button + // makes no sense, so replace it by a FixedText label + if( ! maNUpPage.maBrochureBtn.IsVisible() ) + { + if( maNUpPage.mxPagesBtnLabel.get() ) + { + maNUpPage.maPagesBoxTitleTxt.SetText( maNUpPage.maPagesBtn.GetText() ); + maNUpPage.maPagesBoxTitleTxt.Show( TRUE ); + maNUpPage.mxPagesBtnLabel->setLabel( &maNUpPage.maPagesBoxTitleTxt ); + maNUpPage.maPagesBtn.Show( FALSE ); + } + } + + // update enable states + checkOptionalControlDependencies(); + + // print range empty (currently math only) -> hide print range and spacer line + if( maJobPage.mxPrintRange->countElements() == 0 ) + { + maJobPage.mxPrintRange->show( false, false ); + maJobPage.maCopySpacer.Show( FALSE ); + } + +#ifdef WNT + // FIXME: the GetNativeControlRegion call on Windows has some issues + // (which skew the results of GetOptimalSize()) + // however fixing this thoroughly needs to take interaction with paint into + // acoount, making the right fix less simple. Fix this the right way + // at some point. For now simply add some space at the lowest element + size_t nIndex = maJobPage.maLayout.countElements(); + if( nIndex > 0 ) // sanity check + maJobPage.maLayout.setBorders( nIndex-1, 0, 0, 0, aBorder.Width() ); +#endif + + // calculate job page + Size aMaxSize = maJobPage.maLayout.getOptimalSize( WINDOWSIZE_PREFERRED ); + // and layout page + updateMaxSize( maNUpPage.maLayout.getOptimalSize( WINDOWSIZE_PREFERRED ), aMaxSize ); + // and options page + updateMaxSize( maOptionsPage.maLayout.getOptimalSize( WINDOWSIZE_PREFERRED ), aMaxSize ); + + for( std::vector< vcl::RowOrColumn* >::iterator it = aDynamicColumns.begin(); + it != aDynamicColumns.end(); ++it ) + { + Size aPageSize( (*it)->getOptimalSize( WINDOWSIZE_PREFERRED ) ); + updateMaxSize( aPageSize, aMaxSize ); + } + + // resize dialog if necessary + Size aTabSize = maTabCtrl.GetTabPageSizePixel(); + maTabCtrl.SetMinimumSizePixel( maTabCtrl.GetSizePixel() ); + if( aMaxSize.Height() > aTabSize.Height() || aMaxSize.Width() > aTabSize.Width() ) + { + Size aCurSize( GetOutputSizePixel() ); + if( aMaxSize.Height() > aTabSize.Height() ) + { + aCurSize.Height() += aMaxSize.Height() - aTabSize.Height(); + aTabSize.Height() = aMaxSize.Height(); + } + if( aMaxSize.Width() > aTabSize.Width() ) + { + aCurSize.Width() += aMaxSize.Width() - aTabSize.Width(); + // and the tab ctrl needs more space, too + aTabSize.Width() = aMaxSize.Width(); + } + maTabCtrl.SetTabPageSizePixel( aTabSize ); + maTabCtrl.SetMinimumSizePixel( maTabCtrl.GetSizePixel() ); + } + + // and finally arrange controls + for( std::vector< vcl::RowOrColumn* >::iterator it = aDynamicColumns.begin(); + it != aDynamicColumns.end(); ++it ) + { + (*it)->setManagedArea( Rectangle( Point(), aTabSize ) ); + delete *it; + *it = NULL; + } + maJobPage.Resize(); + maNUpPage.Resize(); + maOptionsPage.Resize(); + + Size aSz = maLayout.getOptimalSize( WINDOWSIZE_PREFERRED ); + SetOutputSizePixel( aSz ); +} + +void PrintDialog::DataChanged( const DataChangedEvent& i_rDCEvt ) +{ + // react on settings changed + if( i_rDCEvt.GetType() == DATACHANGED_SETTINGS ) + checkControlDependencies(); + ModalDialog::DataChanged( i_rDCEvt ); +} + +void PrintDialog::checkControlDependencies() +{ + if( maJobPage.maCopyCountField.GetValue() > 1 ) + maJobPage.maCollateBox.Enable( maJobPage.mnCollateUIMode == 0 ); + else + maJobPage.maCollateBox.Enable( FALSE ); + + Image aImg( maJobPage.maCollateBox.IsChecked() ? maJobPage.maCollateImg : maJobPage.maNoCollateImg ); + Image aHCImg( maJobPage.maCollateBox.IsChecked() ? maJobPage.maCollateHCImg : maJobPage.maNoCollateHCImg ); + bool bHC = GetSettings().GetStyleSettings().GetHighContrastMode(); + + Size aImgSize( aImg.GetSizePixel() ); + Size aHCImgSize( aHCImg.GetSizePixel() ); + + if( aHCImgSize.Width() > aImgSize.Width() ) + aImgSize.Width() = aHCImgSize.Width(); + if( aHCImgSize.Height() > aImgSize.Height() ) + aImgSize.Height() = aHCImgSize.Height(); + + // adjust size of image + maJobPage.maCollateImage.SetSizePixel( aImgSize ); + maJobPage.maCollateImage.SetImage( bHC ? aHCImg : aImg ); + maJobPage.maCollateImage.SetModeImage( aHCImg, BMP_COLOR_HIGHCONTRAST ); + + // enable setup button only for printers that can be setup + bool bHaveSetup = maPController->getPrinter()->HasSupport( SUPPORT_SETUPDIALOG ); + maJobPage.maSetupButton.Enable( bHaveSetup ); + if( bHaveSetup ) + { + if( ! maJobPage.maSetupButton.IsVisible() ) + { + Point aPrinterPos( maJobPage.maPrinters.GetPosPixel() ); + Point aSetupPos( maJobPage.maSetupButton.GetPosPixel() ); + Size aPrinterSize( maJobPage.maPrinters.GetSizePixel() ); + aPrinterSize.Width() = aSetupPos.X() - aPrinterPos.X() - LogicToPixel( Size( 5, 5 ), MapMode( MAP_APPFONT ) ).Width(); + maJobPage.maPrinters.SetSizePixel( aPrinterSize ); + maJobPage.maSetupButton.Show(); + maLayout.resize(); + } + } + else + { + if( maJobPage.maSetupButton.IsVisible() ) + { + Point aPrinterPos( maJobPage.maPrinters.GetPosPixel() ); + Point aSetupPos( maJobPage.maSetupButton.GetPosPixel() ); + Size aPrinterSize( maJobPage.maPrinters.GetSizePixel() ); + Size aSetupSize( maJobPage.maSetupButton.GetSizePixel() ); + aPrinterSize.Width() = aSetupPos.X() + aSetupSize.Width() - aPrinterPos.X(); + maJobPage.maPrinters.SetSizePixel( aPrinterSize ); + maJobPage.maSetupButton.Hide(); + maLayout.resize(); + } + } +} + +void PrintDialog::checkOptionalControlDependencies() +{ + for( std::map< Window*, rtl::OUString >::iterator it = maControlToPropertyMap.begin(); + it != maControlToPropertyMap.end(); ++it ) + { + bool bShouldbeEnabled = maPController->isUIOptionEnabled( it->second ); + if( ! bShouldbeEnabled ) + { + // enable controls that are directly attached to a dependency anyway + // if the normally disabled controls get modified, change the dependency + // so the control would be enabled + // example: in print range "Print All" is selected, "Page Range" is then of course + // not selected and the Edit for the Page Range would be disabled + // as a convenience we should enable the Edit anyway and automatically select + // "Page Range" instead of "Print All" if the Edit gets modified + if( maReverseDependencySet.find( it->second ) != maReverseDependencySet.end() ) + { + rtl::OUString aDep( maPController->getDependency( it->second ) ); + // if the dependency is at least enabled, then enable this control anyway + if( aDep.getLength() && maPController->isUIOptionEnabled( aDep ) ) + bShouldbeEnabled = true; + } + } + + bool bIsEnabled = it->first->IsEnabled(); + // Enable does not do a change check first, so can be less cheap than expected + if( bShouldbeEnabled != bIsEnabled ) + it->first->Enable( bShouldbeEnabled ); + } +} + +static rtl::OUString searchAndReplace( const rtl::OUString& i_rOrig, const char* i_pRepl, sal_Int32 i_nReplLen, const rtl::OUString& i_rRepl ) +{ + sal_Int32 nPos = i_rOrig.indexOfAsciiL( i_pRepl, i_nReplLen ); + if( nPos != -1 ) + { + rtl::OUStringBuffer aBuf( i_rOrig.getLength() ); + aBuf.append( i_rOrig.getStr(), nPos ); + aBuf.append( i_rRepl ); + if( nPos + i_nReplLen < i_rOrig.getLength() ) + aBuf.append( i_rOrig.getStr() + nPos + i_nReplLen ); + return aBuf.makeStringAndClear(); + } + return i_rOrig; +} + +void PrintDialog::updatePrinterText() +{ + String aDefPrt( Printer::GetDefaultPrinterName() ); + const QueueInfo* pInfo = Printer::GetQueueInfo( maJobPage.maPrinters.GetSelectEntry(), true ); + if( pInfo ) + { + maJobPage.maLocationTxt.SetText( pInfo->GetLocation() ); + maJobPage.maCommentTxt.SetText( pInfo->GetComment() ); + // FIXME: status text + rtl::OUString aStatus; + if( aDefPrt == pInfo->GetPrinterName() ) + aStatus = maDefPrtText; + maJobPage.maStatusTxt.SetText( aStatus ); + } + else + { + maJobPage.maLocationTxt.SetText( String() ); + maJobPage.maCommentTxt.SetText( String() ); + maJobPage.maStatusTxt.SetText( String() ); + } +} + +void PrintDialog::setPreviewText( sal_Int32 ) +{ + rtl::OUString aNewText( searchAndReplace( maPageStr, "%n", 2, rtl::OUString::valueOf( mnCachedPages ) ) ); + maNumPagesText.SetText( aNewText ); + + // if layout is already established the refresh layout of + // preview controls since text length may have changes + if( mxPreviewCtrls.get() ) + mxPreviewCtrls->setManagedArea( mxPreviewCtrls->getManagedArea() ); +} + +void PrintDialog::preparePreview( bool i_bNewPage, bool i_bMayUseCache ) +{ + // page range may have changed depending on options + sal_Int32 nPages = maPController->getFilteredPageCount(); + mnCachedPages = nPages; + + if( mnCurPage >= nPages ) + mnCurPage = nPages-1; + if( mnCurPage < 0 ) + mnCurPage = 0; + + setPreviewText( mnCurPage ); + + maPageEdit.SetMin( 1 ); + maPageEdit.SetMax( nPages ); + + if( i_bNewPage ) + { + const MapMode aMapMode( MAP_100TH_MM ); + GDIMetaFile aMtf; + boost::shared_ptr<Printer> aPrt( maPController->getPrinter() ); + if( nPages > 0 ) + { + PrinterController::PageSize aPageSize = + maPController->getFilteredPageFile( mnCurPage, aMtf, i_bMayUseCache ); + if( ! aPageSize.bFullPaper ) + { + Point aOff( aPrt->PixelToLogic( aPrt->GetPageOffsetPixel(), aMapMode ) ); + aMtf.Move( aOff.X(), aOff.Y() ); + } + } + + Size aCurPageSize = aPrt->PixelToLogic( aPrt->GetPaperSizePixel(), MapMode( MAP_100TH_MM ) ); + maPreviewWindow.setPreview( aMtf, aCurPageSize, nPages > 0 ? rtl::OUString() : maNoPageStr, + aPrt->ImplGetDPIX(), aPrt->ImplGetDPIY() + ); + + maForwardBtn.Enable( mnCurPage < nPages-1 ); + maBackwardBtn.Enable( mnCurPage != 0 ); + maPageEdit.Enable( nPages > 1 ); + } +} + +Size PrintDialog::getJobPageSize() +{ + if( maFirstPageSize.Width() == 0 && maFirstPageSize.Height() == 0) + { + maFirstPageSize = maNupPortraitSize; + GDIMetaFile aMtf; + if( maPController->getPageCountProtected() > 0 ) + { + PrinterController::PageSize aPageSize = maPController->getPageFile( 0, aMtf, true ); + maFirstPageSize = aPageSize.aSize; + } + } + return maFirstPageSize; +} + +void PrintDialog::updateNupFromPages() +{ + long nPages = long(maNUpPage.maNupPagesBox.GetEntryData(maNUpPage.maNupPagesBox.GetSelectEntryPos())); + int nRows = int(maNUpPage.maNupRowsEdt.GetValue()); + int nCols = int(maNUpPage.maNupColEdt.GetValue()); + long nPageMargin = long(maNUpPage.maPageMarginEdt.Denormalize(maNUpPage.maPageMarginEdt.GetValue( FUNIT_100TH_MM ))); + long nSheetMargin = long(maNUpPage.maSheetMarginEdt.Denormalize(maNUpPage.maSheetMarginEdt.GetValue( FUNIT_100TH_MM ))); + bool bCustom = false; + + if( nPages == 1 ) + { + nRows = nCols = 1; + nSheetMargin = 0; + nPageMargin = 0; + } + else if( nPages == 2 || nPages == 4 || nPages == 6 || nPages == 9 || nPages == 16 ) + { + Size aJobPageSize( getJobPageSize() ); + bool bPortrait = aJobPageSize.Width() < aJobPageSize.Height(); + if( nPages == 2 ) + { + if( bPortrait ) + nRows = 1, nCols = 2; + else + nRows = 2, nCols = 1; + } + else if( nPages == 4 ) + nRows = nCols = 2; + else if( nPages == 6 ) + { + if( bPortrait ) + nRows = 2, nCols = 3; + else + nRows = 3, nCols = 2; + } + else if( nPages == 9 ) + nRows = nCols = 3; + else if( nPages == 16 ) + nRows = nCols = 4; + nPageMargin = 0; + nSheetMargin = 0; + } + else + bCustom = true; + + if( nPages > 1 ) + { + // set upper limits for margins based on job page size and rows/columns + Size aSize( getJobPageSize() ); + + // maximum sheet distance: 1/2 sheet + long nHorzMax = aSize.Width()/2; + long nVertMax = aSize.Height()/2; + if( nSheetMargin > nHorzMax ) + nSheetMargin = nHorzMax; + if( nSheetMargin > nVertMax ) + nSheetMargin = nVertMax; + + maNUpPage.maSheetMarginEdt.SetMax( + maNUpPage.maSheetMarginEdt.Normalize( + nHorzMax > nVertMax ? nVertMax : nHorzMax ), FUNIT_100TH_MM ); + + // maximum page distance + nHorzMax = (aSize.Width() - 2*nSheetMargin); + if( nCols > 1 ) + nHorzMax /= (nCols-1); + nVertMax = (aSize.Height() - 2*nSheetMargin); + if( nRows > 1 ) + nHorzMax /= (nRows-1); + + if( nPageMargin > nHorzMax ) + nPageMargin = nHorzMax; + if( nPageMargin > nVertMax ) + nPageMargin = nVertMax; + + maNUpPage.maPageMarginEdt.SetMax( + maNUpPage.maSheetMarginEdt.Normalize( + nHorzMax > nVertMax ? nVertMax : nHorzMax ), FUNIT_100TH_MM ); + } + + maNUpPage.maNupRowsEdt.SetValue( nRows ); + maNUpPage.maNupColEdt.SetValue( nCols ); + maNUpPage.maPageMarginEdt.SetValue( maNUpPage.maPageMarginEdt.Normalize( nPageMargin ), FUNIT_100TH_MM ); + maNUpPage.maSheetMarginEdt.SetValue( maNUpPage.maSheetMarginEdt.Normalize( nSheetMargin ), FUNIT_100TH_MM ); + + maNUpPage.showAdvancedControls( bCustom ); + if( bCustom ) + { + // see if we have to enlarge the dialog to make the tab page fit + Size aCurSize( maNUpPage.maLayout.getOptimalSize( WINDOWSIZE_PREFERRED ) ); + Size aTabSize( maTabCtrl.GetTabPageSizePixel() ); + if( aTabSize.Height() < aCurSize.Height() ) + { + Size aDlgSize( GetSizePixel() ); + aDlgSize.Height() += aCurSize.Height() - aTabSize.Height(); + SetSizePixel( aDlgSize ); + } + } + + updateNup(); +} + +void PrintDialog::updateNup() +{ + int nRows = int(maNUpPage.maNupRowsEdt.GetValue()); + int nCols = int(maNUpPage.maNupColEdt.GetValue()); + long nPageMargin = long(maNUpPage.maPageMarginEdt.Denormalize(maNUpPage.maPageMarginEdt.GetValue( FUNIT_100TH_MM ))); + long nSheetMargin = long(maNUpPage.maSheetMarginEdt.Denormalize(maNUpPage.maSheetMarginEdt.GetValue( FUNIT_100TH_MM ))); + + PrinterController::MultiPageSetup aMPS; + aMPS.nRows = nRows; + aMPS.nColumns = nCols; + aMPS.nRepeat = 1; + aMPS.nLeftMargin = + aMPS.nTopMargin = + aMPS.nRightMargin = + aMPS.nBottomMargin = nSheetMargin; + + aMPS.nHorizontalSpacing = + aMPS.nVerticalSpacing = nPageMargin; + + aMPS.bDrawBorder = maNUpPage.maBorderCB.IsChecked(); + + int nOrderMode = int(sal_IntPtr(maNUpPage.maNupOrderBox.GetEntryData( + maNUpPage.maNupOrderBox.GetSelectEntryPos() ))); + if( nOrderMode == SV_PRINT_PRT_NUP_ORDER_LRTD ) + aMPS.nOrder = PrinterController::LRTB; + else if( nOrderMode == SV_PRINT_PRT_NUP_ORDER_TDLR ) + aMPS.nOrder = PrinterController::TBLR; + + int nOrientationMode = int(sal_IntPtr(maNUpPage.maNupOrientationBox.GetEntryData( + maNUpPage.maNupOrientationBox.GetSelectEntryPos() ))); + if( nOrientationMode == SV_PRINT_PRT_NUP_ORIENTATION_LANDSCAPE ) + aMPS.aPaperSize = maNupLandscapeSize; + else if( nOrientationMode == SV_PRINT_PRT_NUP_ORIENTATION_PORTRAIT ) + aMPS.aPaperSize = maNupPortraitSize; + else // automatic mode + { + // get size of first real page to see if it is portrait or landscape + // we assume same page sizes for all the pages for this + Size aPageSize = getJobPageSize(); + + Size aMultiSize( aPageSize.Width() * nCols, aPageSize.Height() * nRows ); + if( aMultiSize.Width() > aMultiSize.Height() ) // fits better on landscape + aMPS.aPaperSize = maNupLandscapeSize; + else + aMPS.aPaperSize = maNupPortraitSize; + } + + maPController->setMultipage( aMPS ); + + maNUpPage.maNupOrderWin.setValues( nOrderMode, nCols, nRows ); + + preparePreview( true, true ); +} + +IMPL_LINK( PrintDialog, SelectHdl, ListBox*, pBox ) +{ + if( pBox == &maJobPage.maPrinters ) + { + String aNewPrinter( pBox->GetSelectEntry() ); + // set new printer + maPController->setPrinter( boost::shared_ptr<Printer>( new Printer( aNewPrinter ) ) ); + // update text fields + updatePrinterText(); + } + else if( pBox == &maNUpPage.maNupOrientationBox || pBox == &maNUpPage.maNupOrderBox ) + { + updateNup(); + } + else if( pBox == &maNUpPage.maNupPagesBox ) + { + if( !maNUpPage.maPagesBtn.IsChecked() ) + maNUpPage.maPagesBtn.Check(); + updateNupFromPages(); + } + + return 0; +} + +IMPL_LINK( PrintDialog, ClickHdl, Button*, pButton ) +{ + if( pButton == &maOKButton || pButton == &maCancelButton ) + { + storeToSettings(); + EndDialog( pButton == &maOKButton ); + } + else if( pButton == &maHelpButton ) + { + // start help system + Help* pHelp = Application::GetHelp(); + if( pHelp ) + { + // FIXME: find out proper help URL and use here + pHelp->Start( HID_PRINTDLG, GetParent() ); + } + } + else if( pButton == &maForwardBtn ) + { + previewForward(); + } + else if( pButton == &maBackwardBtn ) + { + previewBackward(); + } + else if( pButton == &maOptionsPage.maToFileBox ) + { + maOKButton.SetText( maOptionsPage.maToFileBox.IsChecked() ? maPrintToFileText : maPrintText ); + maLayout.resize(); + } + else if( pButton == &maNUpPage.maBrochureBtn ) + { + PropertyValue* pVal = getValueForWindow( pButton ); + if( pVal ) + { + sal_Bool bVal = maNUpPage.maBrochureBtn.IsChecked(); + pVal->Value <<= bVal; + + checkOptionalControlDependencies(); + + // update preview and page settings + preparePreview(); + } + if( maNUpPage.maBrochureBtn.IsChecked() ) + { + maNUpPage.maNupPagesBox.SelectEntryPos( 0 ); + updateNupFromPages(); + maNUpPage.showAdvancedControls( false ); + maNUpPage.enableNupControls( false ); + } + } + else if( pButton == &maNUpPage.maPagesBtn ) + { + maNUpPage.enableNupControls( true ); + updateNupFromPages(); + } + else if( pButton == &maJobPage.maDetailsBtn ) + { + bool bShow = maJobPage.maDetailsBtn.IsChecked(); + maJobPage.mxDetails->show( bShow ); + if( bShow ) + { + maDetailsCollapsedSize = GetOutputSizePixel(); + // enlarge dialog if necessary + Size aMinSize( maJobPage.maLayout.getOptimalSize( WINDOWSIZE_MINIMUM ) ); + Size aCurSize( maJobPage.GetSizePixel() ); + if( aCurSize.Height() < aMinSize.Height() ) + { + Size aDlgSize( GetOutputSizePixel() ); + aDlgSize.Height() += aMinSize.Height() - aCurSize.Height(); + SetOutputSizePixel( aDlgSize ); + } + maDetailsExpandedSize = GetOutputSizePixel(); + } + else if( maDetailsCollapsedSize.Width() > 0 && + maDetailsCollapsedSize.Height() > 0 ) + { + // if the user did not resize the dialog + // make it smaller again on collapsing the details + Size aDlgSize( GetOutputSizePixel() ); + if( aDlgSize == maDetailsExpandedSize && + aDlgSize.Height() > maDetailsCollapsedSize.Height() ) + { + SetOutputSizePixel( maDetailsCollapsedSize ); + } + } + } + else if( pButton == &maJobPage.maCollateBox ) + { + maPController->setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Collate" ) ), + makeAny( sal_Bool(isCollate()) ) ); + checkControlDependencies(); + } + else if( pButton == &maOptionsPage.maReverseOrderBox ) + { + sal_Bool bChecked = maOptionsPage.maReverseOrderBox.IsChecked(); + maPController->setReversePrint( bChecked ); + maPController->setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintReverse" ) ), + makeAny( bChecked ) ); + preparePreview( true, true ); + } + else if( pButton == &maNUpPage.maBorderCB ) + { + updateNup(); + } + else + { + if( pButton == &maJobPage.maSetupButton ) + { + maPController->setupPrinter( this ); + preparePreview( true, true ); + } + checkControlDependencies(); + } + return 0; +} + +IMPL_LINK( PrintDialog, ModifyHdl, Edit*, pEdit ) +{ + checkControlDependencies(); + if( pEdit == &maNUpPage.maNupRowsEdt || pEdit == &maNUpPage.maNupColEdt || + pEdit == &maNUpPage.maSheetMarginEdt || pEdit == &maNUpPage.maPageMarginEdt + ) + { + updateNupFromPages(); + } + else if( pEdit == &maPageEdit ) + { + mnCurPage = sal_Int32( maPageEdit.GetValue() - 1 ); + preparePreview( true, true ); + } + else if( pEdit == &maJobPage.maCopyCountField ) + { + maPController->setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CopyCount" ) ), + makeAny( sal_Int32(maJobPage.maCopyCountField.GetValue()) ) ); + maPController->setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Collate" ) ), + makeAny( sal_Bool(isCollate()) ) ); + } + return 0; +} + +IMPL_LINK( PrintDialog, UIOptionsChanged, void*, EMPTYARG ) +{ + checkOptionalControlDependencies(); + return 0; +} + +PropertyValue* PrintDialog::getValueForWindow( Window* i_pWindow ) const +{ + PropertyValue* pVal = NULL; + std::map< Window*, rtl::OUString >::const_iterator it = maControlToPropertyMap.find( i_pWindow ); + if( it != maControlToPropertyMap.end() ) + { + pVal = maPController->getValue( it->second ); + DBG_ASSERT( pVal, "property value not found" ); + } + else + { + DBG_ERROR( "changed control not in property map" ); + } + return pVal; +} + +void PrintDialog::updateWindowFromProperty( const rtl::OUString& i_rProperty ) +{ + beans::PropertyValue* pValue = maPController->getValue( i_rProperty ); + std::map< rtl::OUString, std::vector< Window* > >::const_iterator it = maPropertyToWindowMap.find( i_rProperty ); + if( pValue && it != maPropertyToWindowMap.end() ) + { + const std::vector< Window* >& rWindows( it->second ); + if( ! rWindows.empty() ) + { + sal_Bool bVal = sal_False; + sal_Int32 nVal = -1; + if( pValue->Value >>= bVal ) + { + // we should have a CheckBox for this one + CheckBox* pBox = dynamic_cast< CheckBox* >( rWindows.front() ); + if( pBox ) + { + pBox->Check( bVal ); + } + else if( i_rProperty.equalsAscii( "PrintProspect" ) ) + { + // EVIL special case + if( bVal ) + maNUpPage.maBrochureBtn.Check(); + else + maNUpPage.maPagesBtn.Check(); + } + else + { + DBG_ASSERT( 0, "missing a checkbox" ); + } + } + else if( pValue->Value >>= nVal ) + { + // this could be a ListBox or a RadioButtonGroup + ListBox* pList = dynamic_cast< ListBox* >( rWindows.front() ); + if( pList ) + { + pList->SelectEntryPos( static_cast< USHORT >(nVal) ); + } + else if( nVal >= 0 && nVal < sal_Int32(rWindows.size() ) ) + { + RadioButton* pBtn = dynamic_cast< RadioButton* >( rWindows[nVal] ); + DBG_ASSERT( pBtn, "unexpected control for property" ); + if( pBtn ) + pBtn->Check(); + } + } + } + } +} + +void PrintDialog::makeEnabled( Window* i_pWindow ) +{ + std::map< Window*, rtl::OUString >::const_iterator it = maControlToPropertyMap.find( i_pWindow ); + if( it != maControlToPropertyMap.end() ) + { + rtl::OUString aDependency( maPController->makeEnabled( it->second ) ); + if( aDependency.getLength() ) + updateWindowFromProperty( aDependency ); + } +} + +IMPL_LINK( PrintDialog, UIOption_CheckHdl, CheckBox*, i_pBox ) +{ + PropertyValue* pVal = getValueForWindow( i_pBox ); + if( pVal ) + { + makeEnabled( i_pBox ); + + sal_Bool bVal = i_pBox->IsChecked(); + pVal->Value <<= bVal; + + checkOptionalControlDependencies(); + + // update preview and page settings + preparePreview(); + } + return 0; +} + +IMPL_LINK( PrintDialog, UIOption_RadioHdl, RadioButton*, i_pBtn ) +{ + // this handler gets called for all radiobuttons that get unchecked, too + // however we only want one notificaction for the new value (that is for + // the button that gets checked) + if( i_pBtn->IsChecked() ) + { + PropertyValue* pVal = getValueForWindow( i_pBtn ); + std::map< Window*, sal_Int32 >::const_iterator it = maControlToNumValMap.find( i_pBtn ); + if( pVal && it != maControlToNumValMap.end() ) + { + makeEnabled( i_pBtn ); + + sal_Int32 nVal = it->second; + pVal->Value <<= nVal; + + checkOptionalControlDependencies(); + + // update preview and page settings + preparePreview(); + } + } + return 0; +} + +IMPL_LINK( PrintDialog, UIOption_SelectHdl, ListBox*, i_pBox ) +{ + PropertyValue* pVal = getValueForWindow( i_pBox ); + if( pVal ) + { + makeEnabled( i_pBox ); + + sal_Int32 nVal( i_pBox->GetSelectEntryPos() ); + pVal->Value <<= nVal; + + checkOptionalControlDependencies(); + + // update preview and page settings + preparePreview(); + } + return 0; +} + +IMPL_LINK( PrintDialog, UIOption_ModifyHdl, Edit*, i_pBox ) +{ + PropertyValue* pVal = getValueForWindow( i_pBox ); + if( pVal ) + { + makeEnabled( i_pBox ); + + NumericField* pNum = dynamic_cast<NumericField*>(i_pBox); + MetricField* pMetric = dynamic_cast<MetricField*>(i_pBox); + if( pNum ) + { + sal_Int64 nVal = pNum->GetValue(); + pVal->Value <<= nVal; + } + else if( pMetric ) + { + sal_Int64 nVal = pMetric->GetValue(); + pVal->Value <<= nVal; + } + else + { + rtl::OUString aVal( i_pBox->GetText() ); + pVal->Value <<= aVal; + } + + checkOptionalControlDependencies(); + + // update preview and page settings + preparePreview(); + } + return 0; +} + +void PrintDialog::Command( const CommandEvent& rEvt ) +{ + if( rEvt.GetCommand() == COMMAND_WHEEL ) + { + const CommandWheelData* pWheelData = rEvt.GetWheelData(); + if( pWheelData->GetDelta() > 0 ) + previewForward(); + else if( pWheelData->GetDelta() < 0 ) + previewBackward(); + /* + else + huh ? + */ + } +} + +void PrintDialog::Resize() +{ + maLayout.setManagedArea( Rectangle( Point( 0, 0 ), GetSizePixel() ) ); + // and do the preview; however the metafile does not need to be gotten anew + preparePreview( false ); + + // do an invalidate for the benefit of the grouping elements + Invalidate(); +} + +void PrintDialog::previewForward() +{ + maPageEdit.Up(); +} + +void PrintDialog::previewBackward() +{ + maPageEdit.Down(); +} + +// ----------------------------------------------------------------------------- +// +// PrintProgressDialog +// +// ----------------------------------------------------------------------------- + +PrintProgressDialog::PrintProgressDialog( Window* i_pParent, int i_nMax ) : + ModelessDialog( i_pParent, VclResId( SV_DLG_PRINT_PROGRESS ) ), + maText( this, VclResId( SV_PRINT_PROGRESS_TEXT ) ), + maButton( this, VclResId( SV_PRINT_PROGRESS_CANCEL ) ), + mbCanceled( false ), + mnCur( 0 ), + mnMax( i_nMax ), + mnProgressHeight( 15 ), + mbNativeProgress( false ) +{ + FreeResource(); + + if( mnMax < 1 ) + mnMax = 1; + + maStr = maText.GetText(); + + maButton.SetClickHdl( LINK( this, PrintProgressDialog, ClickHdl ) ); + +} + +PrintProgressDialog::~PrintProgressDialog() +{ +} + +IMPL_LINK( PrintProgressDialog, ClickHdl, Button*, pButton ) +{ + if( pButton == &maButton ) + mbCanceled = true; + + return 0; +} + +void PrintProgressDialog::implCalcProgressRect() +{ + if( IsNativeControlSupported( CTRL_PROGRESS, PART_ENTIRE_CONTROL ) ) + { + ImplControlValue aValue; + Region aControlRegion( Rectangle( Point(), Size( 100, mnProgressHeight ) ) ); + Region aNativeControlRegion, aNativeContentRegion; + if( GetNativeControlRegion( CTRL_PROGRESS, PART_ENTIRE_CONTROL, aControlRegion, + CTRL_STATE_ENABLED, aValue, rtl::OUString(), + aNativeControlRegion, aNativeContentRegion ) ) + { + mnProgressHeight = aNativeControlRegion.GetBoundRect().GetHeight(); + } + mbNativeProgress = true; + } + maProgressRect = Rectangle( Point( 10, maText.GetPosPixel().Y() + maText.GetSizePixel().Height() + 8 ), + Size( GetSizePixel().Width() - 20, mnProgressHeight ) ); +} + +void PrintProgressDialog::setProgress( int i_nCurrent, int i_nMax ) +{ + if( maProgressRect.IsEmpty() ) + implCalcProgressRect(); + + mnCur = i_nCurrent; + if( i_nMax != -1 ) + mnMax = i_nMax; + + if( mnMax < 1 ) + mnMax = 1; + + rtl::OUString aNewText( searchAndReplace( maStr, "%p", 2, rtl::OUString::valueOf( mnCur ) ) ); + aNewText = searchAndReplace( aNewText, "%n", 2, rtl::OUString::valueOf( mnMax ) ); + maText.SetText( aNewText ); + + // update progress + Invalidate( maProgressRect, INVALIDATE_UPDATE ); +} + +void PrintProgressDialog::tick() +{ + if( mnCur < mnMax ) + setProgress( ++mnCur ); +} + +void PrintProgressDialog::Paint( const Rectangle& ) +{ + if( maProgressRect.IsEmpty() ) + implCalcProgressRect(); + + Push( PUSH_LINECOLOR | PUSH_FILLCOLOR ); + const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings(); + Color aPrgsColor = rStyleSettings.GetHighlightColor(); + if ( aPrgsColor == rStyleSettings.GetFaceColor() ) + aPrgsColor = rStyleSettings.GetDarkShadowColor(); + SetLineColor(); + SetFillColor( aPrgsColor ); + + const long nOffset = 3; + const long nWidth = 3*mnProgressHeight/2; + const long nFullWidth = nWidth + nOffset; + const long nMaxCount = maProgressRect.GetWidth() / nFullWidth; + DrawProgress( this, maProgressRect.TopLeft(), + nOffset, + nWidth, + mnProgressHeight, + static_cast<USHORT>(0), + static_cast<USHORT>(10000*mnCur/mnMax), + static_cast<USHORT>(10000/nMaxCount), + maProgressRect + ); + Pop(); + + if( ! mbNativeProgress ) + { + DecorationView aDecoView( this ); + Rectangle aFrameRect( maProgressRect ); + aFrameRect.Left() -= nOffset; + aFrameRect.Right() += nOffset; + aFrameRect.Top() -= nOffset; + aFrameRect.Bottom() += nOffset; + aDecoView.DrawFrame( aFrameRect ); + } +} + |