diff options
Diffstat (limited to 'vcl/source')
-rw-r--r-- | vcl/source/app/salvtables.cxx | 2 | ||||
-rw-r--r-- | vcl/source/app/svdata.cxx | 11 | ||||
-rw-r--r-- | vcl/source/gdi/impprn.cxx | 2 | ||||
-rw-r--r-- | vcl/source/gdi/makefile.mk | 2 | ||||
-rw-r--r-- | vcl/source/gdi/print.cxx | 4 | ||||
-rw-r--r-- | vcl/source/gdi/print3.cxx | 672 | ||||
-rw-r--r-- | vcl/source/src/makefile.mk | 5 | ||||
-rw-r--r-- | vcl/source/src/print.src | 277 | ||||
-rw-r--r-- | vcl/source/src/stdtext.src | 7 | ||||
-rw-r--r-- | vcl/source/window/makefile.mk | 3 | ||||
-rw-r--r-- | vcl/source/window/printdlg.cxx | 1054 |
11 files changed, 2031 insertions, 8 deletions
diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx index 9d398aef10cd..fe1ef6e7b992 100644 --- a/vcl/source/app/salvtables.cxx +++ b/vcl/source/app/salvtables.cxx @@ -91,7 +91,7 @@ SalPrinter::~SalPrinter() } BOOL SalPrinter::StartJob( const String*, const String&, - ImplJobSetup*, ImplQPrinter* ) + ImplJobSetup*, vcl::PrinterListener& ) { return FALSE; } diff --git a/vcl/source/app/svdata.cxx b/vcl/source/app/svdata.cxx index edfd6a24bff9..56ba933e3931 100644 --- a/vcl/source/app/svdata.cxx +++ b/vcl/source/app/svdata.cxx @@ -7,7 +7,7 @@ * OpenOffice.org - a multi-platform office productivity suite * * $RCSfile: svdata.cxx,v $ - * $Revision: 1.56 $ + * $Revision: 1.56.114.1 $ * * This file is part of OpenOffice.org. * @@ -220,6 +220,15 @@ ResMgr* ImplGetResMgr() return pSVData->mpResMgr; } +ResId VclResId( sal_Int32 nId ) +{ + ResMgr* pMgr = ImplGetResMgr(); + if( ! pMgr ) + throw std::bad_alloc(); + + return ResId( nId, *pMgr ); +} + DockingManager* ImplGetDockingManager() { ImplSVData* pSVData = ImplGetSVData(); diff --git a/vcl/source/gdi/impprn.cxx b/vcl/source/gdi/impprn.cxx index 539c879c89ea..28d92a0b3832 100644 --- a/vcl/source/gdi/impprn.cxx +++ b/vcl/source/gdi/impprn.cxx @@ -478,10 +478,12 @@ void ImplQPrinter::EndQueuePrint() DBG_ASSERT( mpPrinter, "no SalPrinter in ImplQPrinter" ); if( mpPrinter ) { + #if 0 mpPrinter->StartJob( mbPrintFile ? &maPrintFile : NULL, Application::GetDisplayName(), maJobSetup.ImplGetConstData(), this ); + #endif EndJob(); mpParent->ImplEndPrint(); } diff --git a/vcl/source/gdi/makefile.mk b/vcl/source/gdi/makefile.mk index 977e5386fe97..57d5804a8afa 100644 --- a/vcl/source/gdi/makefile.mk +++ b/vcl/source/gdi/makefile.mk @@ -96,6 +96,7 @@ SLOFILES= $(SLO)$/salmisc.obj \ $(SLO)$/fontcvt.obj \ $(SLO)$/print.obj \ $(SLO)$/print2.obj \ + $(SLO)$/print3.obj \ $(SLO)$/regband.obj \ $(SLO)$/region.obj \ $(SLO)$/wall.obj \ @@ -120,6 +121,7 @@ EXCEPTIONSFILES= $(SLO)$/salmisc.obj \ $(SLO)$/gfxlink.obj \ $(SLO)$/print.obj \ $(SLO)$/print2.obj \ + $(SLO)$/print3.obj \ $(SLO)$/sallayout.obj \ $(SLO)$/image.obj \ $(SLO)$/impimage.obj \ diff --git a/vcl/source/gdi/print.cxx b/vcl/source/gdi/print.cxx index 0a5fbb189885..e8a1f5b32213 100644 --- a/vcl/source/gdi/print.cxx +++ b/vcl/source/gdi/print.cxx @@ -7,7 +7,7 @@ * OpenOffice.org - a multi-platform office productivity suite * * $RCSfile: print.cxx,v $ - * $Revision: 1.65 $ + * $Revision: 1.65.114.1 $ * * This file is part of OpenOffice.org. * @@ -1309,7 +1309,7 @@ void Printer::PrintPage() // ----------------------------------------------------------------------- -ULONG ImplSalPrinterErrorCodeToVCL( ULONG nError ) +ULONG Printer::ImplSalPrinterErrorCodeToVCL( ULONG nError ) { ULONG nVCLError; switch ( nError ) diff --git a/vcl/source/gdi/print3.cxx b/vcl/source/gdi/print3.cxx new file mode 100644 index 000000000000..887fa2ce39dd --- /dev/null +++ b/vcl/source/gdi/print3.cxx @@ -0,0 +1,672 @@ +/************************************************************************* + * + * 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: print3.cxx,v $ + * $Revision: 1.1.2.11 $ + * + * 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/svapp.hxx" +#include "vcl/svdata.hxx" +#include "vcl/salinst.hxx" +#include "vcl/salprn.hxx" +#include "vcl/svids.hrc" + +#include "tools/urlobj.hxx" +#include "tools/multisel.hxx" + +#include "com/sun/star/ui/dialogs/XFilePicker.hpp" +#include "com/sun/star/ui/dialogs/XFilterManager.hpp" +#include "com/sun/star/ui/dialogs/TemplateDescription.hpp" +#include "com/sun/star/ui/dialogs/ExecutableDialogResults.hpp" +#include "com/sun/star/lang/XMultiServiceFactory.hpp" +#include "com/sun/star/awt/Size.hpp" +#include "comphelper/processfactory.hxx" + +#include <hash_map> +#include <hash_set> + +using namespace com::sun::star; +using namespace com::sun::star::uno; +using namespace com::sun::star::beans; +using namespace vcl; + +class vcl::ImplPrinterListenerData +{ +public: + struct ControlDependency + { + rtl::OUString maDependsOnName; + sal_Int32 mnDependsOnEntry; + + ControlDependency() : mnDependsOnEntry( -1 ) {} + }; + + typedef std::hash_map< rtl::OUString, size_t, rtl::OUStringHash > PropertyToIndexMap; + typedef std::hash_map< rtl::OUString, ControlDependency, rtl::OUStringHash > ControlDependencyMap; + + boost::shared_ptr<Printer> mpPrinter; + MultiSelection maSelection; + Sequence< PropertyValue > maUIOptions; + std::vector< PropertyValue > maUIProperties; + std::vector< bool > maUIPropertyEnabled; + PropertyToIndexMap maPropertyToIndex; + Link maOptionChangeHdl; + ControlDependencyMap maControlDependencies; + + vcl::PrintProgressDialog* mpProgress; + + ImplPrinterListenerData() : mpProgress( NULL ) {} + ~ImplPrinterListenerData() { delete mpProgress; } +}; + +PrinterListener::PrinterListener() + : mpImplData( new ImplPrinterListenerData ) +{ +} + +static rtl::OUString queryFile( Printer* pPrinter ) +{ + rtl::OUString aResult; + + uno::Reference< lang::XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory() ); + if( xFactory.is() ) + { + uno::Sequence< uno::Any > aTempl( 1 ); + aTempl.getArray()[0] <<= ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION; + uno::Reference< ui::dialogs::XFilePicker > xFilePicker( + xFactory->createInstanceWithArguments( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.ui.dialogs.FilePicker" ) ), + aTempl ), uno::UNO_QUERY ); + DBG_ASSERT( xFilePicker.is(), "could not get FilePicker service" ); + + uno::Reference< ui::dialogs::XFilterManager > xFilterMgr( xFilePicker, uno::UNO_QUERY ); + if( xFilePicker.is() && xFilterMgr.is() ) + { + try + { +#ifdef UNX + // add PostScript and PDF + bool bPS = true, bPDF = true; + if( pPrinter ) + { + if( pPrinter->GetCapabilities( PRINTER_CAPABILITIES_PDF ) ) + bPS = false; + else + bPDF = false; + } + if( bPS ) + xFilterMgr->appendFilter( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PostScript" ) ), ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "*.ps" ) ) ); + if( bPDF ) + xFilterMgr->appendFilter( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Portable Document Format" ) ), ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "*.pdf" ) ) ); +#elif defined WNT + (void)pPrinter; + xFilterMgr->appendFilter( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "*.PRN" ) ), ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "*.prn" ) ) ); +#endif + // add arbitrary files + xFilterMgr->appendFilter( String( VclResId( SV_STDTEXT_ALLFILETYPES ) ), ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "*.*" ) ) ); + } + catch( lang::IllegalArgumentException rExc ) + { + DBG_ERRORFILE( "caught IllegalArgumentException when registering filter\n" ); + } + + if( xFilePicker->execute() == ui::dialogs::ExecutableDialogResults::OK ) + { + uno::Sequence< ::rtl::OUString > aPathSeq( xFilePicker->getFiles() ); + INetURLObject aObj( aPathSeq[0] ); + aResult = aObj.PathToFileName(); + } + } + } + return aResult; +} + +struct PrintJobAsync +{ + boost::shared_ptr<PrinterListener> mpListener; + JobSetup maInitSetup; + + PrintJobAsync( const boost::shared_ptr<PrinterListener>& i_pListener, + const JobSetup& i_rInitSetup + ) + : mpListener( i_pListener ), maInitSetup( i_rInitSetup ) + {} + + DECL_LINK( ExecJob, void* ); +}; + +IMPL_LINK( PrintJobAsync, ExecJob, void*, EMPTYARG ) +{ + Printer::ImplPrintJob( mpListener, maInitSetup ); + + // clean up, do not access members after this + delete this; + + return 0; +} + +void Printer::PrintJob( const boost::shared_ptr<PrinterListener>& i_pListener, + const JobSetup& i_rInitSetup + ) +{ + PrintJobAsync* pAsync = new PrintJobAsync( i_pListener, i_rInitSetup ); + Application::PostUserEvent( LINK( pAsync, PrintJobAsync, ExecJob ) ); +} + +void Printer::ImplPrintJob( const boost::shared_ptr<PrinterListener>& i_pListener, + const JobSetup& i_rInitSetup + ) +{ + // setup printer + boost::shared_ptr<PrinterListener> pListener( i_pListener ); + boost::shared_ptr<Printer> pPrinter( new Printer( i_rInitSetup.GetPrinterName() ) ); + pListener->setPrinter( pPrinter ); + + // setup page range selection + MultiSelection aSel; + int nPages = i_pListener->getPageCount(); + aSel.SetTotalRange( Range( 1, nPages ) ); + aSel.SelectAll(); + + // check if the printer brings up its own dialog + // in that case leave the work to that dialog + if( ! pListener->getPrinter()->GetCapabilities( PRINTER_CAPABILITIES_EXTERNALDIALOG ) ) + { + try + { + PrintDialog aDlg( NULL, i_pListener ); + if( ! aDlg.Execute() ) + return; + if( aDlg.isPrintToFile() ) + { + rtl::OUString aFile = queryFile( pListener->getPrinter().get() ); + if( ! aFile.getLength() ) + return; + pListener->getPrinter()->EnablePrintFile( TRUE ); + pListener->getPrinter()->SetPrintFile( aFile ); + } + aSel = aDlg.getPageSelection(); + pListener->getPrinter()->SetCopyCount( static_cast<USHORT>(aDlg.getCopyCount()), aDlg.isCollate() ); + } + catch( std::bad_alloc& ) + { + } + } + + pListener->setPageSelection( aSel ); + pListener->getPrinter()->StartJob( String( RTL_CONSTASCII_USTRINGPARAM( "FIXME: no job name" ) ), + pListener ); + + pListener->jobFinished(); +} + +bool Printer::StartJob( const XubString& i_rJobName, boost::shared_ptr<vcl::PrinterListener>& i_pListener ) +{ + mnError = PRINTER_OK; + + if ( IsDisplayPrinter() ) + return FALSE; + + if ( IsJobActive() || IsPrinting() ) + return FALSE; + + if( mpPrinterData->mbNextJobIsQuick ) + { + String aKey( RTL_CONSTASCII_USTRINGPARAM( "IsQuickJob" ) ); + if( maJobSetup.GetValue( aKey ).Len() == 0 ) + maJobSetup.SetValue( aKey, String( RTL_CONSTASCII_USTRINGPARAM( "true" ) ) ); + } + + ULONG nCopies = mnCopyCount; + BOOL bCollateCopy = mbCollateCopy; + BOOL bUserCopy = FALSE; + + if ( nCopies > 1 ) + { + ULONG nDevCopy; + + if ( bCollateCopy ) + nDevCopy = GetCapabilities( PRINTER_CAPABILITIES_COLLATECOPIES ); + else + nDevCopy = GetCapabilities( PRINTER_CAPABILITIES_COPIES ); + + // Muessen Kopien selber gemacht werden? + if ( nCopies > nDevCopy ) + { + bUserCopy = TRUE; + nCopies = 1; + bCollateCopy = FALSE; + } + } + else + bCollateCopy = FALSE; + + + ImplSVData* pSVData = ImplGetSVData(); + mpPrinter = pSVData->mpDefInst->CreatePrinter( mpInfoPrinter ); + + if ( !mpPrinter ) + return FALSE; + + XubString* pPrintFile; + if ( mbPrintFile ) + pPrintFile = &maPrintFile; + else + pPrintFile = NULL; + + maJobName = i_rJobName; + mnCurPage = 1; + mnCurPrintPage = 1; + mbPrinting = TRUE; + if( ImplGetSVData()->maGDIData.mbPrinterPullModel ) + { + mbJobActive = TRUE; + // sallayer does all necesseary page printing + if( mpPrinter->StartJob( pPrintFile, + Application::GetDisplayName(), + maJobSetup.ImplGetConstData(), + *i_pListener ) ) + { + EndJob(); + } + else + { + mnError = ImplSalPrinterErrorCodeToVCL( mpPrinter->GetErrorCode() ); + if ( !mnError ) + mnError = PRINTER_GENERALERROR; + pSVData->mpDefInst->DestroyPrinter( mpPrinter ); + mnCurPage = 0; + mnCurPrintPage = 0; + mbPrinting = FALSE; + mpPrinter = NULL; + + return false; + } + } + else + { + if( mpPrinter->StartJob( pPrintFile, + i_rJobName, + Application::GetDisplayName(), + nCopies, bCollateCopy, + maJobSetup.ImplGetConstData() ) ) + { + mbJobActive = TRUE; + MultiSelection aSel( i_pListener->getPageSelection() ); + i_pListener->createProgressDialog(); + for( long nPage = aSel.FirstSelected(); nPage != long(SFX_ENDOFSELECTION); nPage = aSel.NextSelected() ) + { + // remember MultiSelection is 1 based (due to user input) + i_pListener->printFilteredPage( static_cast<int>(nPage-1) ); + } + EndJob(); + } + else + { + mnError = ImplSalPrinterErrorCodeToVCL( mpPrinter->GetErrorCode() ); + if ( !mnError ) + mnError = PRINTER_GENERALERROR; + pSVData->mpDefInst->DestroyPrinter( mpPrinter ); + mnCurPage = 0; + mnCurPrintPage = 0; + mbPrinting = FALSE; + mpPrinter = NULL; + + return false; + } + } + + return true; +} + +PrinterListener::~PrinterListener() +{ + delete mpImplData; +} + +const boost::shared_ptr<Printer>& PrinterListener::getPrinter() const +{ + return mpImplData->mpPrinter; +} + +const MultiSelection& PrinterListener::getPageSelection() const +{ + return mpImplData->maSelection; +} + +void PrinterListener::setPrinter( const boost::shared_ptr<Printer>& i_rPrinter ) +{ + mpImplData->mpPrinter = i_rPrinter; +} + +void PrinterListener::setPageSelection( const MultiSelection& i_rSel ) +{ + mpImplData->maSelection = i_rSel; +} + +static void modifyJobSetup( Printer* pPrinter, const Sequence< PropertyValue >& i_rProps ) +{ + for( sal_Int32 nProperty = 0, nPropertyCount = i_rProps.getLength(); nProperty < nPropertyCount; ++nProperty ) + { + if( i_rProps[ nProperty ].Name.equalsAscii( "PageSize" ) ) + { + Size aPageSize; + awt::Size aSize; + i_rProps[ nProperty].Value >>= aSize; + aPageSize.Width() = aSize.Width; + aPageSize.Height() = aSize.Height; + + Size aCurSize( pPrinter->GetPaperSize() ); + if( aPageSize != aCurSize ) + pPrinter->SetPaperSizeUser( aPageSize ); + } + } +} + +void PrinterListener::printFilteredPage( int i_nPage ) +{ + // update progress if necessary + if( mpImplData->mpProgress ) + { + // do nothing if printing is canceled + if( mpImplData->mpProgress->isCanceled() ) + return; + mpImplData->mpProgress->tick(); + Application::Reschedule( true ); + } + + // get page parameters + Sequence< PropertyValue > aPageParm( getPageParameters( i_nPage ) ); + const MapMode aMapMode( MAP_100TH_MM ); + + mpImplData->mpPrinter->Push(); + mpImplData->mpPrinter->SetMapMode( aMapMode ); + + // modify job setup if necessary + modifyJobSetup( mpImplData->mpPrinter.get(), aPageParm ); + + mpImplData->mpPrinter->EnableOutput( FALSE ); + + GDIMetaFile aPageFile; + aPageFile.Record( mpImplData->mpPrinter.get() ); + + printPage( i_nPage ); + + aPageFile.Stop(); + aPageFile.WindStart(); + mpImplData->mpPrinter->Pop(); + + ULONG nRestoreDrawMode = mpImplData->mpPrinter->GetDrawMode(); + sal_Int32 nMaxBmpDPIX = mpImplData->mpPrinter->ImplGetDPIX(); + sal_Int32 nMaxBmpDPIY = mpImplData->mpPrinter->ImplGetDPIY(); + + const PrinterOptions& rPrinterOptions = mpImplData->mpPrinter->GetPrinterOptions(); + + static const sal_Int32 OPTIMAL_BMP_RESOLUTION = 300; + static const sal_Int32 NORMAL_BMP_RESOLUTION = 200; + + + if( rPrinterOptions.IsReduceBitmaps() ) + { + // calculate maximum resolution for bitmap graphics + if( PRINTER_BITMAP_OPTIMAL == rPrinterOptions.GetReducedBitmapMode() ) + { + nMaxBmpDPIX = std::min( sal_Int32(OPTIMAL_BMP_RESOLUTION), nMaxBmpDPIX ); + nMaxBmpDPIY = std::min( sal_Int32(OPTIMAL_BMP_RESOLUTION), nMaxBmpDPIY ); + } + else if( PRINTER_BITMAP_NORMAL == rPrinterOptions.GetReducedBitmapMode() ) + { + nMaxBmpDPIX = std::min( sal_Int32(NORMAL_BMP_RESOLUTION), nMaxBmpDPIX ); + nMaxBmpDPIY = std::min( sal_Int32(NORMAL_BMP_RESOLUTION), nMaxBmpDPIY ); + } + else + { + nMaxBmpDPIX = std::min( sal_Int32(rPrinterOptions.GetReducedBitmapResolution()), nMaxBmpDPIX ); + nMaxBmpDPIY = std::min( sal_Int32(rPrinterOptions.GetReducedBitmapResolution()), nMaxBmpDPIY ); + } + } + + // convert to greysacles + if( rPrinterOptions.IsConvertToGreyscales() ) + { + mpImplData->mpPrinter->SetDrawMode( mpImplData->mpPrinter->GetDrawMode() | + ( DRAWMODE_GRAYLINE | DRAWMODE_GRAYFILL | DRAWMODE_GRAYTEXT | + DRAWMODE_GRAYBITMAP | DRAWMODE_GRAYGRADIENT ) ); + } + + // disable transparency output + if( rPrinterOptions.IsReduceTransparency() && ( PRINTER_TRANSPARENCY_NONE == rPrinterOptions.GetReducedTransparencyMode() ) ) + { + mpImplData->mpPrinter->SetDrawMode( mpImplData->mpPrinter->GetDrawMode() | DRAWMODE_NOTRANSPARENCY ); + } + + GDIMetaFile aCleanedFile; + mpImplData->mpPrinter->RemoveTransparenciesFromMetaFile( aPageFile, aCleanedFile, nMaxBmpDPIX, nMaxBmpDPIY, + rPrinterOptions.IsReduceTransparency(), + rPrinterOptions.GetReducedTransparencyMode() == PRINTER_TRANSPARENCY_AUTO, + rPrinterOptions.IsReduceBitmaps() && rPrinterOptions.IsReducedBitmapIncludesTransparency() + ); + + mpImplData->mpPrinter->EnableOutput( TRUE ); + + // actually print the page + mpImplData->mpPrinter->StartPage(); + + mpImplData->mpPrinter->Push(); + mpImplData->mpPrinter->SetMapMode( MAP_100TH_MM ); + aCleanedFile.WindStart(); + aCleanedFile.Play( mpImplData->mpPrinter.get() ); + mpImplData->mpPrinter->Pop(); + + mpImplData->mpPrinter->EndPage(); + + mpImplData->mpPrinter->SetDrawMode( nRestoreDrawMode ); +} + +void PrinterListener::jobFinished() +{ +} + +Sequence< PropertyValue > PrinterListener::getJobProperties( const Sequence< PropertyValue >& i_rMergeList ) const +{ + std::hash_set< rtl::OUString, rtl::OUStringHash > aMergeSet; + size_t nResultLen = size_t(i_rMergeList.getLength()) + mpImplData->maUIProperties.size(); + for( int i = 0; i < i_rMergeList.getLength(); i++ ) + aMergeSet.insert( i_rMergeList[i].Name ); + + Sequence< PropertyValue > aResult( nResultLen ); + for( int i = 0; i < i_rMergeList.getLength(); i++ ) + aResult[i] = i_rMergeList[i]; + int nCur = i_rMergeList.getLength(); + for( size_t i = 0; i < mpImplData->maUIProperties.size(); i++ ) + { + if( aMergeSet.find( mpImplData->maUIProperties[i].Name ) == aMergeSet.end() ) + aResult[nCur++] = mpImplData->maUIProperties[i]; + } + aResult.realloc( nCur ); + return aResult; +} + +const Sequence< beans::PropertyValue >& PrinterListener::getUIOptions() const +{ + return mpImplData->maUIOptions; +} + +com::sun::star::beans::PropertyValue* PrinterListener::getValue( const rtl::OUString& i_rProperty ) +{ + std::hash_map< rtl::OUString, size_t, rtl::OUStringHash >::const_iterator it = + mpImplData->maPropertyToIndex.find( i_rProperty ); + return it != mpImplData->maPropertyToIndex.end() ? &mpImplData->maUIProperties[it->second] : NULL; +} + +const com::sun::star::beans::PropertyValue* PrinterListener::getValue( const rtl::OUString& i_rProperty ) const +{ + std::hash_map< rtl::OUString, size_t, rtl::OUStringHash >::const_iterator it = + mpImplData->maPropertyToIndex.find( i_rProperty ); + return it != mpImplData->maPropertyToIndex.end() ? &mpImplData->maUIProperties[it->second] : NULL; +} + +void PrinterListener::setUIOptions( const Sequence< beans::PropertyValue >& i_rOptions ) +{ + DBG_ASSERT( mpImplData->maUIOptions.getLength() == 0, "setUIOptions called twice !" ); + + mpImplData->maUIOptions = i_rOptions; + mpImplData->maUIProperties.clear(); + mpImplData->maPropertyToIndex.clear(); + mpImplData->maUIPropertyEnabled.clear(); + + for( int i = 0; i < i_rOptions.getLength(); i++ ) + { + Sequence< beans::PropertyValue > aOptProp; + i_rOptions[i].Value >>= aOptProp; + bool bIsEnabled = true; + bool bHaveProperty = false; + vcl::ImplPrinterListenerData::ControlDependency aDep; + for( int n = 0; n < aOptProp.getLength(); n++ ) + { + const beans::PropertyValue& rEntry( aOptProp[ n ] ); + if( rEntry.Name.equalsAscii( "Property" ) ) + { + PropertyValue aVal; + rEntry.Value >>= aVal; + DBG_ASSERT( mpImplData->maPropertyToIndex.find( aVal.Name ) + == mpImplData->maPropertyToIndex.end(), "duplicate property entry" ); + mpImplData->maPropertyToIndex[ aVal.Name ] = mpImplData->maUIProperties.size(); + mpImplData->maUIProperties.push_back( aVal ); + bHaveProperty = true; + } + else if( rEntry.Name.equalsAscii( "Enabled" ) ) + { + sal_Bool bValue = sal_True; + rEntry.Value >>= bValue; + bIsEnabled = bValue; + } + else if( rEntry.Name.equalsAscii( "DependsOnName" ) ) + { + rEntry.Value >>= aDep.maDependsOnName; + } + else if( rEntry.Name.equalsAscii( "DependsOnEntry" ) ) + { + rEntry.Value >>= aDep.mnDependsOnEntry; + } + } + if( bHaveProperty ) + { + mpImplData->maUIPropertyEnabled.push_back( bIsEnabled ); + if( aDep.maDependsOnName.getLength() > 0 ) + mpImplData->maControlDependencies[ mpImplData->maUIProperties.back().Name ] = aDep; + } + } +} + +void PrinterListener::enableUIOption( const rtl::OUString& i_rProperty, bool i_bEnable ) +{ + std::hash_map< rtl::OUString, size_t, rtl::OUStringHash >::const_iterator it = + mpImplData->maPropertyToIndex.find( i_rProperty ); + if( it != mpImplData->maPropertyToIndex.end() ) + { + // call handler only for actual changes + if( ( mpImplData->maUIPropertyEnabled[ it->second ] && ! i_bEnable ) || + ( ! mpImplData->maUIPropertyEnabled[ it->second ] && i_bEnable ) ) + { + mpImplData->maUIPropertyEnabled[ it->second ] = i_bEnable; + rtl::OUString aPropName( i_rProperty ); + mpImplData->maOptionChangeHdl.Call( &aPropName ); + } + } +} + +bool PrinterListener::isUIOptionEnabled( const rtl::OUString& i_rProperty ) const +{ + bool bEnabled = false; + std::hash_map< rtl::OUString, size_t, rtl::OUStringHash >::const_iterator prop_it = + mpImplData->maPropertyToIndex.find( i_rProperty ); + if( prop_it != mpImplData->maPropertyToIndex.end() ) + { + bEnabled = mpImplData->maUIPropertyEnabled[prop_it->second]; + + if( bEnabled ) + { + // check control dependencies + vcl::ImplPrinterListenerData::ControlDependencyMap::const_iterator it = + mpImplData->maControlDependencies.find( i_rProperty ); + if( it != mpImplData->maControlDependencies.end() ) + { + // check if the dependency is enabled + // if the dependency is disabled, we are too + bEnabled = isUIOptionEnabled( it->second.maDependsOnName ); + + if( bEnabled ) + { + // does the dependency have the correct value ? + const com::sun::star::beans::PropertyValue* pVal = getValue( it->second.maDependsOnName ); + OSL_ENSURE( pVal, "unknown property in dependency" ); + if( pVal ) + { + sal_Int32 nDepVal; + sal_Bool bDepVal; + if( pVal->Value >>= nDepVal ) + { + bEnabled = (nDepVal == it->second.mnDependsOnEntry); + } + else if( pVal->Value >>= bDepVal ) + { + // could be a dependency on a checked boolean + // in this case the dependency is on a non zero for checked value + bEnabled = ( bDepVal && it->second.mnDependsOnEntry != 0) || + ( ! bDepVal && it->second.mnDependsOnEntry == 0); + } + else + { + // if the type does not match something is awry + OSL_ENSURE( 0, "strange type in control dependency" ); + bEnabled = false; + } + } + } + } + } + } + return bEnabled; +} + +void PrinterListener::setOptionChangeHdl( const Link& i_rHdl ) +{ + mpImplData->maOptionChangeHdl = i_rHdl; +} + +void PrinterListener::createProgressDialog() +{ + if( ! mpImplData->mpProgress ) + { + mpImplData->mpProgress = new PrintProgressDialog( NULL, mpImplData->maSelection.GetSelectCount() ); + mpImplData->mpProgress->Show(); + } +} diff --git a/vcl/source/src/makefile.mk b/vcl/source/src/makefile.mk index cf01c74b977d..7772af5a0978 100644 --- a/vcl/source/src/makefile.mk +++ b/vcl/source/src/makefile.mk @@ -8,7 +8,7 @@ # # $RCSfile: makefile.mk,v $ # -# $Revision: 1.8 $ +# $Revision: 1.8.114.1 $ # # This file is part of OpenOffice.org. # @@ -47,7 +47,8 @@ SRC1FILES= images.src \ stdtext.src \ helptext.src \ units.src \ - btntext.src + btntext.src \ + print.src RESLIB1NAME= $(RESTARGET) RESLIB1IMAGES= $(PRJ)$/source/src diff --git a/vcl/source/src/print.src b/vcl/source/src/print.src new file mode 100644 index 000000000000..e8543515d68c --- /dev/null +++ b/vcl/source/src/print.src @@ -0,0 +1,277 @@ +/************************************************************************* + * + * 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: print.src,v $ + * $Revision: 1.1.2.4 $ + * + * 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 "vcl/svids.hrc" + +ModalDialog SV_DLG_PRINT +{ + Text [en-US] = "Printing"; + Closeable = TRUE; + Sizeable = TRUE; + Moveable = TRUE; + SVLook = TRUE; + + Size = MAP_APPFONT( 350, 195 ); + + OKButton SV_PRINT_OK + { + DefButton = TRUE; + Pos = MAP_APPFONT( 240, 175 ); + Size = MAP_APPFONT( 50, 15 ); + }; + CancelButton SV_PRINT_CANCEL + { + Pos = MAP_APPFONT( 295, 175 ); + Size = MAP_APPFONT( 50, 15 ); + }; + + Window SV_PRINT_PAGE_PREVIEW + { + Pos = MAP_APPFONT( 5, 5 ); + Size = MAP_APPFONT( 130, 130 ); + Border = TRUE; + }; + ScrollBar SV_PRINT_PAGE_SCROLL + { + Pos = MAP_APPFONT( 5, 140 ); + Size = MAP_APPFONT( 130, 10 ); + SVLook = TRUE; + HScroll = TRUE; + TabStop = TRUE; + }; + FixedText SV_PRINT_PAGE_TXT + { + Pos = MAP_APPFONT( 5,150 ); + Size = MAP_APPFONT( 130, 10 ); + Text [ en-US ] = "Page %p of %n"; + Center = TRUE; + }; + TabControl SV_PRINT_TABCTRL + { + Pos = MAP_APPFONT( 140, 5 ); + Size = MAP_APPFONT( 205, 155 ); + }; + FixedLine SV_PRINT_BUTTONLINE + { + Pos = MAP_APPFONT( 0, 165 ); + Size = MAP_APPFONT( 350, 8 ); + }; + + TabPage SV_PRINT_TAB_PRINTER + { + Text [en-US] = "Printer"; + Hide = TRUE; + + ListBox SV_PRINT_PRINTERS + { + Pos = MAP_APPFONT( 5, 5 ); + Size = MAP_APPFONT( 100, 200 ); + DropDown = TRUE; + }; + PushButton SV_PRINT_PRT_SETUP + { + Pos = MAP_APPFONT( 115, 5 ); + Size = MAP_APPFONT( 50, 15 ); + Text [en-US] = "Properties..."; + }; + FixedText SV_PRINT_PRT_TYPE + { + Pos = MAP_APPFONT( 5, 30 ); + Size = MAP_APPFONT( 40, 10 ); + Text [en-US] = "Type"; + }; + FixedText SV_PRINT_PRT_TYPE_TXT + { + Pos = MAP_APPFONT( 50, 30 ); + Size = MAP_APPFONT( 200, 10 ); + }; + FixedText SV_PRINT_PRT_STATUS + { + Pos = MAP_APPFONT( 5, 42 ); + Size = MAP_APPFONT( 40, 10 ); + Text [en-US] = "Status"; + }; + FixedText SV_PRINT_PRT_STATUS_TXT + { + Pos = MAP_APPFONT( 50, 42 ); + Size = MAP_APPFONT( 200, 10 ); + }; + FixedText SV_PRINT_PRT_LOCATION + { + Pos = MAP_APPFONT( 5, 54 ); + Size = MAP_APPFONT( 40, 10 ); + Text [en-US] = "Location"; + }; + FixedText SV_PRINT_PRT_LOCATION_TXT + { + Pos = MAP_APPFONT( 50, 54 ); + Size = MAP_APPFONT( 200, 10 ); + }; + FixedText SV_PRINT_PRT_COMMENT + { + Pos = MAP_APPFONT( 5, 66 ); + Size = MAP_APPFONT( 40, 10 ); + Text [en-US] = "Comment"; + }; + FixedText SV_PRINT_PRT_COMMENT_TXT + { + Pos = MAP_APPFONT( 50, 66 ); + Size = MAP_APPFONT( 200, 10 ); + }; + }; + + TabPage SV_PRINT_TAB_JOB + { + Text [en-US] = "Job Setup"; + Hide = TRUE; + + ListBox SV_PRINT_PRINTERS + { + Pos = MAP_APPFONT( 5, 5 ); + Size = MAP_APPFONT( 100, 200 ); + DropDown = TRUE; + }; + CheckBox SV_PRINT_PRT_TOFILE + { + Pos = MAP_APPFONT( 15, 20 ); + Size = MAP_APPFONT( 200, 12 ); + Text [en-US] = "Print to file"; + }; + FixedLine SV_PRINT_RANGE + { + Pos = MAP_APPFONT( 5, 30 ); + Size = MAP_APPFONT( 150, 10 ); + Text [en-US] = "Print range"; + }; + RadioButton SV_PRINT_ALL + { + Pos = MAP_APPFONT( 10, 40 ); + Size = MAP_APPFONT( 145, 15 ); + Text [en-US] = "All pages"; + Check = TRUE; + }; + RadioButton SV_PRINT_PAGERANGE + { + Pos = MAP_APPFONT( 10, 55 ); + Size = MAP_APPFONT( 60, 15 ); + Text [en-US] = "Pages"; + }; + Edit SV_PRINT_PAGERANGE_EDIT + { + Pos = MAP_APPFONT( 70, 55 ); + Size = MAP_APPFONT( 80, 15 ); + Border = TRUE; + }; + RadioButton SV_PRINT_SELECTION + { + Pos = MAP_APPFONT( 10, 70 ); + Size = MAP_APPFONT( 145, 15 ); + Text [en-US] = "Selection"; + }; + + FixedLine SV_PRINT_COPIES + { + Pos = MAP_APPFONT( 5, 90 ); + Size = MAP_APPFONT( 150, 10 ); + Text [en-US] = "Copies"; + }; + FixedText SV_PRINT_COPYCOUNT + { + Pos = MAP_APPFONT( 10, 100 ); + Size = MAP_APPFONT( 80, 10 ); + Text [en-US] = "Number of copies"; + }; + NumericField SV_PRINT_COPYCOUNT_FIELD + { + Pos = MAP_APPFONT( 90, 100 ); + Size = MAP_APPFONT( 40, 10 ); + Border = TRUE; + Spin = TRUE; + Minimum = 1; + Maximum = 16384; + Value = 1; + }; + FixedImage SV_PRINT_COLLATE_IMAGE + { + Pos = MAP_APPFONT( 10, 120 ); + Size = MAP_PIXEL( 80, 30 ); + }; + CheckBox SV_PRINT_COLLATE + { + Pos = MAP_APPFONT( 80, 120 ); + Size = MAP_APPFONT( 70, 10 ); + Text [en-US] = "Collate"; + }; + + Image SV_PRINT_COLLATE_IMG + { + ImageBitmap = Bitmap { File = "collate.png" ; }; + }; + + Image SV_PRINT_NOCOLLATE_IMG + { + ImageBitmap = Bitmap { File = "ncollate.png" ; }; + }; + + Image SV_PRINT_COLLATE_HC_IMG + { + ImageBitmap = Bitmap { File = "collate_h.png" ; }; + }; + + Image SV_PRINT_NOCOLLATE_HC_IMG + { + ImageBitmap = Bitmap { File = "ncollate_h.png" ; }; + }; + }; +}; + +ModelessDialog SV_DLG_PRINT_PROGRESS +{ + Text [en-US] = "Printing"; + Closeable = FALSE; + Sizeable = FALSE; + Moveable = TRUE; + SVLook = TRUE; + + Size = MAP_APPFONT( 120, 70 ); + + CancelButton SV_PRINT_PROGRESS_CANCEL + { + Pos = MAP_APPFONT( 35, 50 ); + Size = MAP_APPFONT( 50, 15 ); + }; + FixedText SV_PRINT_PROGRESS_TEXT + { + Pos = MAP_APPFONT( 5,10 ); + Size = MAP_APPFONT( 110, 10 ); + Text [ en-US ] = "Page %p of %n"; + Center = TRUE; + }; +}; diff --git a/vcl/source/src/stdtext.src b/vcl/source/src/stdtext.src index 5ad1cdceeb61..d4dca4915b6b 100644 --- a/vcl/source/src/stdtext.src +++ b/vcl/source/src/stdtext.src @@ -7,7 +7,7 @@ * OpenOffice.org - a multi-platform office productivity suite * * $RCSfile: stdtext.src,v $ - * $Revision: 1.53 $ + * $Revision: 1.53.84.1 $ * * This file is part of OpenOffice.org. * @@ -123,3 +123,8 @@ String SV_MAC_SCREENNNAME { Text [en-US] = "Screen %d"; }; + +String SV_STDTEXT_ALLFILETYPES +{ + Text [en-US] = "Any type"; +}; diff --git a/vcl/source/window/makefile.mk b/vcl/source/window/makefile.mk index cdd4aef73bb0..cadea48f6f7a 100644 --- a/vcl/source/window/makefile.mk +++ b/vcl/source/window/makefile.mk @@ -8,7 +8,7 @@ # # $RCSfile: makefile.mk,v $ # -# $Revision: 1.25 $ +# $Revision: 1.25.114.1 $ # # This file is part of OpenOffice.org. # @@ -70,6 +70,7 @@ SLOFILES= \ $(SLO)$/mnemonicengine.obj \ $(SLO)$/msgbox.obj \ $(SLO)$/scrwnd.obj \ + $(SLO)$/printdlg.obj \ $(SLO)$/seleng.obj \ $(SLO)$/split.obj \ $(SLO)$/splitwin.obj \ diff --git a/vcl/source/window/printdlg.cxx b/vcl/source/window/printdlg.cxx new file mode 100644 index 000000000000..739e9c036794 --- /dev/null +++ b/vcl/source/window/printdlg.cxx @@ -0,0 +1,1054 @@ +/************************************************************************* + * + * 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 "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; + +PrintDialog::PrintPreviewWindow::PrintPreviewWindow( Window* i_pParent, const ResId& i_rId ) + : Window( i_pParent, i_rId ) +{ +} + +PrintDialog::PrintPreviewWindow::~PrintPreviewWindow() +{ +} + +void PrintDialog::PrintPreviewWindow::Paint( const Rectangle& i_rRect ) +{ + Window::Paint( i_rRect ); + + SetFillColor( Color( COL_WHITE ) ); + SetLineColor(); + DrawRect( Rectangle( Point( 0, 0 ), GetSizePixel() )); + Push(); + SetMapMode( MAP_100TH_MM ); + maMtf.WindStart(); + maMtf.Play( this, Point( 0, 0 ), PixelToLogic( GetSizePixel() ) ); + Pop(); +} + +void PrintDialog::PrintPreviewWindow::setPreview( const GDIMetaFile& i_rNewPreview ) +{ + maMtf = i_rNewPreview; + Invalidate(); +} + +PrintDialog::PrinterTabPage::PrinterTabPage( Window* i_pParent, const ResId& rResId ) + : TabPage( i_pParent, rResId ) + , maPrinters( this, VclResId( SV_PRINT_PRINTERS) ) + , maSetupButton( this, VclResId( SV_PRINT_PRT_SETUP ) ) + , maType( this, VclResId( SV_PRINT_PRT_TYPE ) ) + , maTypeText( this, VclResId( SV_PRINT_PRT_TYPE_TXT ) ) + , maStatus( this, VclResId( SV_PRINT_PRT_STATUS ) ) + , maStatusText(this, VclResId( SV_PRINT_PRT_STATUS_TXT ) ) + , maLocation( this, VclResId( SV_PRINT_PRT_LOCATION ) ) + , maLocText( this, VclResId( SV_PRINT_PRT_LOCATION_TXT ) ) + , maComment( this, VclResId( SV_PRINT_PRT_COMMENT ) ) + , maCommentText( this, VclResId( SV_PRINT_PRT_COMMENT_TXT ) ) +{ + FreeResource(); +} + +PrintDialog::PrinterTabPage::~PrinterTabPage() +{ +} + +PrintDialog::JobTabPage::JobTabPage( Window* i_pParent, const ResId& rResId ) + : TabPage( i_pParent, rResId ) + , maPrinters( this, VclResId( SV_PRINT_PRINTERS) ) + , maToFileBox( this, VclResId( SV_PRINT_PRT_TOFILE ) ) + , maPrintRange( this, VclResId( SV_PRINT_RANGE ) ) + , maAllButton( this, VclResId( SV_PRINT_ALL ) ) + , maPagesButton( this, VclResId( SV_PRINT_PAGERANGE ) ) + , maSelectionButton( this, VclResId( SV_PRINT_SELECTION ) ) + , maPagesEdit( this, VclResId( SV_PRINT_PAGERANGE_EDIT ) ) + , maCopies( this, VclResId( SV_PRINT_COPIES ) ) + , 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 ) ) +{ + FreeResource(); +} + +PrintDialog::JobTabPage::~JobTabPage() +{ +} + +PrintDialog::PrintDialog( Window* i_pParent, const boost::shared_ptr<PrinterListener>& i_rListener ) + : ModalDialog( i_pParent, VclResId( SV_DLG_PRINT ) ) + , maOKButton( this, VclResId( SV_PRINT_OK ) ) + , maCancelButton( this, VclResId( SV_PRINT_CANCEL ) ) + , maPreviewWindow( this, VclResId( SV_PRINT_PAGE_PREVIEW ) ) + , maPageText( this, VclResId( SV_PRINT_PAGE_TXT ) ) + , maPageScrollbar( this, VclResId( SV_PRINT_PAGE_SCROLL ) ) + , maTabCtrl( this, VclResId( SV_PRINT_TABCTRL ) ) + , maPrinterPage( &maTabCtrl, VclResId( SV_PRINT_TAB_PRINTER ) ) + , maJobPage( &maTabCtrl, VclResId( SV_PRINT_TAB_JOB ) ) + , maButtonLine( this, VclResId( SV_PRINT_BUTTONLINE ) ) + , maPListener( i_rListener ) + , mnCurPage( 0 ) + , mnCachedPages( 0 ) +{ + FreeResource(); + + // insert the tab pages + maTabCtrl.InsertPage( SV_PRINT_TAB_JOB, maJobPage.GetText() ); + maTabCtrl.SetTabPage( SV_PRINT_TAB_JOB, &maJobPage ); + maTabCtrl.InsertPage( SV_PRINT_PAGE_PREVIEW, maPrinterPage.GetText() ); + maTabCtrl.SetTabPage( SV_PRINT_PAGE_PREVIEW, &maPrinterPage ); + + maPageStr = maPageText.GetText(); + // save space for the preview window + maPreviewSpace = Rectangle( maPreviewWindow.GetPosPixel(), maPreviewWindow.GetSizePixel() ); + // get the first page + preparePreview(); + + // set up the scrollbar for the preview pages + maPageScrollbar.SetScrollHdl( LINK( this, PrintDialog, ScrollHdl ) ); + maPageScrollbar.SetEndScrollHdl( LINK( this, PrintDialog, ScrollEndHdl ) ); + maPageScrollbar.EnableDrag( 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 ) + { + maPrinterPage.maPrinters.InsertEntry( *it ); + maJobPage.maPrinters.InsertEntry( *it ); + } + // select current printer + if( maPrinterPage.maPrinters.GetEntryPos( maPListener->getPrinter()->GetName() ) != LISTBOX_ENTRY_NOTFOUND ) + { + maPrinterPage.maPrinters.SelectEntry( maPListener->getPrinter()->GetName() ); + maJobPage.maPrinters.SelectEntry( maPListener->getPrinter()->GetName() ); + } + else + { + // fall back to default printer + maPrinterPage.maPrinters.SelectEntry( Printer::GetDefaultPrinterName() ); + maJobPage.maPrinters.SelectEntry( Printer::GetDefaultPrinterName() ); + maPListener->setPrinter( boost::shared_ptr<Printer>( new Printer( Printer::GetDefaultPrinterName() ) ) ); + } + // update the text fields for the printer + updatePrinterText(); + + // set a select handler + maPrinterPage.maPrinters.SetSelectHdl( LINK( this, PrintDialog, SelectHdl ) ); + maJobPage.maPrinters.SetSelectHdl( LINK( this, PrintDialog, SelectHdl ) ); + + // setup page range edit + rtl::OUStringBuffer aBuf( 16 ); + aBuf.append( sal_Unicode('1') ); + if( mnCachedPages > 1 ) + { + aBuf.append( sal_Unicode('-') ); + aBuf.append( mnCachedPages ); + } + maJobPage.maPagesEdit.SetText( aBuf.makeStringAndClear() ); + + // setup click handler on the various buttons + maJobPage.maCollateBox.SetClickHdl( LINK( this, PrintDialog, ClickHdl ) ); + maJobPage.maAllButton.SetClickHdl( LINK( this, PrintDialog, ClickHdl ) ); + maJobPage.maSelectionButton.SetClickHdl( LINK( this, PrintDialog, ClickHdl ) ); + maJobPage.maPagesButton.SetClickHdl( LINK( this, PrintDialog, ClickHdl ) ); + maPrinterPage.maSetupButton.SetClickHdl( LINK( this, PrintDialog, ClickHdl ) ); + + // setup modify hdl + maJobPage.maCopyCountField.SetModifyHdl( LINK( this, PrintDialog, ModifyHdl ) ); + + // setup optional UI options set by application + setupOptionalUI(); + + // set change handler for UI options + maPListener->setOptionChangeHdl( LINK( this, PrintDialog, UIOptionsChanged ) ); + + // set min size pixel to current size + SetMinOutputSizePixel( GetOutputSizePixel() ); + + // setup dependencies + checkControlDependencies(); +} + +PrintDialog::~PrintDialog() +{ + while( ! maControls.empty() ) + { + delete maControls.front(); + maControls.pop_front(); + } +} + +bool PrintDialog::isPrintToFile() +{ + return maJobPage.maToFileBox.IsChecked(); +} + +int PrintDialog::getCopyCount() +{ + return static_cast<int>(maJobPage.maCopyCountField.GetValue()); +} + +bool PrintDialog::isCollate() +{ + return maJobPage.maCopyCountField.GetValue() > 1 ? maJobPage.maCollateBox.IsChecked() : FALSE; +} + +MultiSelection PrintDialog::getPageSelection() +{ + if( maJobPage.maPagesButton.IsChecked() ) + return MultiSelection( maJobPage.maPagesEdit.GetText() ); + else if( maJobPage.maAllButton.IsChecked() ) + { + MultiSelection aSel( Range( 1, maPListener->getPageCount() ) ); + aSel.SelectAll(); + return aSel; + } + DBG_ERROR( "NYI: Selection" ); + return MultiSelection(); +} + +void PrintDialog::setupOptionalUI() +{ + Window* pCurParent = 0; + long nCurY = 0, nXPos = 5; + USHORT nOptPageId = 9; + MapMode aFontMapMode( MAP_APPFONT ); + + Size aTabSize = maTabCtrl.GetSizePixel(); + const Sequence< PropertyValue >& rOptions( maPListener->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; + sal_Int64 nMinValue = 0, nMaxValue = 0; + bool bDependency = 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( "DependsOnName" ) ) + { + bDependency = true; + } + else if( rEntry.Name.equalsAscii( "MinValue" ) ) + { + rEntry.Value >>= nMinValue; + } + else if( rEntry.Name.equalsAscii( "MaxValue" ) ) + { + rEntry.Value >>= nMaxValue; + } + } + + if( aCtrlType.equalsAscii( "Group" ) || + aCtrlType.equalsAscii( "Subgroup" ) || + aCtrlType.equalsAscii( "Radio" ) || + aCtrlType.equalsAscii( "List" ) || + aCtrlType.equalsAscii( "Range" ) || + aCtrlType.equalsAscii( "Bool" ) ) + { + if( aCtrlType.equalsAscii( "Group" ) || ! pCurParent ) + { + // add new tab page + TabPage* pNewGroup = new TabPage( &maTabCtrl ); + maControls.push_front( pNewGroup ); + pCurParent = pNewGroup; + nCurY = 5; + nXPos = 5; + pNewGroup->SetText( aText ); + maTabCtrl.InsertPage( ++nOptPageId, aText ); + maTabCtrl.SetTabPage( nOptPageId, pNewGroup ); + } + + if( aCtrlType.equalsAscii( "Subgroup" ) && pCurParent ) + { + nXPos = 5; + FixedLine* pNewSub = new FixedLine( pCurParent ); + maControls.push_front( pNewSub ); + pNewSub->SetText( aText ); + nCurY += 4; + Size aPixelSize( aTabSize ); + aPixelSize.Width() /= 2; + aPixelSize.Height() = pCurParent->GetTextHeight() + 4; + pNewSub->SetPosSizePixel( pNewSub->LogicToPixel( Point( nXPos, nCurY ), aFontMapMode ), + aPixelSize ); + pNewSub->Show(); + nCurY += 12; + nXPos += 5; + } + else if( aCtrlType.equalsAscii( "Bool" ) && pCurParent ) + { + if( bDependency ) + nXPos += 5; + + // add a check box + CheckBox* pNewBox = new CheckBox( pCurParent ); + maControls.push_front( pNewBox ); + pNewBox->SetText( aText ); + + // FIXME: measure text + pNewBox->SetPosSizePixel( pNewBox->LogicToPixel( Point( nXPos, nCurY ), aFontMapMode ), + pNewBox->LogicToPixel( Size( 100, 10 ), aFontMapMode ) ); + nCurY += 12; + + pNewBox->Show(); + sal_Bool bVal = sal_False; + PropertyValue* pVal = maPListener->getValue( aPropertyName ); + if( pVal ) + pVal->Value >>= bVal; + pNewBox->Check( bVal ); + pNewBox->Enable( maPListener->isUIOptionEnabled( aPropertyName ) && pVal != NULL ); + pNewBox->SetToggleHdl( LINK( this, PrintDialog, UIOption_CheckHdl ) ); + + maPropertyToWindowMap.insert( std::pair< rtl::OUString, Window* >( aPropertyName, pNewBox ) ); + maControlToPropertyMap[pNewBox] = aPropertyName; + + if( bDependency ) + nXPos -= 5; + } + else if( aCtrlType.equalsAscii( "Radio" ) && pCurParent ) + { + long nOldXPos = nXPos; + if( aText.getLength() ) + { + // add a FixedText: + FixedText* pHeading = new FixedText( pCurParent ); + maControls.push_front( pHeading ); + pHeading->SetText( aText ); + Size aPixelSize( pHeading->LogicToPixel( Size( 10, 10 ), aFontMapMode ) ); + aPixelSize.Width() = aTabSize.Width() - aPixelSize.Width(); + pHeading->SetPosSizePixel( pHeading->LogicToPixel( Point( nXPos, nCurY ), aFontMapMode ), + aPixelSize ); + pHeading->Show(); + + nXPos += 10; + nCurY += 12; + } + + // iterate options + sal_Int32 nSelectVal = 0; + PropertyValue* pVal = maPListener->getValue( aPropertyName ); + if( pVal && pVal->Value.hasValue() ) + pVal->Value >>= nSelectVal; + for( sal_Int32 m = 0; m < aChoices.getLength(); m++ ) + { + RadioButton* pBtn = new RadioButton( pCurParent, m == 0 ? WB_GROUP : 0 ); + maControls.push_front( pBtn ); + pBtn->SetText( aChoices[m] ); + pBtn->Check( m == nSelectVal ); + Size aPixelSize( pBtn->LogicToPixel( Size( 10 + nXPos, 12 ), aFontMapMode ) ); + aPixelSize.Width() = aTabSize.Width() - aPixelSize.Width(); + pBtn->SetPosSizePixel( pBtn->LogicToPixel( Point( 15, nCurY ), aFontMapMode ), + aPixelSize ); + pBtn->Enable( maPListener->isUIOptionEnabled( aPropertyName ) ); + pBtn->SetToggleHdl( LINK( this, PrintDialog, UIOption_RadioHdl ) ); + pBtn->Show(); + maPropertyToWindowMap.insert( std::pair< rtl::OUString, Window* >( aPropertyName, pBtn ) ); + maControlToPropertyMap[pBtn] = aPropertyName; + maControlToNumValMap[pBtn] = m; + + nCurY += 12; + } + nXPos = nOldXPos; + } + else if( aCtrlType.equalsAscii( "List" ) && pCurParent ) + { + if( bDependency ) + nXPos += 5; + + // add a FixedText: + FixedText* pHeading = new FixedText( pCurParent ); + maControls.push_front( pHeading ); + pHeading->SetText( aText ); + Size aPixelSize( pHeading->LogicToPixel( Size( 10, 10 ), aFontMapMode ) ); + aPixelSize.Width() += pHeading->GetTextWidth( aText ); + pHeading->SetPosSizePixel( pHeading->LogicToPixel( Point( nXPos, nCurY ), aFontMapMode ), + aPixelSize ); + pHeading->Show(); + + ListBox* pList = new ListBox( pCurParent, WB_DROPDOWN | WB_BORDER ); + maControls.push_front( pList ); + + // iterate options + long nMaxTextWidth = 0; + for( sal_Int32 m = 0; m < aChoices.getLength(); m++ ) + { + pList->InsertEntry( aChoices[m] ); + long nEntryWidth = pList->GetTextWidth( aChoices[m] ); + if( nEntryWidth > nMaxTextWidth ) + nMaxTextWidth = nEntryWidth; + } + nMaxTextWidth += 30; + sal_Int32 nSelectVal = 0; + PropertyValue* pVal = maPListener->getValue( aPropertyName ); + if( pVal && pVal->Value.hasValue() ) + pVal->Value >>= nSelectVal; + pList->SelectEntryPos( static_cast<USHORT>(nSelectVal) ); + + aPixelSize = Size( pList->LogicToPixel( Size( 25, 12 ), aFontMapMode ) ); + aPixelSize.Width() = nMaxTextWidth; + aPixelSize.Height() *= aChoices.getLength() > 15 ? 15 : aChoices.getLength(); + + Point aListPos; + bool bDoAlign = false; + if( nMaxTextWidth + aPixelSize.Width() < aTabSize.Width() - 10 ) + { + aListPos = pHeading->GetPosPixel(); + aListPos.X() += pHeading->GetSizePixel().Width() + 5; + + // align heading and list box + bDoAlign = true; + } + else + { + nCurY += 12; + aListPos = pCurParent->LogicToPixel( Point( 15, nCurY ), aFontMapMode ); + } + + pList->SetPosSizePixel( aListPos, aPixelSize ); + pList->Enable( maPListener->isUIOptionEnabled( aPropertyName ) ); + pList->SetSelectHdl( LINK( this, PrintDialog, UIOption_SelectHdl ) ); + pList->Show(); + + maPropertyToWindowMap.insert( std::pair< rtl::OUString, Window* >( aPropertyName, pList ) ); + maControlToPropertyMap[pList] = aPropertyName; + nCurY += 16; + + if( bDoAlign ) + { + Point aPos = pHeading->GetPosPixel(); + Size aSize = pHeading->GetSizePixel(); + aPos.Y() += (pList->GetSizePixel().Height() - aSize.Height())/2; + pHeading->SetPosSizePixel( aPos, aSize ); + } + + if( bDependency ) + nXPos -= 5; + } + else if( aCtrlType.equalsAscii( "Range" ) && pCurParent ) + { + if( bDependency ) + nXPos += 5; + + // add a FixedText: + FixedText* pHeading = new FixedText( pCurParent ); + maControls.push_front( pHeading ); + pHeading->SetText( aText ); + Size aPixelSize( pHeading->LogicToPixel( Size( 10, 10 ), aFontMapMode ) ); + aPixelSize.Width() += pHeading->GetTextWidth( aText ); + pHeading->SetPosSizePixel( pHeading->LogicToPixel( Point( nXPos, nCurY ), aFontMapMode ), + aPixelSize ); + pHeading->Show(); + + 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 = maPListener->getValue( aPropertyName ); + if( pVal && pVal->Value.hasValue() ) + pVal->Value >>= nCurVal; + pField->SetValue( nCurVal ); + + aPixelSize = Size( pField->LogicToPixel( Size( 80, 12 ), aFontMapMode ) ); + + Point aFieldPos; + bool bDoAlign = false; + if( aPixelSize.Width() < aTabSize.Width() - 10 ) + { + aFieldPos = pHeading->GetPosPixel(); + aFieldPos.X() += pHeading->GetSizePixel().Width() + 5; + + // align heading and list box + bDoAlign = true; + } + else + { + nCurY += 12; + aFieldPos = pCurParent->LogicToPixel( Point( 15, nCurY ), aFontMapMode ); + } + + pField->SetPosSizePixel( aFieldPos, aPixelSize ); + pField->Enable( maPListener->isUIOptionEnabled( aPropertyName ) ); + pField->SetModifyHdl( LINK( this, PrintDialog, UIOption_ModifyHdl ) ); + pField->Show(); + + maPropertyToWindowMap.insert( std::pair< rtl::OUString, Window* >( aPropertyName, pField ) ); + maControlToPropertyMap[pField] = aPropertyName; + nCurY += 16; + + if( bDoAlign ) + { + Point aPos = pHeading->GetPosPixel(); + Size aSize = pHeading->GetSizePixel(); + aPos.Y() += (pField->GetSizePixel().Height() - aSize.Height())/2; + pHeading->SetPosSizePixel( aPos, aSize ); + } + + if( bDependency ) + nXPos -= 5; + } + } + else + { + DBG_ERROR( "Unsupported UI option" ); + } + } +} + +void PrintDialog::checkControlDependencies() +{ + if( maJobPage.maCopyCountField.GetValue() > 1 ) + maJobPage.maCollateBox.Enable( TRUE ); + else + maJobPage.maCollateBox.Enable( FALSE ); + + maJobPage.maPagesEdit.Enable( maJobPage.maPagesButton.IsChecked() ); + Image aImg( maJobPage.maCollateBox.IsChecked() ? maJobPage.maCollateImg : maJobPage.maNoCollateImg ); + if( GetSettings().GetStyleSettings().GetFieldColor().IsDark() ) + aImg = maJobPage.maCollateBox.IsChecked() ? maJobPage.maCollateHCImg : maJobPage.maNoCollateHCImg; + + // adjust position and size of image + maJobPage.maCollateImage.SetSizePixel( aImg.GetSizePixel() ); + Point aPos( maJobPage.maCollateImage.GetPosPixel() ); + aPos.Y() = maJobPage.maCollateBox.GetPosPixel().Y(); + aPos.Y() -= (aImg.GetSizePixel().Height() - maJobPage.maCollateBox.GetSizePixel().Height())/2; + maJobPage.maCollateImage.SetPosPixel( aPos ); + maJobPage.maCollateImage.SetImage( aImg ); + + // enable setup button only for printers that can be setup + maPrinterPage.maSetupButton.Enable( maPListener->getPrinter()->HasSupport( SUPPORT_SETUPDIALOG ) ); +} + +void PrintDialog::checkOptionalControlDependencies() +{ + for( std::map< Window*, rtl::OUString >::iterator it = maControlToPropertyMap.begin(); + it != maControlToPropertyMap.end(); ++it ) + { + bool bShouldbeEnabled = maPListener->isUIOptionEnabled( it->second ); + 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 ); + } +} + +void PrintDialog::updatePrinterText() +{ + const QueueInfo* pInfo = Printer::GetQueueInfo( maPrinterPage.maPrinters.GetSelectEntry(), true ); + if( pInfo ) + { + maPrinterPage.maTypeText.SetText( pInfo->GetDriver() ); + // FIXME: status message + // maJobPage.maStatusText.SetText(); + maPrinterPage.maLocText.SetText( pInfo->GetLocation() ); + maPrinterPage.maCommentText.SetText( pInfo->GetComment() ); + } +} + +static rtl::OUString searchAndReplace( const rtl::OUString& i_rOrig, const char* i_pRepl, sal_Int32 i_nReplLen, sal_Int32 i_nReplacement ) +{ + 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_nReplacement ); + if( nPos + i_nReplLen < i_rOrig.getLength() ) + aBuf.append( i_rOrig.getStr() + nPos + i_nReplLen ); + return aBuf.makeStringAndClear(); + } + return i_rOrig; +} + +void PrintDialog::setPreviewText( sal_Int32 nSetPage ) +{ + rtl::OUString aNewText( searchAndReplace( maPageStr, "%p", 2, nSetPage+1 ) ); + aNewText = searchAndReplace( aNewText, "%n", 2, mnCachedPages ); + maPageText.SetText( aNewText ); +} + +void PrintDialog::preparePreview() +{ + // page range may have changed depending on options + sal_Int32 nPages = maPListener->getPageCount(); + mnCachedPages = nPages; + + if( mnCurPage >= nPages ) + mnCurPage = nPages-1; + + setPreviewText( mnCurPage ); + + maPageScrollbar.SetRange( Range( 0, nPages-1 ) ); + maPageScrollbar.SetThumbPos( mnCurPage ); + + boost::shared_ptr<Printer> aPrt( maPListener->getPrinter() ); + + + const MapMode aMapMode( MAP_100TH_MM ); + aPrt->Push(); + aPrt->SetMapMode( aMapMode ); + + Size aPageSize( aPrt->GetPaperSize() ); + Sequence< PropertyValue > aPageParms( maPListener->getPageParameters( mnCurPage ) ); + for( sal_Int32 nProperty = 0, nPropertyCount = aPageParms.getLength(); nProperty < nPropertyCount; ++nProperty ) + { + if( aPageParms[ nProperty ].Name.equalsIgnoreAsciiCaseAscii( "PageSize" ) ) + { + awt::Size aSize; + aPageParms[ nProperty ].Value >>= aSize; + aPageSize.Width() = aSize.Width; + aPageSize.Height() = aSize.Height; + } + } + + aPrt->EnableOutput( FALSE ); + + GDIMetaFile aMtf; + aMtf.SetPrefSize( aPageSize ); + aMtf.SetPrefMapMode( aMapMode ); + aMtf.Record( &(*aPrt) ); + + maPListener->printPage( mnCurPage ); + + aMtf.Stop(); + aMtf.WindStart(); + aPrt->Pop(); + + Size aPreviewSize; + Point aPreviewPos = maPreviewSpace.TopLeft(); + const long nW = maPreviewSpace.GetSize().Width(); + const long nH = maPreviewSpace.GetSize().Height(); + if( aPageSize.Width() > aPageSize.Height() ) + { + aPreviewSize = Size( nW, nW * aPageSize.Height() / aPageSize.Width() ); + aPreviewPos.Y() += (maPreviewSpace.GetHeight() - aPreviewSize.Height())/2; + } + else + { + aPreviewSize = Size( nH * aPageSize.Width() / aPageSize.Height(), nH ); + aPreviewPos.X() += (maPreviewSpace.GetWidth() - aPreviewSize.Width())/2; + } + maPreviewWindow.SetPosSizePixel( aPreviewPos, aPreviewSize ); + const Size aLogicSize( maPreviewWindow.PixelToLogic( maPreviewWindow.GetSizePixel(), MapMode( MAP_100TH_MM ) ) ); + aMtf.Scale( double(aLogicSize.Width())/double(aPageSize.Width()), + double(aLogicSize.Height())/double(aPageSize.Height()) ); + maPreviewWindow.setPreview( aMtf ); +} + +IMPL_LINK( PrintDialog, ScrollHdl, ScrollBar*, pScrBar ) +{ + if( pScrBar == &maPageScrollbar ) + { + sal_Int32 nNewPage = static_cast<sal_Int32>( maPageScrollbar.GetThumbPos() ); + setPreviewText( nNewPage ); + } + return 0; +} + +IMPL_LINK( PrintDialog, ScrollEndHdl, ScrollBar*, pScrBar ) +{ + if( pScrBar == &maPageScrollbar ) + { + sal_Int32 nNewPage = static_cast<sal_Int32>( maPageScrollbar.GetThumbPos() ); + if( nNewPage != mnCurPage ) + { + mnCurPage = nNewPage; + preparePreview(); + } + } + return 0; +} + +IMPL_LINK( PrintDialog, SelectHdl, ListBox*, pBox ) +{ + if( pBox == &maPrinterPage.maPrinters || pBox == &maJobPage.maPrinters ) + { + String aNewPrinter( pBox->GetSelectEntry() ); + maJobPage.maPrinters.SelectEntry( aNewPrinter ); + maPrinterPage.maPrinters.SelectEntry( aNewPrinter ); + // set new printer + maPListener->setPrinter( boost::shared_ptr<Printer>( new Printer( aNewPrinter ) ) ); + // update text fields + updatePrinterText(); + } + return 0; +} + +IMPL_LINK( PrintDialog, ClickHdl, Button*, pButton ) +{ + if( pButton == &maPrinterPage.maSetupButton ) + { + maPListener->getPrinter()->Setup( this ); + } + checkControlDependencies(); + return 0; +} + +IMPL_LINK( PrintDialog, ModifyHdl, Edit*, EMPTYARG ) +{ + checkControlDependencies(); + 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 = maPListener->getValue( it->second ); + DBG_ASSERT( pVal, "property value not found" ); + } + else + { + DBG_ERROR( "changed control not in property map" ); + } + return pVal; +} + +IMPL_LINK( PrintDialog, UIOption_CheckHdl, CheckBox*, i_pBox ) +{ + PropertyValue* pVal = getValueForWindow( i_pBox ); + if( pVal ) + { + 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() ) + { + + 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 ) + { + 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 ) + { + 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::Resize() +{ + Size aPixDiff( LogicToPixel( Size( 5, 5 ), MapMode( MAP_APPFONT ) ) ); + Size aWindowSize( GetOutputSizePixel() ); + + // position buttons from lower end, right to left + Size aBtnSize( maCancelButton.GetSizePixel() ); + Rectangle aBtnRect( Point( aWindowSize.Width() - aPixDiff.Width() - aBtnSize.Width(), + aWindowSize.Height() - aPixDiff.Height() - aBtnSize.Height() ), + aBtnSize ); + maCancelButton.SetPosSizePixel( aBtnRect.TopLeft(), aBtnRect.GetSize() ); + aBtnSize = maOKButton.GetSizePixel(); + aBtnRect = Rectangle( Point( aBtnRect.Left() - aPixDiff.Width() - aBtnSize.Width(), + aWindowSize.Height() - aPixDiff.Height() - aBtnSize.Height() ), + aBtnSize ); + maOKButton.SetPosSizePixel( aBtnRect.TopLeft(), aBtnRect.GetSize() ); + aBtnSize = maButtonLine.GetSizePixel(); + + // position fixed line above buttons + aBtnRect = Rectangle( Point( 0, aBtnRect.Top() - aPixDiff.Width() - aBtnSize.Height()/2 ), + Size( aWindowSize.Width(), aBtnSize.Height() ) ); + maButtonLine.SetPosSizePixel( aBtnRect.TopLeft(), aBtnRect.GetSize() ); + + // position tab control on upper right + aBtnSize = maTabCtrl.GetSizePixel(); + aBtnRect = Rectangle( Point( aWindowSize.Width() - aPixDiff.Width() - aBtnSize.Width(), + aPixDiff.Height() ), + Size( aBtnSize.Width(), maButtonLine.GetPosPixel().Y() - 2*aPixDiff.Height() ) ); + maTabCtrl.SetPosSizePixel( aBtnRect.TopLeft(), aBtnRect.GetSize() ); + + // set size for preview + long nMaxX = maTabCtrl.GetPosPixel().X() - 2*aPixDiff.Width(); + long nMaxY = maButtonLine.GetPosPixel().Y() + - 2 * aPixDiff.Height() + - maPageText.GetSizePixel().Height() + - maPageScrollbar.GetSizePixel().Height(); + long nPreviewLength = std::min( nMaxX, nMaxY ); + maPreviewSpace = Rectangle( Point( aPixDiff.Width(), aPixDiff.Height() ), + Size( nPreviewLength, nPreviewLength ) ); + + // position text and scrollbar below preview + aBtnRect = Rectangle( Point( aPixDiff.Width(), 2*aPixDiff.Height() + nPreviewLength ), + Size( nPreviewLength, maPageScrollbar.GetSizePixel().Height() ) ); + maPageScrollbar.SetPosSizePixel( aBtnRect.TopLeft(), aBtnRect.GetSize() ); + + aBtnRect.Top() = aBtnRect.Bottom() + aPixDiff.Height()/2; + aBtnRect.Bottom() = aBtnRect.Top() + maPageText.GetSizePixel().Height() - 1; + maPageText.SetPosSizePixel( aBtnRect.TopLeft(), aBtnRect.GetSize() ); + + // and do the preview + preparePreview(); +} + +// ----------------------------------------------------------------------------- +// +// 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 ) +{ + 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; + + rtl::OUString aNewText( searchAndReplace( maStr, "%p", 2, mnCur ) ); + aNewText = searchAndReplace( aNewText, "%n", 2, mnMax ); + maText.SetText( aNewText ); + + // update progress + Invalidate( maProgressRect, INVALIDATE_UPDATE ); +} + +void PrintProgressDialog::tick() +{ + if( mnCur < mnMax ) + setProgress( ++mnCur ); +} + +void PrintProgressDialog::Paint( const Rectangle& ) +{ + 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 ); + } +} |