xref: /trunk/main/vcl/source/window/printdlg.cxx (revision 86e1cf34)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #include "precompiled_vcl.hxx"
25 
26 #include "printdlg.hxx"
27 #include "svdata.hxx"
28 #include "svids.hrc"
29 #include "jobset.h"
30 
31 #include "vcl/print.hxx"
32 #include "vcl/dialog.hxx"
33 #include "vcl/button.hxx"
34 #include "vcl/wall.hxx"
35 #include "vcl/status.hxx"
36 #include "vcl/decoview.hxx"
37 #include "vcl/arrange.hxx"
38 #include "vcl/configsettings.hxx"
39 #include "vcl/help.hxx"
40 #include "vcl/decoview.hxx"
41 #include "vcl/svapp.hxx"
42 #include "vcl/unohelp.hxx"
43 
44 #include "unotools/localedatawrapper.hxx"
45 
46 #include "rtl/strbuf.hxx"
47 
48 #include "com/sun/star/lang/XMultiServiceFactory.hpp"
49 #include "com/sun/star/container/XNameAccess.hpp"
50 #include "com/sun/star/beans/PropertyValue.hpp"
51 #include "com/sun/star/awt/Size.hpp"
52 
53 using namespace vcl;
54 using namespace com::sun::star;
55 using namespace com::sun::star::uno;
56 using namespace com::sun::star::lang;
57 using namespace com::sun::star::container;
58 using namespace com::sun::star::beans;
59 
PrintPreviewWindow(Window * i_pParent,const ResId & i_rId)60 PrintDialog::PrintPreviewWindow::PrintPreviewWindow( Window* i_pParent, const ResId& i_rId )
61     : Window( i_pParent, i_rId )
62     , maOrigSize( 10, 10 )
63     , maPageVDev( *this )
64     , maToolTipString( String( VclResId( SV_PRINT_PRINTPREVIEW_TXT ) ) )
65     , mbGreyscale( false )
66     , maHorzDim( this, WB_HORZ | WB_CENTER  )
67     , maVertDim( this, WB_VERT | WB_VCENTER )
68 {
69     SetPaintTransparent( sal_True );
70     SetBackground();
71     if( useHCColorReplacement() )
72         maPageVDev.SetBackground( GetSettings().GetStyleSettings().GetWindowColor() );
73     else
74         maPageVDev.SetBackground( Color( COL_WHITE ) );
75     maHorzDim.Show();
76     maVertDim.Show();
77 
78     maHorzDim.SetText( String( RTL_CONSTASCII_USTRINGPARAM( "2.0in" ) ) );
79     maVertDim.SetText( String( RTL_CONSTASCII_USTRINGPARAM( "2.0in" ) ) );
80 }
81 
~PrintPreviewWindow()82 PrintDialog::PrintPreviewWindow::~PrintPreviewWindow()
83 {
84 }
85 
useHCColorReplacement() const86 bool PrintDialog::PrintPreviewWindow::useHCColorReplacement() const
87 {
88     bool bRet = false;
89     if( GetSettings().GetStyleSettings().GetHighContrastMode() )
90     {
91         try
92         {
93             // get service provider
94             Reference< XMultiServiceFactory > xSMgr( unohelper::GetMultiServiceFactory() );
95             // create configuration hierarchical access name
96             if( xSMgr.is() )
97             {
98                 try
99                 {
100                     Reference< XMultiServiceFactory > xConfigProvider(
101                         Reference< XMultiServiceFactory >(
102                             xSMgr->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
103                                             "com.sun.star.configuration.ConfigurationProvider" ))),
104                             UNO_QUERY )
105                         );
106                     if( xConfigProvider.is() )
107                     {
108                         Sequence< Any > aArgs(1);
109                         PropertyValue aVal;
110                         aVal.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "nodepath" ) );
111                         aVal.Value <<= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.Common/Accessibility" ) );
112                         aArgs.getArray()[0] <<= aVal;
113                         Reference< XNameAccess > xConfigAccess(
114                             Reference< XNameAccess >(
115                                 xConfigProvider->createInstanceWithArguments( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
116                                                     "com.sun.star.configuration.ConfigurationAccess" )),
117                                                                                 aArgs ),
118                                 UNO_QUERY )
119                             );
120                         if( xConfigAccess.is() )
121                         {
122                             try
123                             {
124                                 sal_Bool bValue = sal_False;
125                                 Any aAny = xConfigAccess->getByName( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsForPagePreviews" ) ) );
126                                 if( aAny >>= bValue )
127                                     bRet = bool(bValue);
128                             }
129                             catch( NoSuchElementException& )
130                             {
131                             }
132                             catch( WrappedTargetException& )
133                             {
134                             }
135                         }
136                     }
137                 }
138                 catch( Exception& )
139                 {
140                 }
141             }
142         }
143         catch( WrappedTargetException& )
144         {
145         }
146     }
147     return bRet;
148 }
149 
DataChanged(const DataChangedEvent & i_rDCEvt)150 void PrintDialog::PrintPreviewWindow::DataChanged( const DataChangedEvent& i_rDCEvt )
151 {
152     // react on settings changed
153     if( i_rDCEvt.GetType() == DATACHANGED_SETTINGS )
154     {
155         if( useHCColorReplacement() )
156             maPageVDev.SetBackground( GetSettings().GetStyleSettings().GetWindowColor() );
157         else
158             maPageVDev.SetBackground( Color( COL_WHITE ) );
159     }
160     Window::DataChanged( i_rDCEvt );
161 }
162 
Resize()163 void PrintDialog::PrintPreviewWindow::Resize()
164 {
165     Size aNewSize( GetSizePixel() );
166     long nTextHeight = maHorzDim.GetTextHeight();
167     // leave small space for decoration
168     aNewSize.Width() -= nTextHeight + 2;
169     aNewSize.Height() -= nTextHeight + 2;
170     Size aScaledSize;
171     double fScale = 1.0;
172 
173     // #i106435# catch corner case of Size(0,0)
174     Size aOrigSize( maOrigSize );
175     if( aOrigSize.Width() < 1 )
176         aOrigSize.Width() = aNewSize.Width();
177     if( aOrigSize.Height() < 1 )
178         aOrigSize.Height() = aNewSize.Height();
179     if( aOrigSize.Width() > aOrigSize.Height() )
180     {
181         aScaledSize = Size( aNewSize.Width(), aNewSize.Width() * aOrigSize.Height() / aOrigSize.Width() );
182         if( aScaledSize.Height() > aNewSize.Height() )
183             fScale = double(aNewSize.Height())/double(aScaledSize.Height());
184     }
185     else
186     {
187         aScaledSize = Size( aNewSize.Height() * aOrigSize.Width() / aOrigSize.Height(), aNewSize.Height() );
188         if( aScaledSize.Width() > aNewSize.Width() )
189             fScale = double(aNewSize.Width())/double(aScaledSize.Width());
190     }
191     aScaledSize.Width() = long(aScaledSize.Width()*fScale);
192     aScaledSize.Height() = long(aScaledSize.Height()*fScale);
193 
194     maPreviewSize = aScaledSize;
195 
196     // #i104784# if we render the page too small then rounding issues result in
197     // layout artifacts looking really bad. So scale the page unto a device that is not
198     // full page size but not too small either. This also results in much better visual
199     // quality of the preview, e.g. when its height approaches the number of text lines
200     // find a good scaling factor
201     Size aPreviewMMSize( maPageVDev.PixelToLogic( aScaledSize, MapMode( MAP_100TH_MM ) ) );
202     double fZoom = double(maOrigSize.Height())/double(aPreviewMMSize.Height());
203     while( fZoom > 10 )
204     {
205         aScaledSize.Width() *= 2;
206         aScaledSize.Height() *= 2;
207         fZoom /= 2.0;
208     }
209 
210     maPageVDev.SetOutputSizePixel( aScaledSize, sal_False );
211 
212     // position dimension lines
213     Point aRef( nTextHeight + (aNewSize.Width() - maPreviewSize.Width())/2,
214                 nTextHeight + (aNewSize.Height() - maPreviewSize.Height())/2 );
215     maHorzDim.SetPosSizePixel( Point( aRef.X(), aRef.Y() - nTextHeight ),
216                                Size( maPreviewSize.Width(), nTextHeight ) );
217     maVertDim.SetPosSizePixel( Point( aRef.X() - nTextHeight, aRef.Y() ),
218                                Size( nTextHeight, maPreviewSize.Height() ) );
219 
220 }
221 
Paint(const Rectangle &)222 void PrintDialog::PrintPreviewWindow::Paint( const Rectangle& )
223 {
224     long nTextHeight = maHorzDim.GetTextHeight();
225     Size aSize( GetSizePixel() );
226     aSize.Width()  -= nTextHeight;
227     aSize.Height() -= nTextHeight;
228     if( maReplacementString.getLength() != 0 )
229     {
230         // replacement is active
231         Push();
232         Rectangle aTextRect( Point( nTextHeight, nTextHeight ), aSize );
233         DecorationView aVw( this );
234         aVw.DrawFrame( aTextRect, FRAME_DRAW_GROUP );
235         aTextRect.Left()   += 2;
236         aTextRect.Top()    += 2;
237         aTextRect.Right()  -= 2;
238         aTextRect.Bottom() -= 2;
239         Font aFont( GetSettings().GetStyleSettings().GetLabelFont() );
240         SetZoomedPointFont( aFont );
241         DrawText( aTextRect, maReplacementString,
242                   TEXT_DRAW_CENTER | TEXT_DRAW_VCENTER | TEXT_DRAW_WORDBREAK | TEXT_DRAW_MULTILINE
243                  );
244         Pop();
245     }
246     else
247     {
248         GDIMetaFile aMtf( maMtf );
249 
250         Point aOffset( (aSize.Width() - maPreviewSize.Width()) / 2 + nTextHeight,
251                        (aSize.Height() - maPreviewSize.Height()) / 2 + nTextHeight );
252 
253         const Size aVDevSize( maPageVDev.GetOutputSizePixel() );
254         const Size aLogicSize( maPageVDev.PixelToLogic( aVDevSize, MapMode( MAP_100TH_MM ) ) );
255         Size aOrigSize( maOrigSize );
256         if( aOrigSize.Width() < 1 )
257             aOrigSize.Width() = aLogicSize.Width();
258         if( aOrigSize.Height() < 1 )
259             aOrigSize.Height() = aLogicSize.Height();
260         double fScale = double(aLogicSize.Width())/double(aOrigSize.Width());
261 
262 
263         maPageVDev.Erase();
264         maPageVDev.Push();
265         maPageVDev.SetMapMode( MAP_100TH_MM );
266         sal_uLong nOldDrawMode = maPageVDev.GetDrawMode();
267         if( mbGreyscale )
268             maPageVDev.SetDrawMode( maPageVDev.GetDrawMode() |
269                                     ( DRAWMODE_GRAYLINE | DRAWMODE_GRAYFILL | DRAWMODE_GRAYTEXT |
270                                       DRAWMODE_GRAYBITMAP | DRAWMODE_GRAYGRADIENT ) );
271         aMtf.WindStart();
272         aMtf.Scale( fScale, fScale );
273         aMtf.WindStart();
274 
275         const sal_uInt16 nOriginalAA(maPageVDev.GetAntialiasing());
276         static bool bNicePrintPreview(true);
277 
278         if(bNicePrintPreview)
279         {
280             // replay metafile with AntiAliasing
281             maPageVDev.SetAntialiasing(nOriginalAA | ANTIALIASING_ENABLE_B2DDRAW);
282         }
283 
284         aMtf.Play( &maPageVDev, Point( 0, 0 ), aLogicSize );
285 
286         maPageVDev.SetAntialiasing(nOriginalAA);
287         maPageVDev.Pop();
288 
289         SetMapMode( MAP_PIXEL );
290         maPageVDev.SetMapMode( MAP_PIXEL );
291 
292         if(bNicePrintPreview)
293         {
294             // use lanzcos scaling
295             Bitmap aContent(maPageVDev.GetBitmap(Point(0, 0), aVDevSize));
296             aContent.Scale(maPreviewSize, BMP_SCALE_BESTQUALITY);
297             DrawBitmap(aOffset, aContent);
298         }
299         else
300         {
301             // direct paint (copy from OutDev to OutDev) is fast, but does not do
302             // any good scaling at all (currently)
303             DrawOutDev( aOffset, maPreviewSize, Point( 0, 0 ), aVDevSize, maPageVDev );
304         }
305 
306         maPageVDev.SetDrawMode( nOldDrawMode );
307 
308         DecorationView aVw( this );
309         Rectangle aFrame( aOffset + Point( -1, -1 ), Size( maPreviewSize.Width() + 2, maPreviewSize.Height() + 2 ) );
310         aVw.DrawFrame( aFrame, FRAME_DRAW_GROUP );
311     }
312 }
313 
Command(const CommandEvent & rEvt)314 void PrintDialog::PrintPreviewWindow::Command( const CommandEvent& rEvt )
315 {
316     if( rEvt.GetCommand() == COMMAND_WHEEL )
317     {
318         const CommandWheelData* pWheelData = rEvt.GetWheelData();
319         PrintDialog* pDlg = dynamic_cast<PrintDialog*>(GetParent());
320         if( pDlg )
321         {
322             if( pWheelData->GetDelta() > 0 )
323                 pDlg->previewForward();
324             else if( pWheelData->GetDelta() < 0 )
325                 pDlg->previewBackward();
326             /*
327             else
328                 huh ?
329             */
330         }
331     }
332 }
333 
setPreview(const GDIMetaFile & i_rNewPreview,const Size & i_rOrigSize,const rtl::OUString & i_rPaperName,const rtl::OUString & i_rReplacement,sal_Int32 i_nDPIX,sal_Int32 i_nDPIY,bool i_bGreyscale)334 void PrintDialog::PrintPreviewWindow::setPreview( const GDIMetaFile& i_rNewPreview,
335                                                   const Size& i_rOrigSize,
336                                                   const rtl::OUString& i_rPaperName,
337                                                   const rtl::OUString& i_rReplacement,
338                                                   sal_Int32 i_nDPIX,
339                                                   sal_Int32 i_nDPIY,
340                                                   bool i_bGreyscale
341                                                  )
342 {
343     rtl::OUStringBuffer aBuf( 256 );
344     aBuf.append( maToolTipString );
345     SetQuickHelpText( aBuf.makeStringAndClear() );
346     maMtf = i_rNewPreview;
347     if( useHCColorReplacement() )
348     {
349         maMtf.ReplaceColors( Color( COL_BLACK ), Color( COL_WHITE ), 30 );
350     }
351 
352     maOrigSize = i_rOrigSize;
353     maReplacementString = i_rReplacement;
354     mbGreyscale = i_bGreyscale;
355     maPageVDev.SetReferenceDevice( i_nDPIX, i_nDPIY );
356     maPageVDev.EnableOutput( sal_True );
357 
358     // use correct measurements
359     const LocaleDataWrapper& rLocWrap( GetSettings().GetLocaleDataWrapper() );
360     MapUnit eUnit = MAP_MM;
361     int nDigits = 0;
362     if( rLocWrap.getMeasurementSystemEnum() == MEASURE_US )
363     {
364         eUnit = MAP_100TH_INCH;
365         nDigits = 2;
366     }
367     Size aLogicPaperSize( LogicToLogic( i_rOrigSize, MapMode( MAP_100TH_MM ), MapMode( eUnit ) ) );
368     String aNumText( rLocWrap.getNum( aLogicPaperSize.Width(), nDigits ) );
369     aBuf.append( aNumText )
370         .append( sal_Unicode( ' ' ) );
371     aBuf.appendAscii( eUnit == MAP_MM ? "mm" : "in" );
372     if( i_rPaperName.getLength() )
373     {
374         aBuf.appendAscii( " (" );
375         aBuf.append( i_rPaperName );
376         aBuf.append( sal_Unicode(')') );
377     }
378     maHorzDim.SetText( aBuf.makeStringAndClear() );
379 
380     aNumText = rLocWrap.getNum( aLogicPaperSize.Height(), nDigits );
381     aBuf.append( aNumText )
382         .append( sal_Unicode( ' ' ) );
383     aBuf.appendAscii( eUnit == MAP_MM ? "mm" : "in" );
384     maVertDim.SetText( aBuf.makeStringAndClear() );
385 
386     Resize();
387     Invalidate();
388 }
389 
ShowNupOrderWindow(Window * i_pParent)390 PrintDialog::ShowNupOrderWindow::ShowNupOrderWindow( Window* i_pParent )
391     : Window( i_pParent, WB_NOBORDER )
392     , mnOrderMode( 0 )
393     , mnRows( 1 )
394     , mnColumns( 1 )
395 {
396     ImplInitSettings();
397 }
398 
~ShowNupOrderWindow()399 PrintDialog::ShowNupOrderWindow::~ShowNupOrderWindow()
400 {
401 }
402 
ImplInitSettings()403 void PrintDialog::ShowNupOrderWindow::ImplInitSettings()
404 {
405     SetBackground( Wallpaper( GetSettings().GetStyleSettings().GetFieldColor() ) );
406 }
407 
Paint(const Rectangle & i_rRect)408 void PrintDialog::ShowNupOrderWindow::Paint( const Rectangle& i_rRect )
409 {
410     Window::Paint( i_rRect );
411     SetMapMode( MAP_PIXEL );
412     SetTextColor( GetSettings().GetStyleSettings().GetFieldTextColor() );
413 
414     int nPages = mnRows * mnColumns;
415     Font aFont( GetSettings().GetStyleSettings().GetFieldFont() );
416     aFont.SetSize( Size( 0, 24 ) );
417     SetFont( aFont );
418     Size aSampleTextSize( GetTextWidth( rtl::OUString::valueOf( sal_Int32(nPages+1) ) ), GetTextHeight() );
419 
420     Size aOutSize( GetOutputSizePixel() );
421     Size aSubSize( aOutSize.Width() / mnColumns, aOutSize.Height() / mnRows );
422     // calculate font size: shrink the sample text so it fits
423     double fX = double(aSubSize.Width())/double(aSampleTextSize.Width());
424     double fY = double(aSubSize.Height())/double(aSampleTextSize.Height());
425     double fScale = (fX < fY) ? fX : fY;
426     long nFontHeight = long(24.0*fScale) - 3;
427     if( nFontHeight < 5 )
428         nFontHeight = 5;
429     aFont.SetSize( Size( 0, nFontHeight ) );
430     SetFont( aFont );
431     long nTextHeight = GetTextHeight();
432     for( int i = 0; i < nPages; i++ )
433     {
434         rtl::OUString aPageText( rtl::OUString::valueOf( sal_Int32(i+1) ) );
435         int nX = 0, nY = 0;
436         switch( mnOrderMode )
437         {
438         case SV_PRINT_PRT_NUP_ORDER_LRTB:
439             nX = (i % mnColumns); nY = (i / mnColumns);
440             break;
441         case SV_PRINT_PRT_NUP_ORDER_TBLR:
442             nX = (i / mnRows); nY = (i % mnRows);
443             break;
444         case SV_PRINT_PRT_NUP_ORDER_RLTB:
445             nX = mnColumns - 1 - (i % mnColumns); nY = (i / mnColumns);
446             break;
447         case SV_PRINT_PRT_NUP_ORDER_TBRL:
448             nX = mnColumns - 1 - (i / mnRows); nY = (i % mnRows);
449             break;
450         }
451         Size aTextSize( GetTextWidth( aPageText ), nTextHeight );
452         int nDeltaX = (aSubSize.Width() - aTextSize.Width()) / 2;
453         int nDeltaY = (aSubSize.Height() - aTextSize.Height()) / 2;
454         DrawText( Point( nX * aSubSize.Width() + nDeltaX,
455                          nY * aSubSize.Height() + nDeltaY ),
456                   aPageText );
457     }
458     DecorationView aVw( this );
459     aVw.DrawFrame( Rectangle( Point( 0, 0), aOutSize ), FRAME_DRAW_GROUP );
460 }
461 
NUpTabPage(Window * i_pParent,const ResId & rResId)462 PrintDialog::NUpTabPage::NUpTabPage( Window* i_pParent, const ResId& rResId )
463     : TabPage( i_pParent, rResId )
464     , maNupLine( this, VclResId( SV_PRINT_PRT_NUP_LAYOUT_FL ) )
465     , maPagesBtn( this, VclResId( SV_PRINT_PRT_NUP_PAGES_BTN ) )
466     , maBrochureBtn( this, VclResId( SV_PRINT_PRT_NUP_BROCHURE_BTN ) )
467     , maPagesBoxTitleTxt( this, 0 )
468     , maNupPagesBox( this, VclResId( SV_PRINT_PRT_NUP_PAGES_BOX ) )
469     , maNupNumPagesTxt( this, VclResId( SV_PRINT_PRT_NUP_NUM_PAGES_TXT ) )
470     , maNupColEdt( this, VclResId( SV_PRINT_PRT_NUP_COLS_EDT ) )
471     , maNupTimesTxt( this, VclResId( SV_PRINT_PRT_NUP_TIMES_TXT ) )
472     , maNupRowsEdt( this, VclResId( SV_PRINT_PRT_NUP_ROWS_EDT ) )
473     , maPageMarginTxt1( this, VclResId( SV_PRINT_PRT_NUP_MARGINS_PAGES_1_TXT ) )
474     , maPageMarginEdt( this, VclResId( SV_PRINT_PRT_NUP_MARGINS_PAGES_EDT ) )
475     , maPageMarginTxt2( this, VclResId( SV_PRINT_PRT_NUP_MARGINS_PAGES_2_TXT ) )
476     , maSheetMarginTxt1( this, VclResId( SV_PRINT_PRT_NUP_MARGINS_SHEET_1_TXT ) )
477     , maSheetMarginEdt( this, VclResId( SV_PRINT_PRT_NUP_MARGINS_SHEET_EDT ) )
478     , maSheetMarginTxt2( this, VclResId( SV_PRINT_PRT_NUP_MARGINS_SHEET_2_TXT ) )
479     , maNupOrientationTxt( this, VclResId( SV_PRINT_PRT_NUP_ORIENTATION_TXT ) )
480     , maNupOrientationBox( this, VclResId( SV_PRINT_PRT_NUP_ORIENTATION_BOX ) )
481     , maNupOrderTxt( this, VclResId( SV_PRINT_PRT_NUP_ORDER_TXT ) )
482     , maNupOrderBox( this, VclResId( SV_PRINT_PRT_NUP_ORDER_BOX ) )
483     , maNupOrderWin( this )
484     , maBorderCB( this, VclResId( SV_PRINT_PRT_NUP_BORDER_CB ) )
485 {
486     FreeResource();
487 
488     maNupOrderWin.Show();
489     maPagesBtn.Check( sal_True );
490     maBrochureBtn.Show( sal_False );
491 
492     // setup field units for metric fields
493     const LocaleDataWrapper& rLocWrap( maPageMarginEdt.GetLocaleDataWrapper() );
494     FieldUnit eUnit = FUNIT_MM;
495     sal_uInt16 nDigits = 0;
496     if( rLocWrap.getMeasurementSystemEnum() == MEASURE_US )
497     {
498         eUnit = FUNIT_INCH;
499         nDigits = 2;
500     }
501     // set units
502     maPageMarginEdt.SetUnit( eUnit );
503     maSheetMarginEdt.SetUnit( eUnit );
504 
505     // set precision
506     maPageMarginEdt.SetDecimalDigits( nDigits );
507     maSheetMarginEdt.SetDecimalDigits( nDigits );
508 
509     setupLayout();
510 }
511 
~NUpTabPage()512 PrintDialog::NUpTabPage::~NUpTabPage()
513 {
514 }
515 
enableNupControls(bool bEnable)516 void PrintDialog::NUpTabPage::enableNupControls( bool bEnable )
517 {
518     maNupPagesBox.Enable( sal_True );
519     maNupNumPagesTxt.Enable( bEnable );
520     maNupColEdt.Enable( bEnable );
521     maNupTimesTxt.Enable( bEnable );
522     maNupRowsEdt.Enable( bEnable );
523     maPageMarginTxt1.Enable( bEnable );
524     maPageMarginEdt.Enable( bEnable );
525     maPageMarginTxt2.Enable( bEnable );
526     maSheetMarginTxt1.Enable( bEnable );
527     maSheetMarginEdt.Enable( bEnable );
528     maSheetMarginTxt2.Enable( bEnable );
529     maNupOrientationTxt.Enable( bEnable );
530     maNupOrientationBox.Enable( bEnable );
531     maNupOrderTxt.Enable( bEnable );
532     maNupOrderBox.Enable( bEnable );
533     maNupOrderWin.Enable( bEnable );
534     maBorderCB.Enable( bEnable );
535 }
536 
showAdvancedControls(bool i_bShow)537 void PrintDialog::NUpTabPage::showAdvancedControls( bool i_bShow )
538 {
539     maNupNumPagesTxt.Show( i_bShow );
540     maNupColEdt.Show( i_bShow );
541     maNupTimesTxt.Show( i_bShow );
542     maNupRowsEdt.Show( i_bShow );
543     maPageMarginTxt1.Show( i_bShow );
544     maPageMarginEdt.Show( i_bShow );
545     maPageMarginTxt2.Show( i_bShow );
546     maSheetMarginTxt1.Show( i_bShow );
547     maSheetMarginEdt.Show( i_bShow );
548     maSheetMarginTxt2.Show( i_bShow );
549     maNupOrientationTxt.Show( i_bShow );
550     maNupOrientationBox.Show( i_bShow );
551     getLayout()->resize();
552 }
553 
setupLayout()554 void PrintDialog::NUpTabPage::setupLayout()
555 {
556     boost::shared_ptr<vcl::RowOrColumn> xLayout =
557         boost::dynamic_pointer_cast<vcl::RowOrColumn>( getLayout() );
558     Size aBorder( LogicToPixel( Size( 6, 6 ), MapMode( MAP_APPFONT ) ) );
559     /*  According to OOo style guide, the horizontal indentation of child
560         elements to their parent element should always be 6 map units. */
561     long nIndent = aBorder.Width();
562 
563     xLayout->addWindow( &maNupLine );
564     boost::shared_ptr< vcl::RowOrColumn > xRow( new vcl::RowOrColumn( xLayout.get(), false ) );
565     xLayout->addChild( xRow );
566     boost::shared_ptr< vcl::Indenter > xIndent( new vcl::Indenter( xRow.get() ) );
567     xRow->addChild( xIndent );
568 
569     boost::shared_ptr< vcl::RowOrColumn > xShowNupCol( new vcl::RowOrColumn( xRow.get() ) );
570     xRow->addChild( xShowNupCol, -1 );
571     xShowNupCol->setMinimumSize( xShowNupCol->addWindow( &maNupOrderWin ), Size( 70, 70 ) );
572     boost::shared_ptr< vcl::Spacer > xSpacer( new vcl::Spacer( xShowNupCol.get() ) );
573     xShowNupCol->addChild( xSpacer );
574 
575     boost::shared_ptr< vcl::LabelColumn > xMainCol( new vcl::LabelColumn( xIndent.get() ) );
576     xIndent->setChild( xMainCol );
577 
578     size_t nPagesIndex = xMainCol->addRow( &maPagesBtn, &maNupPagesBox );
579     mxPagesBtnLabel = boost::dynamic_pointer_cast<vcl::LabeledElement>( xMainCol->getChild( nPagesIndex ) );
580 
581     xRow.reset( new vcl::RowOrColumn( xMainCol.get(), false ) );
582     xMainCol->addRow( &maNupNumPagesTxt, xRow, nIndent );
583     xRow->addWindow( &maNupColEdt );
584     xRow->addWindow( &maNupTimesTxt );
585     xRow->addWindow( &maNupRowsEdt );
586 
587     boost::shared_ptr< vcl::LabeledElement > xLab( new vcl::LabeledElement( xMainCol.get(), 2 ) );
588     xLab->setLabel( &maPageMarginEdt );
589     xLab->setElement( &maPageMarginTxt2 );
590     xMainCol->addRow( &maPageMarginTxt1, xLab, nIndent );
591 
592     xLab.reset( new vcl::LabeledElement( xMainCol.get(), 2 ) );
593     xLab->setLabel( &maSheetMarginEdt );
594     xLab->setElement( &maSheetMarginTxt2 );
595     xMainCol->addRow( &maSheetMarginTxt1, xLab, nIndent );
596 
597     xMainCol->addRow( &maNupOrientationTxt, &maNupOrientationBox, nIndent );
598     xMainCol->addRow( &maNupOrderTxt, &maNupOrderBox, nIndent );
599     xMainCol->setBorders( xMainCol->addWindow( &maBorderCB ), nIndent, 0, 0, 0 );
600 
601     xSpacer.reset( new vcl::Spacer( xMainCol.get(), 0, Size( 10, WindowArranger::getDefaultBorder() ) ) );
602     xMainCol->addChild( xSpacer );
603 
604     xRow.reset( new vcl::RowOrColumn( xMainCol.get(), false ) );
605     xMainCol->addRow( &maBrochureBtn, xRow );
606     // remember brochure row for dependencies
607     mxBrochureDep = xRow;
608 
609     // initially advanced controls are not shown, rows=columns=1
610     showAdvancedControls( false );
611 }
612 
initFromMultiPageSetup(const vcl::PrinterController::MultiPageSetup & i_rMPS)613 void PrintDialog::NUpTabPage::initFromMultiPageSetup( const vcl::PrinterController::MultiPageSetup& i_rMPS )
614 {
615     maSheetMarginEdt.SetValue( maSheetMarginEdt.Normalize( i_rMPS.nLeftMargin ), FUNIT_100TH_MM );
616     maPageMarginEdt.SetValue( maPageMarginEdt.Normalize( i_rMPS.nHorizontalSpacing ), FUNIT_100TH_MM );
617     maBorderCB.Check( i_rMPS.bDrawBorder );
618     maNupRowsEdt.SetValue( i_rMPS.nRows );
619     maNupColEdt.SetValue( i_rMPS.nColumns );
620     maBorderCB.Check( i_rMPS.bDrawBorder );
621     for( sal_uInt16 i = 0; i < maNupOrderBox.GetEntryCount(); i++ )
622     {
623         if( int(sal_IntPtr(maNupOrderBox.GetEntryData( i ))) == i_rMPS.nOrder )
624             maNupOrderBox.SelectEntryPos( i );
625     }
626     if( i_rMPS.nRows != 1 || i_rMPS.nColumns != 1 )
627     {
628         maNupPagesBox.SelectEntryPos( maNupPagesBox.GetEntryCount()-1 );
629         showAdvancedControls( true );
630         maNupOrderWin.setValues( i_rMPS.nOrder, i_rMPS.nColumns, i_rMPS.nRows );
631     }
632 }
633 
readFromSettings()634 void PrintDialog::NUpTabPage::readFromSettings()
635 {
636 }
637 
storeToSettings()638 void PrintDialog::NUpTabPage::storeToSettings()
639 {
640 }
641 
JobTabPage(Window * i_pParent,const ResId & rResId)642 PrintDialog::JobTabPage::JobTabPage( Window* i_pParent, const ResId& rResId )
643     : TabPage( i_pParent, rResId )
644     , maPrinterFL( this, VclResId( SV_PRINT_PRINTERS_FL ) )
645     , maPrinters( this, VclResId( SV_PRINT_PRINTERS ) )
646     , maDetailsBtn( this, VclResId( SV_PRINT_DETAILS_BTN ) )
647     , maStatusLabel( this, VclResId( SV_PRINT_STATUS_TXT ) )
648     , maStatusTxt( this, 0 )
649     , maLocationLabel( this, VclResId( SV_PRINT_LOCATION_TXT ) )
650     , maLocationTxt( this, 0 )
651     , maCommentLabel( this, VclResId( SV_PRINT_COMMENT_TXT ) )
652     , maCommentTxt( this, 0 )
653     , maSetupButton( this, VclResId( SV_PRINT_PRT_SETUP ) )
654     , maCopies( this, VclResId( SV_PRINT_COPIES ) )
655     , maCopySpacer( this, WB_VERT )
656     , maCopyCount( this, VclResId( SV_PRINT_COPYCOUNT ) )
657     , maCopyCountField( this, VclResId( SV_PRINT_COPYCOUNT_FIELD ) )
658     , maCollateBox( this, VclResId( SV_PRINT_COLLATE ) )
659     , maCollateImage( this, VclResId( SV_PRINT_COLLATE_IMAGE ) )
660     , maReverseOrderBox( this, VclResId( SV_PRINT_OPT_REVERSE ) )
661     , maCollateImg( VclResId( SV_PRINT_COLLATE_IMG ) )
662     , maCollateHCImg( VclResId( SV_PRINT_COLLATE_HC_IMG ) )
663     , maNoCollateImg( VclResId( SV_PRINT_NOCOLLATE_IMG ) )
664     , maNoCollateHCImg( VclResId( SV_PRINT_NOCOLLATE_HC_IMG ) )
665     , mnCollateUIMode( 0 )
666 {
667     FreeResource();
668 
669     maCopySpacer.Show();
670     maStatusTxt.Show();
671     maCommentTxt.Show();
672     maLocationTxt.Show();
673 
674     setupLayout();
675 }
676 
~JobTabPage()677 PrintDialog::JobTabPage::~JobTabPage()
678 {
679 }
680 
setupLayout()681 void PrintDialog::JobTabPage::setupLayout()
682 {
683     // HACK: this is not a dropdown box, but the dropdown line count
684     // sets the results of GetOptimalSize in a normal ListBox
685     maPrinters.SetDropDownLineCount( 4 );
686 
687     boost::shared_ptr<vcl::RowOrColumn> xLayout =
688         boost::dynamic_pointer_cast<vcl::RowOrColumn>( getLayout() );
689 
690     // add printer fixed line
691     xLayout->addWindow( &maPrinterFL );
692     // add print LB
693     xLayout->addWindow( &maPrinters, 3 );
694 
695     // create a row for details button/text and properties button
696     boost::shared_ptr< vcl::RowOrColumn > xDetRow( new vcl::RowOrColumn( xLayout.get(), false ) );
697     xLayout->addChild( xDetRow );
698     xDetRow->addWindow( &maDetailsBtn );
699     xDetRow->addChild( new vcl::Spacer( xDetRow.get(), 2 ) );
700     xDetRow->addWindow( &maSetupButton );
701 
702     // create an indent for details
703     boost::shared_ptr< vcl::Indenter > xIndent( new vcl::Indenter( xLayout.get() ) );
704     xLayout->addChild( xIndent );
705     // remember details controls
706     mxDetails = xIndent;
707     // create a column for the details
708     boost::shared_ptr< vcl::LabelColumn > xLabelCol( new vcl::LabelColumn( xIndent.get() ) );
709     xIndent->setChild( xLabelCol );
710     xLabelCol->addRow( &maStatusLabel, &maStatusTxt );
711     xLabelCol->addRow( &maLocationLabel, &maLocationTxt );
712     xLabelCol->addRow( &maCommentLabel, &maCommentTxt );
713 
714     // add print range and copies columns
715     xLayout->addWindow( &maCopies );
716     boost::shared_ptr< vcl::RowOrColumn > xRangeRow( new vcl::RowOrColumn( xLayout.get(), false ) );
717     xLayout->addChild( xRangeRow );
718 
719     // create print range and add to range row
720     mxPrintRange.reset( new vcl::RowOrColumn( xRangeRow.get() ) );
721     xRangeRow->addChild( mxPrintRange );
722     xRangeRow->addWindow( &maCopySpacer );
723 
724     boost::shared_ptr< vcl::RowOrColumn > xCopyCollateCol( new vcl::RowOrColumn( xRangeRow.get() ) );
725     xRangeRow->addChild( xCopyCollateCol );
726 
727     // add copies row to copy/collate column
728     boost::shared_ptr< vcl::LabeledElement > xCopiesRow( new vcl::LabeledElement( xCopyCollateCol.get(), 2 ) );
729     xCopyCollateCol->addChild( xCopiesRow );
730     xCopiesRow->setLabel( &maCopyCount );
731     xCopiesRow->setElement( &maCopyCountField );
732     boost::shared_ptr< vcl::LabeledElement > xCollateRow( new vcl::LabeledElement( xCopyCollateCol.get(), 2 ) );
733     xCopyCollateCol->addChild( xCollateRow );
734     xCollateRow->setLabel( &maCollateBox );
735     xCollateRow->setElement( &maCollateImage );
736 
737     // maDetailsBtn.SetStyle( maDetailsBtn.GetStyle() | (WB_SMALLSTYLE | WB_BEVELBUTTON) );
738     mxDetails->show( false, false );
739 }
740 
readFromSettings()741 void PrintDialog::JobTabPage::readFromSettings()
742 {
743     SettingsConfigItem* pItem = SettingsConfigItem::get();
744     rtl::OUString aValue;
745 
746     #if 0
747     // do not actually make copy count persistent
748     // the assumption is that this would lead to a lot of unwanted copies
749     aValue = pItem->getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintDialog" ) ),
750                               rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CopyCount" ) ) );
751     sal_Int32 nVal = aValue.toInt32();
752     maCopyCountField.SetValue( sal_Int64(nVal > 1 ? nVal : 1) );
753     #endif
754 
755     aValue = pItem->getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintDialog" ) ),
756                               rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CollateBox" ) ) );
757     if( aValue.equalsIgnoreAsciiCaseAscii( "alwaysoff" ) )
758     {
759         mnCollateUIMode = 1;
760         maCollateBox.Check( sal_False );
761         maCollateBox.Enable( sal_False );
762     }
763     else
764     {
765         mnCollateUIMode = 0;
766         aValue = pItem->getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintDialog" ) ),
767                                   rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Collate" ) ) );
768         maCollateBox.Check( aValue.equalsIgnoreAsciiCaseAscii( "true" ) );
769     }
770     Resize();
771 }
772 
storeToSettings()773 void PrintDialog::JobTabPage::storeToSettings()
774 {
775     SettingsConfigItem* pItem = SettingsConfigItem::get();
776     pItem->setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintDialog" ) ),
777                      rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CopyCount" ) ),
778                      maCopyCountField.GetText() );
779     pItem->setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintDialog" ) ),
780                      rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Collate" ) ),
781                      rtl::OUString::createFromAscii( maCollateBox.IsChecked() ? "true" : "false" ) );
782 }
783 
OutputOptPage(Window * i_pParent,const ResId & i_rResId)784 PrintDialog::OutputOptPage::OutputOptPage( Window* i_pParent, const ResId& i_rResId )
785     : TabPage( i_pParent, i_rResId )
786     , maOptionsLine( this, VclResId( SV_PRINT_OPT_PRINT_FL ) )
787     , maToFileBox( this, VclResId( SV_PRINT_OPT_TOFILE ) )
788     , maCollateSingleJobsBox( this, VclResId( SV_PRINT_OPT_SINGLEJOBS ) )
789 {
790     FreeResource();
791 
792     setupLayout();
793 }
794 
~OutputOptPage()795 PrintDialog::OutputOptPage::~OutputOptPage()
796 {
797 }
798 
setupLayout()799 void PrintDialog::OutputOptPage::setupLayout()
800 {
801     boost::shared_ptr<vcl::RowOrColumn> xLayout =
802         boost::dynamic_pointer_cast<vcl::RowOrColumn>( getLayout() );
803 
804     xLayout->addWindow( &maOptionsLine );
805     boost::shared_ptr<vcl::Indenter> xIndent( new vcl::Indenter( xLayout.get(), -1 ) );
806     xLayout->addChild( xIndent );
807     boost::shared_ptr<vcl::RowOrColumn> xCol( new vcl::RowOrColumn( xIndent.get() ) );
808     xIndent->setChild( xCol );
809     mxOptGroup = xCol;
810     xCol->addWindow( &maToFileBox );
811     xCol->addWindow( &maCollateSingleJobsBox );
812 }
813 
readFromSettings()814 void PrintDialog::OutputOptPage::readFromSettings()
815 {
816     #if 0
817     SettingsConfigItem* pItem = SettingsConfigItem::get();
818     rtl::OUString aValue;
819 
820     aValue = pItem->getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintDialog" ) ),
821                               rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ToFile" ) ) );
822     maToFileBox.Check( aValue.equalsIgnoreAsciiCaseAscii( "true" ) );
823     #endif
824 }
825 
storeToSettings()826 void PrintDialog::OutputOptPage::storeToSettings()
827 {
828     SettingsConfigItem* pItem = SettingsConfigItem::get();
829     pItem->setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintDialog" ) ),
830                      rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ToFile" ) ),
831                      rtl::OUString::createFromAscii( maToFileBox.IsChecked() ? "true" : "false" ) );
832 }
833 
PrintDialog(Window * i_pParent,const boost::shared_ptr<PrinterController> & i_rController)834 PrintDialog::PrintDialog( Window* i_pParent, const boost::shared_ptr<PrinterController>& i_rController )
835     : ModalDialog( i_pParent, VclResId( SV_DLG_PRINT ) )
836     , maOKButton( this, VclResId( SV_PRINT_OK ) )
837     , maCancelButton( this, VclResId( SV_PRINT_CANCEL ) )
838     , maHelpButton( this, VclResId( SV_PRINT_HELP ) )
839     , maPreviewWindow( this, VclResId( SV_PRINT_PAGE_PREVIEW ) )
840     , maPageEdit( this, VclResId( SV_PRINT_PAGE_EDIT ) )
841     , maNumPagesText( this, VclResId( SV_PRINT_PAGE_TXT ) )
842     , maBackwardBtn( this, VclResId( SV_PRINT_PAGE_BACKWARD ) )
843     , maForwardBtn( this, VclResId( SV_PRINT_PAGE_FORWARD ) )
844     , maTabCtrl( this, VclResId( SV_PRINT_TABCTRL ) )
845     , maNUpPage( &maTabCtrl, VclResId( SV_PRINT_TAB_NUP ) )
846     , maJobPage( &maTabCtrl, VclResId( SV_PRINT_TAB_JOB ) )
847     , maOptionsPage( &maTabCtrl, VclResId( SV_PRINT_TAB_OPT ) )
848     , maButtonLine( this, VclResId( SV_PRINT_BUTTONLINE ) )
849     , maPController( i_rController )
850     , maNoPageStr( String( VclResId( SV_PRINT_NOPAGES ) ) )
851     , mnCurPage( 0 )
852     , mnCachedPages( 0 )
853     , maPrintToFileText( String( VclResId( SV_PRINT_TOFILE_TXT ) ) )
854     , maDefPrtText( String( VclResId( SV_PRINT_DEFPRT_TXT ) ) )
855     , mbShowLayoutPage( sal_True )
856 {
857     FreeResource();
858 
859     // save printbutton text, gets exchanged occasionally with print to file
860     maPrintText = maOKButton.GetText();
861 
862     // setup preview controls
863     maForwardBtn.SetStyle( maForwardBtn.GetStyle() | WB_BEVELBUTTON );
864     maBackwardBtn.SetStyle( maBackwardBtn.GetStyle() | WB_BEVELBUTTON );
865 
866     // insert the job (general) tab page first
867     maTabCtrl.InsertPage( SV_PRINT_TAB_JOB, maJobPage.GetText() );
868     maTabCtrl.SetTabPage( SV_PRINT_TAB_JOB, &maJobPage );
869 
870     // set symbols on forward and backward button
871     maBackwardBtn.SetSymbol( SYMBOL_PREV );
872     maForwardBtn.SetSymbol( SYMBOL_NEXT );
873     maBackwardBtn.ImplSetSmallSymbol( sal_True );
874     maForwardBtn.ImplSetSmallSymbol( sal_True );
875 
876     maPageStr = maNumPagesText.GetText();
877 
878     // init reverse print
879     maJobPage.maReverseOrderBox.Check( maPController->getReversePrint() );
880 
881     // fill printer listbox
882     const std::vector< rtl::OUString >& rQueues( Printer::GetPrinterQueues() );
883     for( std::vector< rtl::OUString >::const_iterator it = rQueues.begin();
884          it != rQueues.end(); ++it )
885     {
886         maJobPage.maPrinters.InsertEntry( *it );
887     }
888     // select current printer
889     if( maJobPage.maPrinters.GetEntryPos( maPController->getPrinter()->GetName() ) != LISTBOX_ENTRY_NOTFOUND )
890     {
891         maJobPage.maPrinters.SelectEntry( maPController->getPrinter()->GetName() );
892     }
893     else
894     {
895         // fall back to last printer
896         SettingsConfigItem* pItem = SettingsConfigItem::get();
897         String aValue( pItem->getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintDialog" ) ),
898                                         rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LastPrinter" ) ) ) );
899         if( maJobPage.maPrinters.GetEntryPos( aValue ) != LISTBOX_ENTRY_NOTFOUND )
900         {
901             maJobPage.maPrinters.SelectEntry( aValue );
902             maPController->setPrinter( boost::shared_ptr<Printer>( new Printer( aValue ) ) );
903         }
904         else
905         {
906             // fall back to default printer
907             maJobPage.maPrinters.SelectEntry( Printer::GetDefaultPrinterName() );
908             maPController->setPrinter( boost::shared_ptr<Printer>( new Printer( Printer::GetDefaultPrinterName() ) ) );
909         }
910     }
911     // not printing to file
912     maPController->resetPrinterOptions( false );
913 
914     // get the first page
915     preparePreview( true, true );
916 
917     // update the text fields for the printer
918     updatePrinterText();
919 
920     // set a select handler
921     maJobPage.maPrinters.SetSelectHdl( LINK( this, PrintDialog, SelectHdl ) );
922 
923     // setup sizes for N-Up
924     Size aNupSize( maPController->getPrinter()->PixelToLogic(
925                          maPController->getPrinter()->GetPaperSizePixel(), MapMode( MAP_100TH_MM ) ) );
926     if( maPController->getPrinter()->GetOrientation() == ORIENTATION_LANDSCAPE )
927     {
928         maNupLandscapeSize = aNupSize;
929         maNupPortraitSize = Size( aNupSize.Height(), aNupSize.Width() );
930     }
931     else
932     {
933         maNupPortraitSize = aNupSize;
934         maNupLandscapeSize = Size( aNupSize.Height(), aNupSize.Width() );
935     }
936     maNUpPage.initFromMultiPageSetup( maPController->getMultipage() );
937 
938 
939     // setup click handler on the various buttons
940     maOKButton.SetClickHdl( LINK( this, PrintDialog, ClickHdl ) );
941     #if OSL_DEBUG_LEVEL > 1
942     maCancelButton.SetClickHdl( LINK( this, PrintDialog, ClickHdl ) );
943     #endif
944     maHelpButton.SetClickHdl( LINK( this, PrintDialog, ClickHdl ) );
945     maForwardBtn.SetClickHdl( LINK( this, PrintDialog, ClickHdl ) );
946     maBackwardBtn.SetClickHdl( LINK( this, PrintDialog, ClickHdl ) );
947     maJobPage.maCollateBox.SetToggleHdl( LINK( this, PrintDialog, ClickHdl ) );
948     maJobPage.maSetupButton.SetClickHdl( LINK( this, PrintDialog, ClickHdl ) );
949     maJobPage.maDetailsBtn.SetToggleHdl( LINK( this, PrintDialog, ClickHdl ) );
950     maNUpPage.maBorderCB.SetClickHdl( LINK( this, PrintDialog, ClickHdl ) );
951     maOptionsPage.maToFileBox.SetToggleHdl( LINK( this, PrintDialog, ClickHdl ) );
952     maJobPage.maReverseOrderBox.SetToggleHdl( LINK( this, PrintDialog, ClickHdl ) );
953     maOptionsPage.maCollateSingleJobsBox.SetToggleHdl( LINK( this, PrintDialog, ClickHdl ) );
954     maNUpPage.maPagesBtn.SetToggleHdl( LINK( this, PrintDialog, ClickHdl ) );
955 
956     // setup modify hdl
957     maPageEdit.SetModifyHdl( LINK( this, PrintDialog, ModifyHdl ) );
958     maJobPage.maCopyCountField.SetModifyHdl( LINK( this, PrintDialog, ModifyHdl ) );
959     maNUpPage.maNupRowsEdt.SetModifyHdl( LINK( this, PrintDialog, ModifyHdl ) );
960     maNUpPage.maNupColEdt.SetModifyHdl( LINK( this, PrintDialog, ModifyHdl ) );
961     maNUpPage.maPageMarginEdt.SetModifyHdl( LINK( this, PrintDialog, ModifyHdl ) );
962     maNUpPage.maSheetMarginEdt.SetModifyHdl( LINK( this, PrintDialog, ModifyHdl ) );
963 
964     // setup select hdl
965     maNUpPage.maNupPagesBox.SetSelectHdl( LINK( this, PrintDialog, SelectHdl ) );
966     maNUpPage.maNupOrientationBox.SetSelectHdl( LINK( this, PrintDialog, SelectHdl ) );
967     maNUpPage.maNupOrderBox.SetSelectHdl( LINK( this, PrintDialog, SelectHdl ) );
968 
969     // setup the layout
970     setupLayout();
971 
972     // setup optional UI options set by application
973     setupOptionalUI();
974 
975     // set change handler for UI options
976     maPController->setOptionChangeHdl( LINK( this, PrintDialog, UIOptionsChanged ) );
977 
978     // set min size pixel to current size
979     Size aOutSize( GetOutputSizePixel() );
980     SetMinOutputSizePixel( aOutSize );
981 
982     // if there is space enough, enlarge the preview so it gets roughly as
983     // high as the tab control
984     if( aOutSize.Width() < 768 )
985     {
986         Size aJobPageSize( getJobPageSize() );
987         Size aTabSize( maTabCtrl.GetSizePixel() );
988         if( aJobPageSize.Width() < 1 )
989             aJobPageSize.Width() = aTabSize.Width();
990         if( aJobPageSize.Height() < 1 )
991             aJobPageSize.Height() = aTabSize.Height();
992         long nOptPreviewWidth = aTabSize.Height() * aJobPageSize.Width() / aJobPageSize.Height();
993         // add space for borders
994         nOptPreviewWidth += 15;
995         if( aOutSize.Width() - aTabSize.Width() < nOptPreviewWidth )
996         {
997             aOutSize.Width() = aTabSize.Width() + nOptPreviewWidth;
998             if( aOutSize.Width() > 768 ) // don't enlarge the dialog too much
999                 aOutSize.Width() = 768;
1000             SetOutputSizePixel( aOutSize );
1001         }
1002     }
1003 
1004     // append further tab pages
1005     if( mbShowLayoutPage )
1006     {
1007         maTabCtrl.InsertPage( SV_PRINT_TAB_NUP, maNUpPage.GetText() );
1008         maTabCtrl.SetTabPage( SV_PRINT_TAB_NUP, &maNUpPage );
1009     }
1010     maTabCtrl.InsertPage( SV_PRINT_TAB_OPT, maOptionsPage.GetText() );
1011     maTabCtrl.SetTabPage( SV_PRINT_TAB_OPT, &maOptionsPage );
1012 
1013     // restore settings from last run
1014     readFromSettings();
1015 
1016     // setup dependencies
1017     checkControlDependencies();
1018 
1019 }
1020 
~PrintDialog()1021 PrintDialog::~PrintDialog()
1022 {
1023     while( ! maControls.empty() )
1024     {
1025         delete maControls.front();
1026         maControls.pop_front();
1027     }
1028 }
1029 
setupLayout()1030 void PrintDialog::setupLayout()
1031 {
1032     boost::shared_ptr<vcl::RowOrColumn> xLayout =
1033         boost::dynamic_pointer_cast<vcl::RowOrColumn>( getLayout() );
1034     xLayout->setOuterBorder( 0 );
1035 
1036 
1037     boost::shared_ptr< vcl::RowOrColumn > xPreviewAndTab( new vcl::RowOrColumn( xLayout.get(), false ) );
1038     size_t nIndex = xLayout->addChild( xPreviewAndTab, 5 );
1039     xLayout->setBorders( nIndex, -1, -1, -1, 0 );
1040 
1041     // setup column for preview and sub controls
1042     boost::shared_ptr< vcl::RowOrColumn > xPreview( new vcl::RowOrColumn( xPreviewAndTab.get() ) );
1043     xPreviewAndTab->addChild( xPreview, 5 );
1044     xPreview->addWindow( &maPreviewWindow, 5 );
1045     // get a row for the preview controls
1046     mxPreviewCtrls.reset( new vcl::RowOrColumn( xPreview.get(), false ) );
1047     nIndex = xPreview->addChild( mxPreviewCtrls );
1048     boost::shared_ptr< vcl::Spacer > xSpacer( new vcl::Spacer( mxPreviewCtrls.get(), 2 ) );
1049     mxPreviewCtrls->addChild( xSpacer );
1050     mxPreviewCtrls->addWindow( &maPageEdit );
1051     mxPreviewCtrls->addWindow( &maNumPagesText );
1052     xSpacer.reset( new vcl::Spacer( mxPreviewCtrls.get(), 2 ) );
1053     mxPreviewCtrls->addChild( xSpacer );
1054     mxPreviewCtrls->addWindow( &maBackwardBtn );
1055     mxPreviewCtrls->addWindow( &maForwardBtn );
1056     xSpacer.reset( new vcl::Spacer( mxPreviewCtrls.get(), 2 ) );
1057     mxPreviewCtrls->addChild( xSpacer );
1058 
1059     // continue with the tab ctrl
1060     xPreviewAndTab->addWindow( &maTabCtrl );
1061 
1062     // add the button line
1063     xLayout->addWindow( &maButtonLine );
1064 
1065     // add the row for the buttons
1066     boost::shared_ptr< vcl::RowOrColumn > xButtons( new vcl::RowOrColumn( xLayout.get(), false ) );
1067     nIndex = xLayout->addChild( xButtons );
1068     xLayout->setBorders( nIndex, -1, 0, -1, -1 );
1069 
1070     Size aMinSize( maCancelButton.GetSizePixel() );
1071     // insert help button
1072     xButtons->setMinimumSize( xButtons->addWindow( &maHelpButton ), aMinSize );
1073     // insert a spacer, cancel and OK buttons are right aligned
1074     xSpacer.reset( new vcl::Spacer( xButtons.get(), 2 ) );
1075     xButtons->addChild( xSpacer );
1076     xButtons->setMinimumSize( xButtons->addWindow( &maOKButton ), aMinSize );
1077     xButtons->setMinimumSize( xButtons->addWindow( &maCancelButton ), aMinSize );
1078 }
1079 
readFromSettings()1080 void PrintDialog::readFromSettings()
1081 {
1082     maJobPage.readFromSettings();
1083     maNUpPage.readFromSettings();
1084     maOptionsPage.readFromSettings();
1085 
1086     // read last selected tab page; if it exists, actiavte it
1087     SettingsConfigItem* pItem = SettingsConfigItem::get();
1088     rtl::OUString aValue = pItem->getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintDialog" ) ),
1089                                             rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LastPage" ) ) );
1090     sal_uInt16 nCount = maTabCtrl.GetPageCount();
1091     for( sal_uInt16 i = 0; i < nCount; i++ )
1092     {
1093         sal_uInt16 nPageId = maTabCtrl.GetPageId( i );
1094         if( aValue.equals( maTabCtrl.GetPageText( nPageId ) ) )
1095         {
1096             maTabCtrl.SelectTabPage( nPageId );
1097             break;
1098         }
1099     }
1100     maOKButton.SetText( maOptionsPage.maToFileBox.IsChecked() ? maPrintToFileText : maPrintText );
1101 
1102     // persistent window state
1103     rtl::OUString aWinState( pItem->getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintDialog" ) ),
1104                                               rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "WindowState" ) ) ) );
1105     if( aWinState.getLength() )
1106         SetWindowState( rtl::OUStringToOString( aWinState, RTL_TEXTENCODING_UTF8 ) );
1107 
1108     if( maOptionsPage.maToFileBox.IsChecked() )
1109     {
1110         maPController->resetPrinterOptions( true );
1111         preparePreview( true, true );
1112     }
1113 }
1114 
storeToSettings()1115 void PrintDialog::storeToSettings()
1116 {
1117     maJobPage.storeToSettings();
1118     maNUpPage.storeToSettings();
1119     maOptionsPage.storeToSettings();
1120 
1121     // store last selected printer
1122     SettingsConfigItem* pItem = SettingsConfigItem::get();
1123     pItem->setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintDialog" ) ),
1124                      rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LastPrinter" ) ),
1125                      maJobPage.maPrinters.GetSelectEntry() );
1126 
1127     pItem->setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintDialog" ) ),
1128                      rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LastPage" ) ),
1129                      maTabCtrl.GetPageText( maTabCtrl.GetCurPageId() ) );
1130     pItem->setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintDialog" ) ),
1131                      rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "WindowState" ) ),
1132                      rtl::OStringToOUString( GetWindowState(), RTL_TEXTENCODING_UTF8 )
1133                      );
1134     pItem->Commit();
1135 }
1136 
isPrintToFile()1137 bool PrintDialog::isPrintToFile()
1138 {
1139     return maOptionsPage.maToFileBox.IsChecked();
1140 }
1141 
getCopyCount()1142 int PrintDialog::getCopyCount()
1143 {
1144     return static_cast<int>(maJobPage.maCopyCountField.GetValue());
1145 }
1146 
isCollate()1147 bool PrintDialog::isCollate()
1148 {
1149     return maJobPage.maCopyCountField.GetValue() > 1 ? maJobPage.maCollateBox.IsChecked() : sal_False;
1150 }
1151 
isSingleJobs()1152 bool PrintDialog::isSingleJobs()
1153 {
1154     return maOptionsPage.maCollateSingleJobsBox.IsChecked();
1155 }
1156 
setHelpId(Window * i_pWindow,const Sequence<rtl::OUString> & i_rHelpIds,sal_Int32 i_nIndex)1157 void setHelpId( Window* i_pWindow, const Sequence< rtl::OUString >& i_rHelpIds, sal_Int32 i_nIndex )
1158 {
1159     if( i_nIndex >= 0 && i_nIndex < i_rHelpIds.getLength() )
1160         i_pWindow->SetHelpId( rtl::OUStringToOString( i_rHelpIds.getConstArray()[i_nIndex], RTL_TEXTENCODING_UTF8 ) );
1161 }
1162 
setHelpText(Window * i_pWindow,const Sequence<rtl::OUString> & i_rHelpTexts,sal_Int32 i_nIndex)1163 static void setHelpText( Window* i_pWindow, const Sequence< rtl::OUString >& i_rHelpTexts, sal_Int32 i_nIndex )
1164 {
1165     // without a help text set and the correct smartID,
1166     // help texts will be retrieved from the online help system
1167     if( i_nIndex >= 0 && i_nIndex < i_rHelpTexts.getLength() )
1168         i_pWindow->SetHelpText( i_rHelpTexts.getConstArray()[i_nIndex] );
1169 }
1170 
updateMaxSize(const Size & i_rCheckSize,Size & o_rMaxSize)1171 void updateMaxSize( const Size& i_rCheckSize, Size& o_rMaxSize )
1172 {
1173     if( i_rCheckSize.Width() > o_rMaxSize.Width() )
1174         o_rMaxSize.Width() = i_rCheckSize.Width();
1175     if( i_rCheckSize.Height() > o_rMaxSize.Height() )
1176         o_rMaxSize.Height() = i_rCheckSize.Height();
1177 }
1178 
setupOptionalUI()1179 void PrintDialog::setupOptionalUI()
1180 {
1181     std::vector< boost::shared_ptr<vcl::RowOrColumn> > aDynamicColumns;
1182     boost::shared_ptr< vcl::RowOrColumn > pCurColumn;
1183 
1184     Window* pCurParent = 0, *pDynamicPageParent = 0;
1185     sal_uInt16 nOptPageId = 9, nCurSubGroup = 0;
1186     bool bOnStaticPage = false;
1187     bool bSubgroupOnStaticPage = false;
1188 
1189     std::multimap< rtl::OUString, boost::shared_ptr<vcl::RowOrColumn> > aPropertyToDependencyRowMap;
1190 
1191     const Sequence< PropertyValue >& rOptions( maPController->getUIOptions() );
1192     for( int i = 0; i < rOptions.getLength(); i++ )
1193     {
1194         Sequence< beans::PropertyValue > aOptProp;
1195         rOptions[i].Value >>= aOptProp;
1196 
1197         // extract ui element
1198         bool bEnabled = true;
1199         rtl::OUString aCtrlType;
1200         rtl::OUString aText;
1201         rtl::OUString aPropertyName;
1202         Sequence< rtl::OUString > aChoices;
1203         Sequence< sal_Bool > aChoicesDisabled;
1204         Sequence< rtl::OUString > aHelpTexts;
1205         Sequence< rtl::OUString > aHelpIds;
1206         sal_Int64 nMinValue = 0, nMaxValue = 0;
1207         sal_Int32 nCurHelpText = 0;
1208         rtl::OUString aGroupingHint;
1209         rtl::OUString aDependsOnName;
1210         sal_Int32 nDependsOnValue = 0;
1211         sal_Bool bUseDependencyRow = sal_False;
1212 
1213         for( int n = 0; n < aOptProp.getLength(); n++ )
1214         {
1215             const beans::PropertyValue& rEntry( aOptProp[ n ] );
1216             if( rEntry.Name.equalsAscii( "Text" ) )
1217             {
1218                 rEntry.Value >>= aText;
1219             }
1220             else if( rEntry.Name.equalsAscii( "ControlType" ) )
1221             {
1222                 rEntry.Value >>= aCtrlType;
1223             }
1224             else if( rEntry.Name.equalsAscii( "Choices" ) )
1225             {
1226                 rEntry.Value >>= aChoices;
1227             }
1228             else if( rEntry.Name.equalsAscii( "ChoicesDisabled" ) )
1229             {
1230                 rEntry.Value >>= aChoicesDisabled;
1231             }
1232             else if( rEntry.Name.equalsAscii( "Property" ) )
1233             {
1234                 PropertyValue aVal;
1235                 rEntry.Value >>= aVal;
1236                 aPropertyName = aVal.Name;
1237             }
1238             else if( rEntry.Name.equalsAscii( "Enabled" ) )
1239             {
1240                 sal_Bool bValue = sal_True;
1241                 rEntry.Value >>= bValue;
1242                 bEnabled = bValue;
1243             }
1244             else if( rEntry.Name.equalsAscii( "GroupingHint" ) )
1245             {
1246                 rEntry.Value >>= aGroupingHint;
1247             }
1248             else if( rEntry.Name.equalsAscii( "DependsOnName" ) )
1249             {
1250                 rEntry.Value >>= aDependsOnName;
1251             }
1252             else if( rEntry.Name.equalsAscii( "DependsOnEntry" ) )
1253             {
1254                 rEntry.Value >>= nDependsOnValue;
1255             }
1256             else if( rEntry.Name.equalsAscii( "AttachToDependency" ) )
1257             {
1258                 rEntry.Value >>= bUseDependencyRow;
1259             }
1260             else if( rEntry.Name.equalsAscii( "MinValue" ) )
1261             {
1262                 rEntry.Value >>= nMinValue;
1263             }
1264             else if( rEntry.Name.equalsAscii( "MaxValue" ) )
1265             {
1266                 rEntry.Value >>= nMaxValue;
1267             }
1268             else if( rEntry.Name.equalsAscii( "HelpText" ) )
1269             {
1270                 if( ! (rEntry.Value >>= aHelpTexts) )
1271                 {
1272                     rtl::OUString aHelpText;
1273                     if( (rEntry.Value >>= aHelpText) )
1274                     {
1275                         aHelpTexts.realloc( 1 );
1276                         *aHelpTexts.getArray() = aHelpText;
1277                     }
1278                 }
1279             }
1280             else if( rEntry.Name.equalsAscii( "HelpId" ) )
1281             {
1282                 if( ! (rEntry.Value >>= aHelpIds ) )
1283                 {
1284                     rtl::OUString aHelpId;
1285                     if( (rEntry.Value >>= aHelpId) )
1286                     {
1287                         aHelpIds.realloc( 1 );
1288                         *aHelpIds.getArray() = aHelpId;
1289                     }
1290                 }
1291             }
1292             else if( rEntry.Name.equalsAscii( "HintNoLayoutPage" ) )
1293             {
1294                 sal_Bool bNoLayoutPage = sal_False;
1295                 rEntry.Value >>= bNoLayoutPage;
1296                 mbShowLayoutPage = ! bNoLayoutPage;
1297             }
1298         }
1299 
1300         // bUseDependencyRow should only be true if a dependency exists
1301         bUseDependencyRow = bUseDependencyRow && (aDependsOnName.getLength() != 0);
1302 
1303         // is it necessary to switch between static and dynamic pages ?
1304         bool bSwitchPage = false;
1305         if( aGroupingHint.getLength() )
1306             bSwitchPage = true;
1307         else if( aCtrlType.equalsAscii( "Subgroup" ) || (bOnStaticPage && ! bSubgroupOnStaticPage )  )
1308             bSwitchPage = true;
1309         if( bSwitchPage )
1310         {
1311             // restore to dynamic
1312             pCurParent = pDynamicPageParent;
1313             if( ! aDynamicColumns.empty() )
1314                 pCurColumn = aDynamicColumns.back();
1315             else
1316                 pCurColumn.reset();
1317             bOnStaticPage = false;
1318             bSubgroupOnStaticPage = false;
1319 
1320             if( aGroupingHint.equalsAscii( "PrintRange" ) )
1321             {
1322                 pCurColumn = maJobPage.mxPrintRange;
1323                 pCurParent = &maJobPage;            // set job page as current parent
1324                 bOnStaticPage = true;
1325             }
1326             else if( aGroupingHint.equalsAscii( "OptionsPage" ) )
1327             {
1328                 pCurColumn = boost::dynamic_pointer_cast<vcl::RowOrColumn>(maOptionsPage.getLayout());
1329                 pCurParent = &maOptionsPage;        // set options page as current parent
1330                 bOnStaticPage = true;
1331             }
1332             else if( aGroupingHint.equalsAscii( "OptionsPageOptGroup" ) )
1333             {
1334                 pCurColumn = maOptionsPage.mxOptGroup;
1335                 pCurParent = &maOptionsPage;        // set options page as current parent
1336                 bOnStaticPage = true;
1337             }
1338             else if( aGroupingHint.equalsAscii( "LayoutPage" ) )
1339             {
1340                 pCurColumn = boost::dynamic_pointer_cast<vcl::RowOrColumn>(maNUpPage.getLayout());
1341                 pCurParent = &maNUpPage;            // set layout page as current parent
1342                 bOnStaticPage = true;
1343             }
1344             else if( aGroupingHint.getLength() )
1345             {
1346                 pCurColumn = boost::dynamic_pointer_cast<vcl::RowOrColumn>(maJobPage.getLayout());
1347                 pCurParent = &maJobPage;            // set job page as current parent
1348                 bOnStaticPage = true;
1349             }
1350         }
1351 
1352         if( aCtrlType.equalsAscii( "Group" ) ||
1353             ( ! pCurParent && ! (bOnStaticPage || aGroupingHint.getLength() ) ) )
1354         {
1355             // add new tab page
1356             TabPage* pNewGroup = new TabPage( &maTabCtrl );
1357             maControls.push_front( pNewGroup );
1358             pDynamicPageParent = pCurParent = pNewGroup;
1359             pNewGroup->SetText( aText );
1360             maTabCtrl.InsertPage( ++nOptPageId, aText );
1361             maTabCtrl.SetTabPage( nOptPageId, pNewGroup );
1362 
1363             // set help id
1364             setHelpId( pNewGroup, aHelpIds, 0 );
1365             // set help text
1366             setHelpText( pNewGroup, aHelpTexts, 0 );
1367 
1368             // reset subgroup counter
1369             nCurSubGroup = 0;
1370 
1371             aDynamicColumns.push_back( boost::dynamic_pointer_cast<vcl::RowOrColumn>(pNewGroup->getLayout()) );
1372             pCurColumn = aDynamicColumns.back();
1373             pCurColumn->setParentWindow( pNewGroup );
1374             bSubgroupOnStaticPage = false;
1375             bOnStaticPage = false;
1376         }
1377         else if( aCtrlType.equalsAscii( "Subgroup" ) && (pCurParent || aGroupingHint.getLength() ) )
1378         {
1379             bSubgroupOnStaticPage = (aGroupingHint.getLength() != 0);
1380             // create group FixedLine
1381             if( ! aGroupingHint.equalsAscii( "PrintRange" ) ||
1382                 ! pCurColumn->countElements() == 0
1383                )
1384             {
1385                 Window* pNewSub = NULL;
1386                 if( aGroupingHint.equalsAscii( "PrintRange" ) )
1387                     pNewSub = new FixedText( pCurParent, WB_VCENTER );
1388                 else
1389                     pNewSub = new FixedLine( pCurParent );
1390                 maControls.push_front( pNewSub );
1391                 pNewSub->SetText( aText );
1392                 pNewSub->Show();
1393 
1394                 // set help id
1395                 setHelpId( pNewSub, aHelpIds, 0 );
1396                 // set help text
1397                 setHelpText( pNewSub, aHelpTexts, 0 );
1398                 // add group to current column
1399                 pCurColumn->addWindow( pNewSub );
1400             }
1401 
1402             // add an indent to the current column
1403             vcl::Indenter* pIndent = new vcl::Indenter( pCurColumn.get(), -1 );
1404             pCurColumn->addChild( pIndent );
1405             // and create a column inside the indent
1406             pCurColumn.reset( new vcl::RowOrColumn( pIndent ) );
1407             pIndent->setChild( pCurColumn );
1408         }
1409         // EVIL
1410         else if( aCtrlType.equalsAscii( "Bool" ) &&
1411                  aGroupingHint.equalsAscii( "LayoutPage" ) &&
1412                  aPropertyName.equalsAscii( "PrintProspect" )
1413                  )
1414         {
1415             maNUpPage.maBrochureBtn.SetText( aText );
1416             maNUpPage.maBrochureBtn.Show();
1417             setHelpText( &maNUpPage.maBrochureBtn, aHelpTexts, 0 );
1418 
1419             sal_Bool bVal = sal_False;
1420             PropertyValue* pVal = maPController->getValue( aPropertyName );
1421             if( pVal )
1422                 pVal->Value >>= bVal;
1423             maNUpPage.maBrochureBtn.Check( bVal );
1424             maNUpPage.maBrochureBtn.Enable( maPController->isUIOptionEnabled( aPropertyName ) && pVal != NULL );
1425             maNUpPage.maBrochureBtn.SetToggleHdl( LINK( this, PrintDialog, ClickHdl ) );
1426 
1427             maPropertyToWindowMap[ aPropertyName ].push_back( &maNUpPage.maBrochureBtn );
1428             maControlToPropertyMap[&maNUpPage.maBrochureBtn] = aPropertyName;
1429 
1430             aPropertyToDependencyRowMap.insert( std::pair< rtl::OUString, boost::shared_ptr<vcl::RowOrColumn> >( aPropertyName, maNUpPage.mxBrochureDep ) );
1431         }
1432         else
1433         {
1434             boost::shared_ptr<vcl::RowOrColumn> pSaveCurColumn( pCurColumn );
1435 
1436             if( bUseDependencyRow )
1437             {
1438                 // find the correct dependency row (if any)
1439                 std::pair< std::multimap< rtl::OUString, boost::shared_ptr<vcl::RowOrColumn> >::iterator,
1440                            std::multimap< rtl::OUString, boost::shared_ptr<vcl::RowOrColumn> >::iterator > aDepRange;
1441                 aDepRange = aPropertyToDependencyRowMap.equal_range( aDependsOnName );
1442                 if( aDepRange.first != aDepRange.second )
1443                 {
1444                     while( nDependsOnValue && aDepRange.first != aDepRange.second )
1445                     {
1446                         nDependsOnValue--;
1447                         ++aDepRange.first;
1448                     }
1449                     if( aDepRange.first != aPropertyToDependencyRowMap.end() )
1450                     {
1451                         pCurColumn = aDepRange.first->second;
1452                         maReverseDependencySet.insert( aPropertyName );
1453                     }
1454                 }
1455             }
1456             if( aCtrlType.equalsAscii( "Bool" ) && pCurParent )
1457             {
1458                 // add a check box
1459                 CheckBox* pNewBox = new CheckBox( pCurParent );
1460                 maControls.push_front( pNewBox );
1461                 pNewBox->SetText( aText );
1462                 pNewBox->Show();
1463 
1464                 sal_Bool bVal = sal_False;
1465                 PropertyValue* pVal = maPController->getValue( aPropertyName );
1466                 if( pVal )
1467                     pVal->Value >>= bVal;
1468                 pNewBox->Check( bVal );
1469                 pNewBox->SetToggleHdl( LINK( this, PrintDialog, UIOption_CheckHdl ) );
1470 
1471                 maPropertyToWindowMap[ aPropertyName ].push_back( pNewBox );
1472                 maControlToPropertyMap[pNewBox] = aPropertyName;
1473 
1474                 // set help id
1475                 setHelpId( pNewBox, aHelpIds, 0 );
1476                 // set help text
1477                 setHelpText( pNewBox, aHelpTexts, 0 );
1478 
1479                 boost::shared_ptr<vcl::RowOrColumn> pDependencyRow( new vcl::RowOrColumn( pCurColumn.get(), false ) );
1480                 pCurColumn->addChild( pDependencyRow );
1481                 aPropertyToDependencyRowMap.insert( std::pair< rtl::OUString, boost::shared_ptr<vcl::RowOrColumn> >( aPropertyName, pDependencyRow ) );
1482 
1483                 // add checkbox to current column
1484                 pDependencyRow->addWindow( pNewBox );
1485             }
1486             else if( aCtrlType.equalsAscii( "Radio" ) && pCurParent )
1487             {
1488                 boost::shared_ptr<vcl::RowOrColumn> pRadioColumn( pCurColumn );
1489                 if( aText.getLength() )
1490                 {
1491                     // add a FixedText:
1492                     FixedText* pHeading = new FixedText( pCurParent );
1493                     maControls.push_front( pHeading );
1494                     pHeading->SetText( aText );
1495                     pHeading->Show();
1496 
1497                     // set help id
1498                     setHelpId( pHeading, aHelpIds, nCurHelpText );
1499                     // set help text
1500                     setHelpText( pHeading, aHelpTexts, nCurHelpText );
1501                     nCurHelpText++;
1502                     // add fixed text to current column
1503                     pCurColumn->addWindow( pHeading );
1504                     // add an indent to the current column
1505                     vcl::Indenter* pIndent = new vcl::Indenter( pCurColumn.get(), 15 );
1506                     pCurColumn->addChild( pIndent );
1507                     // and create a column inside the indent
1508                     pRadioColumn.reset( new vcl::RowOrColumn( pIndent ) );
1509                     pIndent->setChild( pRadioColumn );
1510                 }
1511                 // iterate options
1512                 sal_Int32 nSelectVal = 0;
1513                 PropertyValue* pVal = maPController->getValue( aPropertyName );
1514                 if( pVal && pVal->Value.hasValue() )
1515                     pVal->Value >>= nSelectVal;
1516                 for( sal_Int32 m = 0; m < aChoices.getLength(); m++ )
1517                 {
1518                     boost::shared_ptr<vcl::LabeledElement> pLabel( new vcl::LabeledElement( pRadioColumn.get(), 1 ) );
1519                     pRadioColumn->addChild( pLabel );
1520                     boost::shared_ptr<vcl::RowOrColumn> pDependencyRow( new vcl::RowOrColumn( pLabel.get(), false ) );
1521                     pLabel->setElement( pDependencyRow );
1522                     aPropertyToDependencyRowMap.insert( std::pair< rtl::OUString, boost::shared_ptr<vcl::RowOrColumn> >( aPropertyName, pDependencyRow ) );
1523 
1524                     RadioButton* pBtn = new RadioButton( pCurParent, m == 0 ? WB_GROUP : 0 );
1525                     maControls.push_front( pBtn );
1526                     pBtn->SetText( aChoices[m] );
1527                     pBtn->Check( m == nSelectVal );
1528                     pBtn->SetToggleHdl( LINK( this, PrintDialog, UIOption_RadioHdl ) );
1529                     if( aChoicesDisabled.getLength() > m && aChoicesDisabled[m] == sal_True )
1530                         pBtn->Enable( sal_False );
1531                     pBtn->Show();
1532                     maPropertyToWindowMap[ aPropertyName ].push_back( pBtn );
1533                     maControlToPropertyMap[pBtn] = aPropertyName;
1534                     maControlToNumValMap[pBtn] = m;
1535 
1536                     // set help id
1537                     setHelpId( pBtn, aHelpIds, nCurHelpText );
1538                     // set help text
1539                     setHelpText( pBtn, aHelpTexts, nCurHelpText );
1540                     nCurHelpText++;
1541                     // add the radio button to the column
1542                     pLabel->setLabel( pBtn );
1543                 }
1544             }
1545             else if( ( aCtrlType.equalsAscii( "List" )   ||
1546                        aCtrlType.equalsAscii( "Range" )  ||
1547                        aCtrlType.equalsAscii( "Edit" )
1548                      ) && pCurParent )
1549             {
1550                 // create a row in the current column
1551                 boost::shared_ptr<vcl::RowOrColumn> pFieldColumn( new vcl::RowOrColumn( pCurColumn.get(), false ) );
1552                 pCurColumn->addChild( pFieldColumn );
1553                 aPropertyToDependencyRowMap.insert( std::pair< rtl::OUString, boost::shared_ptr<vcl::RowOrColumn> >( aPropertyName, pFieldColumn ) );
1554 
1555                 vcl::LabeledElement* pLabel = NULL;
1556                 if( aText.getLength() )
1557                 {
1558                     // add a FixedText:
1559                     FixedText* pHeading = new FixedText( pCurParent, WB_VCENTER );
1560                     maControls.push_front( pHeading );
1561                     pHeading->SetText( aText );
1562                     pHeading->Show();
1563 
1564                     // add to row
1565                     pLabel = new vcl::LabeledElement( pFieldColumn.get(), 2 );
1566                     pFieldColumn->addChild( pLabel );
1567                     pLabel->setLabel( pHeading );
1568                 }
1569 
1570                 if( aCtrlType.equalsAscii( "List" ) )
1571                 {
1572                     ListBox* pList = new ListBox( pCurParent, WB_DROPDOWN | WB_BORDER );
1573                     maControls.push_front( pList );
1574 
1575                     // iterate options
1576                     for( sal_Int32 m = 0; m < aChoices.getLength(); m++ )
1577                     {
1578                         pList->InsertEntry( aChoices[m] );
1579                     }
1580                     sal_Int32 nSelectVal = 0;
1581                     PropertyValue* pVal = maPController->getValue( aPropertyName );
1582                     if( pVal && pVal->Value.hasValue() )
1583                         pVal->Value >>= nSelectVal;
1584                     pList->SelectEntryPos( static_cast<sal_uInt16>(nSelectVal) );
1585                     pList->SetSelectHdl( LINK( this, PrintDialog, UIOption_SelectHdl ) );
1586                     pList->SetDropDownLineCount( static_cast<sal_uInt16>(aChoices.getLength()) );
1587                     pList->Show();
1588 
1589                     // set help id
1590                     setHelpId( pList, aHelpIds, 0 );
1591                     // set help text
1592                     setHelpText( pList, aHelpTexts, 0 );
1593 
1594                     maPropertyToWindowMap[ aPropertyName ].push_back( pList );
1595                     maControlToPropertyMap[pList] = aPropertyName;
1596 
1597                     // finish the pair
1598                     if( pLabel )
1599                         pLabel->setElement( pList );
1600                     else
1601                         pFieldColumn->addWindow( pList );
1602                 }
1603                 else if( aCtrlType.equalsAscii( "Range" ) )
1604                 {
1605                     NumericField* pField = new NumericField( pCurParent, WB_BORDER | WB_SPIN );
1606                     maControls.push_front( pField );
1607 
1608                     // set min/max and current value
1609                     if( nMinValue != nMaxValue )
1610                     {
1611                         pField->SetMin( nMinValue );
1612                         pField->SetMax( nMaxValue );
1613                     }
1614                     sal_Int64 nCurVal = 0;
1615                     PropertyValue* pVal = maPController->getValue( aPropertyName );
1616                     if( pVal && pVal->Value.hasValue() )
1617                         pVal->Value >>= nCurVal;
1618                     pField->SetValue( nCurVal );
1619                     pField->SetModifyHdl( LINK( this, PrintDialog, UIOption_ModifyHdl ) );
1620                     pField->Show();
1621 
1622                     // set help id
1623                     setHelpId( pField, aHelpIds, 0 );
1624                     // set help text
1625                     setHelpText( pField, aHelpTexts, 0 );
1626 
1627                     maPropertyToWindowMap[ aPropertyName ].push_back( pField );
1628                     maControlToPropertyMap[pField] = aPropertyName;
1629 
1630                     // add to row
1631                     if( pLabel )
1632                         pLabel->setElement( pField );
1633                     else
1634                         pFieldColumn->addWindow( pField );
1635                 }
1636                 else if( aCtrlType.equalsAscii( "Edit" ) )
1637                 {
1638                     Edit* pField = new Edit( pCurParent, WB_BORDER );
1639                     maControls.push_front( pField );
1640 
1641                     rtl::OUString aCurVal;
1642                     PropertyValue* pVal = maPController->getValue( aPropertyName );
1643                     if( pVal && pVal->Value.hasValue() )
1644                         pVal->Value >>= aCurVal;
1645                     pField->SetText( aCurVal );
1646                     pField->SetModifyHdl( LINK( this, PrintDialog, UIOption_ModifyHdl ) );
1647                     pField->Show();
1648 
1649                     // set help id
1650                     setHelpId( pField, aHelpIds, 0 );
1651                     // set help text
1652                     setHelpText( pField, aHelpTexts, 0 );
1653 
1654                     maPropertyToWindowMap[ aPropertyName ].push_back( pField );
1655                     maControlToPropertyMap[pField] = aPropertyName;
1656 
1657                     // add to row
1658                     if( pLabel )
1659                         pLabel->setElement( pField );
1660                     else
1661                         pFieldColumn->addWindow( pField, 2 );
1662                 }
1663             }
1664             else
1665             {
1666                 DBG_ERROR( "Unsupported UI option" );
1667             }
1668 
1669             pCurColumn = pSaveCurColumn;
1670         }
1671     }
1672 
1673     // #i106506# if no brochure button, then the singular Pages radio button
1674     // makes no sense, so replace it by a FixedText label
1675     if( ! maNUpPage.maBrochureBtn.IsVisible() )
1676     {
1677         if( maNUpPage.mxPagesBtnLabel.get() )
1678         {
1679             maNUpPage.maPagesBoxTitleTxt.SetText( maNUpPage.maPagesBtn.GetText() );
1680             maNUpPage.maPagesBoxTitleTxt.Show( sal_True );
1681             maNUpPage.mxPagesBtnLabel->setLabel( &maNUpPage.maPagesBoxTitleTxt );
1682             maNUpPage.maPagesBtn.Show( sal_False );
1683         }
1684     }
1685 
1686     // update enable states
1687     checkOptionalControlDependencies();
1688 
1689     // print range empty (currently math only) -> hide print range and spacer line
1690     if( maJobPage.mxPrintRange->countElements() == 0 )
1691     {
1692         maJobPage.mxPrintRange->show( false, false );
1693         maJobPage.maCopySpacer.Show( sal_False );
1694         maJobPage.maReverseOrderBox.Show( sal_False );
1695     }
1696     else
1697     {
1698         // add an indent to the current column
1699         vcl::Indenter* pIndent = new vcl::Indenter( maJobPage.mxPrintRange.get(), -1 );
1700         maJobPage.mxPrintRange->addChild( pIndent );
1701         // and create a column inside the indent
1702         pIndent->setWindow( &maJobPage.maReverseOrderBox );
1703         maJobPage.maReverseOrderBox.Show( sal_True );
1704     }
1705 
1706 #ifdef WNT
1707     // FIXME: the GetNativeControlRegion call on Windows has some issues
1708     // (which skew the results of GetOptimalSize())
1709     // however fixing this thoroughly needs to take interaction with paint into
1710     // account, making the right fix less simple. Fix this the right way
1711     // at some point. For now simply add some space at the lowest element
1712     size_t nIndex = maJobPage.getLayout()->countElements();
1713     if( nIndex > 0 ) // sanity check
1714         maJobPage.getLayout()->setBorders( nIndex-1, 0, 0, 0, -1 );
1715 #endif
1716 
1717     // create auto mnemomnics now so they can be calculated in layout
1718     ImplWindowAutoMnemonic( &maJobPage );
1719     ImplWindowAutoMnemonic( &maNUpPage );
1720     ImplWindowAutoMnemonic( &maOptionsPage );
1721     ImplWindowAutoMnemonic( this );
1722 
1723     // calculate job page
1724     Size aMaxSize = maJobPage.getLayout()->getOptimalSize( WINDOWSIZE_PREFERRED );
1725     // and layout page
1726     updateMaxSize( maNUpPage.getLayout()->getOptimalSize( WINDOWSIZE_PREFERRED ), aMaxSize );
1727     // and options page
1728     updateMaxSize( maOptionsPage.getLayout()->getOptimalSize( WINDOWSIZE_PREFERRED ), aMaxSize );
1729 
1730     for( std::vector< boost::shared_ptr<vcl::RowOrColumn> >::iterator it = aDynamicColumns.begin();
1731          it != aDynamicColumns.end(); ++it )
1732     {
1733         Size aPageSize( (*it)->getOptimalSize( WINDOWSIZE_PREFERRED ) );
1734         updateMaxSize( aPageSize, aMaxSize );
1735     }
1736 
1737     // resize dialog if necessary
1738     Size aTabSize = maTabCtrl.GetTabPageSizePixel();
1739     maTabCtrl.SetMinimumSizePixel( maTabCtrl.GetSizePixel() );
1740     if( aMaxSize.Height() > aTabSize.Height() || aMaxSize.Width() > aTabSize.Width() )
1741     {
1742         Size aCurSize( GetOutputSizePixel() );
1743         if( aMaxSize.Height() > aTabSize.Height() )
1744 		{
1745             aCurSize.Height() += aMaxSize.Height() - aTabSize.Height();
1746 			aTabSize.Height() = aMaxSize.Height();
1747 		}
1748         if( aMaxSize.Width() > aTabSize.Width() )
1749         {
1750             aCurSize.Width() += aMaxSize.Width() - aTabSize.Width();
1751             // and the tab ctrl needs more space, too
1752             aTabSize.Width() = aMaxSize.Width();
1753         }
1754         maTabCtrl.SetTabPageSizePixel( aTabSize );
1755         maTabCtrl.SetMinimumSizePixel( maTabCtrl.GetSizePixel() );
1756     }
1757 
1758     Size aSz = getLayout()->getOptimalSize( WINDOWSIZE_PREFERRED );
1759     SetOutputSizePixel( aSz );
1760 }
1761 
DataChanged(const DataChangedEvent & i_rDCEvt)1762 void PrintDialog::DataChanged( const DataChangedEvent& i_rDCEvt )
1763 {
1764     // react on settings changed
1765     if( i_rDCEvt.GetType() == DATACHANGED_SETTINGS )
1766         checkControlDependencies();
1767     ModalDialog::DataChanged( i_rDCEvt );
1768 }
1769 
checkControlDependencies()1770 void PrintDialog::checkControlDependencies()
1771 {
1772     if( maJobPage.maCopyCountField.GetValue() > 1 )
1773         maJobPage.maCollateBox.Enable( maJobPage.mnCollateUIMode == 0 );
1774     else
1775         maJobPage.maCollateBox.Enable( sal_False );
1776 
1777     Image aImg( maJobPage.maCollateBox.IsChecked() ? maJobPage.maCollateImg : maJobPage.maNoCollateImg );
1778     Image aHCImg( maJobPage.maCollateBox.IsChecked() ? maJobPage.maCollateHCImg : maJobPage.maNoCollateHCImg );
1779     bool bHC = GetSettings().GetStyleSettings().GetHighContrastMode();
1780 
1781     Size aImgSize( aImg.GetSizePixel() );
1782     Size aHCImgSize( aHCImg.GetSizePixel() );
1783 
1784     if( aHCImgSize.Width() > aImgSize.Width() )
1785         aImgSize.Width() = aHCImgSize.Width();
1786     if( aHCImgSize.Height() > aImgSize.Height() )
1787         aImgSize.Height() = aHCImgSize.Height();
1788 
1789     // adjust size of image
1790     maJobPage.maCollateImage.SetSizePixel( aImgSize );
1791     maJobPage.maCollateImage.SetImage( bHC ? aHCImg : aImg );
1792     maJobPage.maCollateImage.SetModeImage( aHCImg, BMP_COLOR_HIGHCONTRAST );
1793     maJobPage.getLayout()->resize();
1794 
1795     // enable setup button only for printers that can be setup
1796     bool bHaveSetup = maPController->getPrinter()->HasSupport( SUPPORT_SETUPDIALOG );
1797     maJobPage.maSetupButton.Enable( bHaveSetup );
1798     if( bHaveSetup )
1799     {
1800         if( ! maJobPage.maSetupButton.IsVisible() )
1801         {
1802             Point aPrinterPos( maJobPage.maPrinters.GetPosPixel() );
1803             Point aSetupPos( maJobPage.maSetupButton.GetPosPixel() );
1804             Size aPrinterSize( maJobPage.maPrinters.GetSizePixel() );
1805             aPrinterSize.Width() = aSetupPos.X() - aPrinterPos.X() - LogicToPixel( Size( 5, 5 ), MapMode( MAP_APPFONT ) ).Width();
1806             maJobPage.maPrinters.SetSizePixel( aPrinterSize );
1807             maJobPage.maSetupButton.Show();
1808             getLayout()->resize();
1809         }
1810     }
1811     else
1812     {
1813         if( maJobPage.maSetupButton.IsVisible() )
1814         {
1815             Point aPrinterPos( maJobPage.maPrinters.GetPosPixel() );
1816             Point aSetupPos( maJobPage.maSetupButton.GetPosPixel() );
1817             Size aPrinterSize( maJobPage.maPrinters.GetSizePixel() );
1818             Size aSetupSize( maJobPage.maSetupButton.GetSizePixel() );
1819             aPrinterSize.Width() = aSetupPos.X() + aSetupSize.Width() - aPrinterPos.X();
1820             maJobPage.maPrinters.SetSizePixel( aPrinterSize );
1821             maJobPage.maSetupButton.Hide();
1822             getLayout()->resize();
1823         }
1824     }
1825 }
1826 
checkOptionalControlDependencies()1827 void PrintDialog::checkOptionalControlDependencies()
1828 {
1829     for( std::map< Window*, rtl::OUString >::iterator it = maControlToPropertyMap.begin();
1830          it != maControlToPropertyMap.end(); ++it )
1831     {
1832         bool bShouldbeEnabled = maPController->isUIOptionEnabled( it->second );
1833         if( ! bShouldbeEnabled )
1834         {
1835             // enable controls that are directly attached to a dependency anyway
1836             // if the normally disabled controls get modified, change the dependency
1837             // so the control would be enabled
1838             // example: in print range "Print All" is selected, "Page Range" is then of course
1839             // not selected and the Edit for the Page Range would be disabled
1840             // as a convenience we should enable the Edit anyway and automatically select
1841             // "Page Range" instead of "Print All" if the Edit gets modified
1842             if( maReverseDependencySet.find( it->second ) != maReverseDependencySet.end() )
1843             {
1844                 rtl::OUString aDep( maPController->getDependency( it->second ) );
1845                 // if the dependency is at least enabled, then enable this control anyway
1846                 if( aDep.getLength() && maPController->isUIOptionEnabled( aDep ) )
1847                     bShouldbeEnabled = true;
1848             }
1849         }
1850 
1851         if( bShouldbeEnabled && dynamic_cast<RadioButton*>(it->first) )
1852         {
1853             std::map< Window*, sal_Int32 >::const_iterator r_it = maControlToNumValMap.find( it->first );
1854             if( r_it != maControlToNumValMap.end() )
1855             {
1856                 bShouldbeEnabled = maPController->isUIChoiceEnabled( it->second, r_it->second );
1857             }
1858         }
1859 
1860 
1861         bool bIsEnabled = it->first->IsEnabled();
1862         // Enable does not do a change check first, so can be less cheap than expected
1863         if( bShouldbeEnabled != bIsEnabled )
1864             it->first->Enable( bShouldbeEnabled );
1865     }
1866 }
1867 
searchAndReplace(const rtl::OUString & i_rOrig,const char * i_pRepl,sal_Int32 i_nReplLen,const rtl::OUString & i_rRepl)1868 static rtl::OUString searchAndReplace( const rtl::OUString& i_rOrig, const char* i_pRepl, sal_Int32 i_nReplLen, const rtl::OUString& i_rRepl )
1869 {
1870     sal_Int32 nPos = i_rOrig.indexOfAsciiL( i_pRepl, i_nReplLen );
1871     if( nPos != -1 )
1872     {
1873         rtl::OUStringBuffer aBuf( i_rOrig.getLength() );
1874         aBuf.append( i_rOrig.getStr(), nPos );
1875         aBuf.append( i_rRepl );
1876         if( nPos + i_nReplLen < i_rOrig.getLength() )
1877             aBuf.append( i_rOrig.getStr() + nPos + i_nReplLen );
1878         return aBuf.makeStringAndClear();
1879     }
1880     return i_rOrig;
1881 }
1882 
updatePrinterText()1883 void PrintDialog::updatePrinterText()
1884 {
1885     String aDefPrt( Printer::GetDefaultPrinterName() );
1886     const QueueInfo* pInfo = Printer::GetQueueInfo( maJobPage.maPrinters.GetSelectEntry(), true );
1887     if( pInfo )
1888     {
1889         maJobPage.maLocationTxt.SetText( pInfo->GetLocation() );
1890         maJobPage.maCommentTxt.SetText( pInfo->GetComment() );
1891         // FIXME: status text
1892         rtl::OUString aStatus;
1893         if( aDefPrt == pInfo->GetPrinterName() )
1894             aStatus = maDefPrtText;
1895         maJobPage.maStatusTxt.SetText( aStatus );
1896     }
1897     else
1898     {
1899         maJobPage.maLocationTxt.SetText( String() );
1900         maJobPage.maCommentTxt.SetText( String() );
1901         maJobPage.maStatusTxt.SetText( String() );
1902     }
1903 }
1904 
setPreviewText(sal_Int32)1905 void PrintDialog::setPreviewText( sal_Int32 )
1906 {
1907     rtl::OUString aNewText( searchAndReplace( maPageStr, "%n", 2, rtl::OUString::valueOf( mnCachedPages )  ) );
1908     maNumPagesText.SetText( aNewText );
1909 
1910     // if layout is already established the refresh layout of
1911     // preview controls since text length may have changes
1912     if( mxPreviewCtrls.get() )
1913         mxPreviewCtrls->setManagedArea( mxPreviewCtrls->getManagedArea() );
1914 }
1915 
preparePreview(bool i_bNewPage,bool i_bMayUseCache)1916 void PrintDialog::preparePreview( bool i_bNewPage, bool i_bMayUseCache )
1917 {
1918     // page range may have changed depending on options
1919     sal_Int32 nPages = maPController->getFilteredPageCount();
1920     mnCachedPages = nPages;
1921 
1922     if( mnCurPage >= nPages )
1923         mnCurPage = nPages-1;
1924     if( mnCurPage < 0 )
1925         mnCurPage = 0;
1926 
1927     setPreviewText( mnCurPage );
1928 
1929     maPageEdit.SetMin( 1 );
1930     maPageEdit.SetMax( nPages );
1931 
1932     if( i_bNewPage )
1933     {
1934         const MapMode aMapMode( MAP_100TH_MM );
1935         GDIMetaFile aMtf;
1936         boost::shared_ptr<Printer> aPrt( maPController->getPrinter() );
1937         if( nPages > 0 )
1938         {
1939             PrinterController::PageSize aPageSize =
1940                 maPController->getFilteredPageFile( mnCurPage, aMtf, i_bMayUseCache );
1941             if( ! aPageSize.bFullPaper )
1942             {
1943                 Point aOff( aPrt->PixelToLogic( aPrt->GetPageOffsetPixel(), aMapMode ) );
1944                 aMtf.Move( aOff.X(), aOff.Y() );
1945             }
1946         }
1947 
1948         Size aCurPageSize = aPrt->PixelToLogic( aPrt->GetPaperSizePixel(), MapMode( MAP_100TH_MM ) );
1949         maPreviewWindow.setPreview( aMtf, aCurPageSize,
1950                                     aPrt->GetPaperName( false ),
1951                                     nPages > 0 ? rtl::OUString() : maNoPageStr,
1952                                     aPrt->ImplGetDPIX(), aPrt->ImplGetDPIY(),
1953                                     aPrt->GetPrinterOptions().IsConvertToGreyscales()
1954                                    );
1955 
1956         maForwardBtn.Enable( mnCurPage < nPages-1 );
1957         maBackwardBtn.Enable( mnCurPage != 0 );
1958         maPageEdit.Enable( nPages > 1 );
1959     }
1960 }
1961 
getJobPageSize()1962 Size PrintDialog::getJobPageSize()
1963 {
1964     if( maFirstPageSize.Width() == 0 && maFirstPageSize.Height() == 0)
1965     {
1966         maFirstPageSize = maNupPortraitSize;
1967         GDIMetaFile aMtf;
1968         if( maPController->getPageCountProtected() > 0 )
1969         {
1970             PrinterController::PageSize aPageSize = maPController->getPageFile( 0, aMtf, true );
1971             maFirstPageSize = aPageSize.aSize;
1972         }
1973     }
1974     return maFirstPageSize;
1975 }
1976 
updateNupFromPages()1977 void PrintDialog::updateNupFromPages()
1978 {
1979     long nPages = long(maNUpPage.maNupPagesBox.GetEntryData(maNUpPage.maNupPagesBox.GetSelectEntryPos()));
1980     int nRows   = int(maNUpPage.maNupRowsEdt.GetValue());
1981     int nCols   = int(maNUpPage.maNupColEdt.GetValue());
1982     long nPageMargin  = long(maNUpPage.maPageMarginEdt.Denormalize(maNUpPage.maPageMarginEdt.GetValue( FUNIT_100TH_MM )));
1983     long nSheetMargin = long(maNUpPage.maSheetMarginEdt.Denormalize(maNUpPage.maSheetMarginEdt.GetValue( FUNIT_100TH_MM )));
1984     bool bCustom = false;
1985 
1986     if( nPages == 1 )
1987     {
1988         nRows = nCols = 1;
1989         nSheetMargin = 0;
1990         nPageMargin = 0;
1991     }
1992     else if( nPages == 2 || nPages == 4 || nPages == 6 || nPages == 9 || nPages == 16 )
1993     {
1994         Size aJobPageSize( getJobPageSize() );
1995         bool bPortrait = aJobPageSize.Width() < aJobPageSize.Height();
1996         if( nPages == 2 )
1997         {
1998             if( bPortrait )
1999                 nRows = 1, nCols = 2;
2000             else
2001                 nRows = 2, nCols = 1;
2002         }
2003         else if( nPages == 4 )
2004             nRows = nCols = 2;
2005         else if( nPages == 6 )
2006         {
2007             if( bPortrait )
2008                 nRows = 2, nCols = 3;
2009             else
2010                 nRows = 3, nCols = 2;
2011         }
2012         else if( nPages == 9 )
2013             nRows = nCols = 3;
2014         else if( nPages == 16 )
2015             nRows = nCols = 4;
2016         nPageMargin = 0;
2017         nSheetMargin = 0;
2018     }
2019     else
2020         bCustom = true;
2021 
2022     if( nPages > 1 )
2023     {
2024         // set upper limits for margins based on job page size and rows/columns
2025         Size aSize( getJobPageSize() );
2026 
2027         // maximum sheet distance: 1/2 sheet
2028         long nHorzMax = aSize.Width()/2;
2029         long nVertMax = aSize.Height()/2;
2030         if( nSheetMargin > nHorzMax )
2031             nSheetMargin = nHorzMax;
2032         if( nSheetMargin > nVertMax )
2033             nSheetMargin = nVertMax;
2034 
2035         maNUpPage.maSheetMarginEdt.SetMax(
2036                   maNUpPage.maSheetMarginEdt.Normalize(
2037                            nHorzMax > nVertMax ? nVertMax : nHorzMax ), FUNIT_100TH_MM );
2038 
2039         // maximum page distance
2040         nHorzMax = (aSize.Width() - 2*nSheetMargin);
2041         if( nCols > 1 )
2042             nHorzMax /= (nCols-1);
2043         nVertMax = (aSize.Height() - 2*nSheetMargin);
2044         if( nRows > 1 )
2045             nHorzMax /= (nRows-1);
2046 
2047         if( nPageMargin > nHorzMax )
2048             nPageMargin = nHorzMax;
2049         if( nPageMargin > nVertMax )
2050             nPageMargin = nVertMax;
2051 
2052         maNUpPage.maPageMarginEdt.SetMax(
2053                  maNUpPage.maSheetMarginEdt.Normalize(
2054                            nHorzMax > nVertMax ? nVertMax : nHorzMax ), FUNIT_100TH_MM );
2055     }
2056 
2057     maNUpPage.maNupRowsEdt.SetValue( nRows );
2058     maNUpPage.maNupColEdt.SetValue( nCols );
2059     maNUpPage.maPageMarginEdt.SetValue( maNUpPage.maPageMarginEdt.Normalize( nPageMargin ), FUNIT_100TH_MM );
2060     maNUpPage.maSheetMarginEdt.SetValue( maNUpPage.maSheetMarginEdt.Normalize( nSheetMargin ), FUNIT_100TH_MM );
2061 
2062     maNUpPage.showAdvancedControls( bCustom );
2063     if( bCustom )
2064     {
2065         // see if we have to enlarge the dialog to make the tab page fit
2066         Size aCurSize( maNUpPage.getLayout()->getOptimalSize( WINDOWSIZE_PREFERRED ) );
2067         Size aTabSize( maTabCtrl.GetTabPageSizePixel() );
2068         if( aTabSize.Height() < aCurSize.Height() )
2069         {
2070             Size aDlgSize( GetSizePixel() );
2071             aDlgSize.Height() += aCurSize.Height() - aTabSize.Height();
2072             SetSizePixel( aDlgSize );
2073         }
2074     }
2075 
2076     updateNup();
2077 }
2078 
updateNup()2079 void PrintDialog::updateNup()
2080 {
2081     int nRows         = int(maNUpPage.maNupRowsEdt.GetValue());
2082     int nCols         = int(maNUpPage.maNupColEdt.GetValue());
2083     long nPageMargin  = long(maNUpPage.maPageMarginEdt.Denormalize(maNUpPage.maPageMarginEdt.GetValue( FUNIT_100TH_MM )));
2084     long nSheetMargin = long(maNUpPage.maSheetMarginEdt.Denormalize(maNUpPage.maSheetMarginEdt.GetValue( FUNIT_100TH_MM )));
2085 
2086     PrinterController::MultiPageSetup aMPS;
2087     aMPS.nRows         = nRows;
2088     aMPS.nColumns      = nCols;
2089     aMPS.nRepeat       = 1;
2090     aMPS.nLeftMargin   =
2091     aMPS.nTopMargin    =
2092     aMPS.nRightMargin  =
2093     aMPS.nBottomMargin = nSheetMargin;
2094 
2095     aMPS.nHorizontalSpacing =
2096     aMPS.nVerticalSpacing   = nPageMargin;
2097 
2098     aMPS.bDrawBorder        = maNUpPage.maBorderCB.IsChecked();
2099 
2100     int nOrderMode = int(sal_IntPtr(maNUpPage.maNupOrderBox.GetEntryData(
2101                            maNUpPage.maNupOrderBox.GetSelectEntryPos() )));
2102     if( nOrderMode == SV_PRINT_PRT_NUP_ORDER_LRTB )
2103         aMPS.nOrder = PrinterController::LRTB;
2104     else if( nOrderMode == SV_PRINT_PRT_NUP_ORDER_TBLR )
2105         aMPS.nOrder = PrinterController::TBLR;
2106     else if( nOrderMode == SV_PRINT_PRT_NUP_ORDER_RLTB )
2107         aMPS.nOrder = PrinterController::RLTB;
2108     else if( nOrderMode == SV_PRINT_PRT_NUP_ORDER_TBRL )
2109         aMPS.nOrder = PrinterController::TBRL;
2110 
2111     int nOrientationMode = int(sal_IntPtr(maNUpPage.maNupOrientationBox.GetEntryData(
2112                                  maNUpPage.maNupOrientationBox.GetSelectEntryPos() )));
2113     if( nOrientationMode == SV_PRINT_PRT_NUP_ORIENTATION_LANDSCAPE )
2114         aMPS.aPaperSize = maNupLandscapeSize;
2115     else if( nOrientationMode == SV_PRINT_PRT_NUP_ORIENTATION_PORTRAIT )
2116         aMPS.aPaperSize = maNupPortraitSize;
2117     else // automatic mode
2118     {
2119         // get size of first real page to see if it is portrait or landscape
2120         // we assume same page sizes for all the pages for this
2121         Size aPageSize = getJobPageSize();
2122 
2123         Size aMultiSize( aPageSize.Width() * nCols, aPageSize.Height() * nRows );
2124         if( aMultiSize.Width() > aMultiSize.Height() ) // fits better on landscape
2125             aMPS.aPaperSize = maNupLandscapeSize;
2126         else
2127             aMPS.aPaperSize = maNupPortraitSize;
2128     }
2129 
2130     maPController->setMultipage( aMPS );
2131 
2132     maNUpPage.maNupOrderWin.setValues( nOrderMode, nCols, nRows );
2133 
2134     preparePreview( true, true );
2135 }
2136 
IMPL_LINK(PrintDialog,SelectHdl,ListBox *,pBox)2137 IMPL_LINK( PrintDialog, SelectHdl, ListBox*, pBox )
2138 {
2139     if(  pBox == &maJobPage.maPrinters )
2140     {
2141         String aNewPrinter( pBox->GetSelectEntry() );
2142         // set new printer
2143         maPController->setPrinter( boost::shared_ptr<Printer>( new Printer( aNewPrinter ) ) );
2144         maPController->resetPrinterOptions( maOptionsPage.maToFileBox.IsChecked() );
2145         // update text fields
2146         updatePrinterText();
2147         preparePreview( true, false );
2148     }
2149     else if( pBox == &maNUpPage.maNupOrientationBox || pBox == &maNUpPage.maNupOrderBox )
2150     {
2151         updateNup();
2152     }
2153     else if( pBox == &maNUpPage.maNupPagesBox )
2154     {
2155         if( !maNUpPage.maPagesBtn.IsChecked() )
2156             maNUpPage.maPagesBtn.Check();
2157         updateNupFromPages();
2158     }
2159 
2160     return 0;
2161 }
2162 
IMPL_LINK(PrintDialog,ClickHdl,Button *,pButton)2163 IMPL_LINK( PrintDialog, ClickHdl, Button*, pButton )
2164 {
2165     if( pButton == &maOKButton || pButton == &maCancelButton )
2166     {
2167         storeToSettings();
2168         EndDialog( pButton == &maOKButton );
2169     }
2170     else if( pButton == &maHelpButton )
2171     {
2172         // start help system
2173         Help* pHelp = Application::GetHelp();
2174         if( pHelp )
2175         {
2176             pHelp->Start( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".HelpID:vcl:PrintDialog:OK" ) ), &maOKButton );
2177         }
2178     }
2179     else if( pButton == &maForwardBtn )
2180     {
2181         previewForward();
2182     }
2183     else if( pButton == &maBackwardBtn )
2184     {
2185         previewBackward();
2186     }
2187     else if( pButton == &maOptionsPage.maToFileBox )
2188     {
2189         maOKButton.SetText( maOptionsPage.maToFileBox.IsChecked() ? maPrintToFileText : maPrintText );
2190         maPController->resetPrinterOptions( maOptionsPage.maToFileBox.IsChecked() );
2191         getLayout()->resize();
2192         preparePreview( true, true );
2193     }
2194     else if( pButton == &maNUpPage.maBrochureBtn )
2195     {
2196         PropertyValue* pVal = getValueForWindow( pButton );
2197         if( pVal )
2198         {
2199             sal_Bool bVal = maNUpPage.maBrochureBtn.IsChecked();
2200             pVal->Value <<= bVal;
2201 
2202             checkOptionalControlDependencies();
2203 
2204             // update preview and page settings
2205             preparePreview();
2206         }
2207         if( maNUpPage.maBrochureBtn.IsChecked() )
2208         {
2209             maNUpPage.maNupPagesBox.SelectEntryPos( 0 );
2210             updateNupFromPages();
2211             maNUpPage.showAdvancedControls( false );
2212             maNUpPage.enableNupControls( false );
2213         }
2214     }
2215     else if( pButton == &maNUpPage.maPagesBtn )
2216     {
2217         maNUpPage.enableNupControls( true );
2218         updateNupFromPages();
2219     }
2220     else if( pButton == &maJobPage.maDetailsBtn )
2221     {
2222         bool bShow = maJobPage.maDetailsBtn.IsChecked();
2223         maJobPage.mxDetails->show( bShow );
2224         if( bShow )
2225         {
2226             maDetailsCollapsedSize = GetOutputSizePixel();
2227             // enlarge dialog if necessary
2228             Size aMinSize( maJobPage.getLayout()->getOptimalSize( WINDOWSIZE_MINIMUM ) );
2229             Size aCurSize( maJobPage.GetSizePixel() );
2230             if( aCurSize.Height() < aMinSize.Height() )
2231             {
2232                 Size aDlgSize( GetOutputSizePixel() );
2233                 aDlgSize.Height() += aMinSize.Height() - aCurSize.Height();
2234                 SetOutputSizePixel( aDlgSize );
2235             }
2236             maDetailsExpandedSize = GetOutputSizePixel();
2237         }
2238         else if( maDetailsCollapsedSize.Width() > 0   &&
2239                  maDetailsCollapsedSize.Height() > 0 )
2240         {
2241             // if the user did not resize the dialog
2242             // make it smaller again on collapsing the details
2243             Size aDlgSize( GetOutputSizePixel() );
2244             if( aDlgSize == maDetailsExpandedSize &&
2245                 aDlgSize.Height() > maDetailsCollapsedSize.Height() )
2246             {
2247                 SetOutputSizePixel( maDetailsCollapsedSize );
2248             }
2249         }
2250     }
2251     else if( pButton == &maJobPage.maCollateBox )
2252     {
2253         maPController->setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Collate" ) ),
2254                                  makeAny( sal_Bool(isCollate()) ) );
2255         checkControlDependencies();
2256     }
2257     else if( pButton == &maJobPage.maReverseOrderBox )
2258     {
2259         sal_Bool bChecked = maJobPage.maReverseOrderBox.IsChecked();
2260         maPController->setReversePrint( bChecked );
2261         maPController->setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintReverse" ) ),
2262                                  makeAny( bChecked ) );
2263         preparePreview( true, true );
2264     }
2265     else if( pButton == &maNUpPage.maBorderCB )
2266     {
2267         updateNup();
2268     }
2269     else
2270     {
2271         if( pButton == &maJobPage.maSetupButton )
2272         {
2273             maPController->setupPrinter( this );
2274             preparePreview( true, true );
2275         }
2276         checkControlDependencies();
2277     }
2278     return 0;
2279 }
2280 
IMPL_LINK(PrintDialog,ModifyHdl,Edit *,pEdit)2281 IMPL_LINK( PrintDialog, ModifyHdl, Edit*, pEdit )
2282 {
2283     checkControlDependencies();
2284     if( pEdit == &maNUpPage.maNupRowsEdt || pEdit == &maNUpPage.maNupColEdt ||
2285         pEdit == &maNUpPage.maSheetMarginEdt || pEdit == &maNUpPage.maPageMarginEdt
2286        )
2287     {
2288         updateNupFromPages();
2289     }
2290     else if( pEdit == &maPageEdit )
2291     {
2292         mnCurPage = sal_Int32( maPageEdit.GetValue() - 1 );
2293         preparePreview( true, true );
2294     }
2295     else if( pEdit == &maJobPage.maCopyCountField )
2296     {
2297         maPController->setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CopyCount" ) ),
2298                                makeAny( sal_Int32(maJobPage.maCopyCountField.GetValue()) ) );
2299         maPController->setValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Collate" ) ),
2300                                makeAny( sal_Bool(isCollate()) ) );
2301     }
2302     return 0;
2303 }
2304 
IMPL_LINK(PrintDialog,UIOptionsChanged,void *,EMPTYARG)2305 IMPL_LINK( PrintDialog, UIOptionsChanged, void*, EMPTYARG )
2306 {
2307     checkOptionalControlDependencies();
2308     return 0;
2309 }
2310 
getValueForWindow(Window * i_pWindow) const2311 PropertyValue* PrintDialog::getValueForWindow( Window* i_pWindow ) const
2312 {
2313     PropertyValue* pVal = NULL;
2314     std::map< Window*, rtl::OUString >::const_iterator it = maControlToPropertyMap.find( i_pWindow );
2315     if( it != maControlToPropertyMap.end() )
2316     {
2317         pVal = maPController->getValue( it->second );
2318         DBG_ASSERT( pVal, "property value not found" );
2319     }
2320     else
2321     {
2322         DBG_ERROR( "changed control not in property map" );
2323     }
2324     return pVal;
2325 }
2326 
updateWindowFromProperty(const rtl::OUString & i_rProperty)2327 void PrintDialog::updateWindowFromProperty( const rtl::OUString& i_rProperty )
2328 {
2329     beans::PropertyValue* pValue = maPController->getValue( i_rProperty );
2330     std::map< rtl::OUString, std::vector< Window* > >::const_iterator it = maPropertyToWindowMap.find( i_rProperty );
2331     if( pValue && it != maPropertyToWindowMap.end() )
2332     {
2333         const std::vector< Window* >& rWindows( it->second );
2334         if( ! rWindows.empty() )
2335         {
2336             sal_Bool bVal = sal_False;
2337             sal_Int32 nVal = -1;
2338             if( pValue->Value >>= bVal )
2339             {
2340                 // we should have a CheckBox for this one
2341                 CheckBox* pBox = dynamic_cast< CheckBox* >( rWindows.front() );
2342                 if( pBox )
2343                 {
2344                     pBox->Check( bVal );
2345                 }
2346                 else if( i_rProperty.equalsAscii( "PrintProspect" ) )
2347                 {
2348                     // EVIL special case
2349                     if( bVal )
2350                         maNUpPage.maBrochureBtn.Check();
2351                     else
2352                         maNUpPage.maPagesBtn.Check();
2353                 }
2354                 else
2355                 {
2356                     DBG_ASSERT( 0, "missing a checkbox" );
2357                 }
2358             }
2359             else if( pValue->Value >>= nVal )
2360             {
2361                 // this could be a ListBox or a RadioButtonGroup
2362                 ListBox* pList = dynamic_cast< ListBox* >( rWindows.front() );
2363                 if( pList )
2364                 {
2365                     pList->SelectEntryPos( static_cast< sal_uInt16 >(nVal) );
2366                 }
2367                 else if( nVal >= 0 && nVal < sal_Int32(rWindows.size() ) )
2368                 {
2369                     RadioButton* pBtn = dynamic_cast< RadioButton* >( rWindows[nVal] );
2370                     DBG_ASSERT( pBtn, "unexpected control for property" );
2371                     if( pBtn )
2372                         pBtn->Check();
2373                 }
2374             }
2375         }
2376     }
2377 }
2378 
makeEnabled(Window * i_pWindow)2379 void PrintDialog::makeEnabled( Window* i_pWindow )
2380 {
2381     std::map< Window*, rtl::OUString >::const_iterator it = maControlToPropertyMap.find( i_pWindow );
2382     if( it != maControlToPropertyMap.end() )
2383     {
2384         rtl::OUString aDependency( maPController->makeEnabled( it->second ) );
2385         if( aDependency.getLength() )
2386             updateWindowFromProperty( aDependency );
2387     }
2388 }
2389 
IMPL_LINK(PrintDialog,UIOption_CheckHdl,CheckBox *,i_pBox)2390 IMPL_LINK( PrintDialog, UIOption_CheckHdl, CheckBox*, i_pBox )
2391 {
2392     PropertyValue* pVal = getValueForWindow( i_pBox );
2393     if( pVal )
2394     {
2395         makeEnabled( i_pBox );
2396 
2397         sal_Bool bVal = i_pBox->IsChecked();
2398         pVal->Value <<= bVal;
2399 
2400         checkOptionalControlDependencies();
2401 
2402         // update preview and page settings
2403         preparePreview();
2404     }
2405     return 0;
2406 }
2407 
IMPL_LINK(PrintDialog,UIOption_RadioHdl,RadioButton *,i_pBtn)2408 IMPL_LINK( PrintDialog, UIOption_RadioHdl, RadioButton*, i_pBtn )
2409 {
2410     // this handler gets called for all radiobuttons that get unchecked, too
2411     // however we only want one notificaction for the new value (that is for
2412     // the button that gets checked)
2413     if( i_pBtn->IsChecked() )
2414     {
2415         PropertyValue* pVal = getValueForWindow( i_pBtn );
2416         std::map< Window*, sal_Int32 >::const_iterator it = maControlToNumValMap.find( i_pBtn );
2417         if( pVal && it != maControlToNumValMap.end() )
2418         {
2419             makeEnabled( i_pBtn );
2420 
2421             sal_Int32 nVal = it->second;
2422             pVal->Value <<= nVal;
2423 
2424             checkOptionalControlDependencies();
2425 
2426             // update preview and page settings
2427             preparePreview();
2428         }
2429     }
2430     return 0;
2431 }
2432 
IMPL_LINK(PrintDialog,UIOption_SelectHdl,ListBox *,i_pBox)2433 IMPL_LINK( PrintDialog, UIOption_SelectHdl, ListBox*, i_pBox )
2434 {
2435     PropertyValue* pVal = getValueForWindow( i_pBox );
2436     if( pVal )
2437     {
2438         makeEnabled( i_pBox );
2439 
2440         sal_Int32 nVal( i_pBox->GetSelectEntryPos() );
2441         pVal->Value <<= nVal;
2442 
2443         checkOptionalControlDependencies();
2444 
2445         // update preview and page settings
2446         preparePreview();
2447     }
2448     return 0;
2449 }
2450 
IMPL_LINK(PrintDialog,UIOption_ModifyHdl,Edit *,i_pBox)2451 IMPL_LINK( PrintDialog, UIOption_ModifyHdl, Edit*, i_pBox )
2452 {
2453     PropertyValue* pVal = getValueForWindow( i_pBox );
2454     if( pVal )
2455     {
2456         makeEnabled( i_pBox );
2457 
2458         NumericField* pNum = dynamic_cast<NumericField*>(i_pBox);
2459         MetricField* pMetric = dynamic_cast<MetricField*>(i_pBox);
2460         if( pNum )
2461         {
2462             sal_Int64 nVal = pNum->GetValue();
2463             pVal->Value <<= nVal;
2464         }
2465         else if( pMetric )
2466         {
2467             sal_Int64 nVal = pMetric->GetValue();
2468             pVal->Value <<= nVal;
2469         }
2470         else
2471         {
2472             rtl::OUString aVal( i_pBox->GetText() );
2473             pVal->Value <<= aVal;
2474         }
2475 
2476         checkOptionalControlDependencies();
2477 
2478         // update preview and page settings
2479         preparePreview();
2480     }
2481     return 0;
2482 }
2483 
Command(const CommandEvent & rEvt)2484 void PrintDialog::Command( const CommandEvent& rEvt )
2485 {
2486     if( rEvt.GetCommand() == COMMAND_WHEEL )
2487     {
2488         const CommandWheelData* pWheelData = rEvt.GetWheelData();
2489         if( pWheelData->GetDelta() > 0 )
2490             previewForward();
2491         else if( pWheelData->GetDelta() < 0 )
2492             previewBackward();
2493         /*
2494         else
2495             huh ?
2496         */
2497     }
2498 }
2499 
Resize()2500 void PrintDialog::Resize()
2501 {
2502     // maLayout.setManagedArea( Rectangle( Point( 0, 0 ), GetSizePixel() ) );
2503     // and do the preview; however the metafile does not need to be gotten anew
2504     preparePreview( false );
2505 
2506     // do an invalidate for the benefit of the grouping elements
2507     Invalidate();
2508 }
2509 
previewForward()2510 void PrintDialog::previewForward()
2511 {
2512     maPageEdit.Up();
2513 }
2514 
previewBackward()2515 void PrintDialog::previewBackward()
2516 {
2517     maPageEdit.Down();
2518 }
2519 
2520 // -----------------------------------------------------------------------------
2521 //
2522 // PrintProgressDialog
2523 //
2524 // -----------------------------------------------------------------------------
2525 
PrintProgressDialog(Window * i_pParent,int i_nMax)2526 PrintProgressDialog::PrintProgressDialog( Window* i_pParent, int i_nMax ) :
2527     ModelessDialog( i_pParent, VclResId( SV_DLG_PRINT_PROGRESS ) ),
2528     maText( this, VclResId( SV_PRINT_PROGRESS_TEXT ) ),
2529     maButton( this, VclResId( SV_PRINT_PROGRESS_CANCEL ) ),
2530     mbCanceled( false ),
2531     mnCur( 0 ),
2532     mnMax( i_nMax ),
2533     mnProgressHeight( 15 ),
2534     mbNativeProgress( false )
2535 {
2536     FreeResource();
2537 
2538     if( mnMax < 1 )
2539         mnMax = 1;
2540 
2541     maStr = maText.GetText();
2542 
2543     maButton.SetClickHdl( LINK( this, PrintProgressDialog, ClickHdl ) );
2544 
2545 }
2546 
~PrintProgressDialog()2547 PrintProgressDialog::~PrintProgressDialog()
2548 {
2549 }
2550 
IMPL_LINK(PrintProgressDialog,ClickHdl,Button *,pButton)2551 IMPL_LINK( PrintProgressDialog, ClickHdl, Button*, pButton )
2552 {
2553     if( pButton == &maButton )
2554         mbCanceled = true;
2555 
2556     return 0;
2557 }
2558 
implCalcProgressRect()2559 void PrintProgressDialog::implCalcProgressRect()
2560 {
2561     if( IsNativeControlSupported( CTRL_PROGRESS, PART_ENTIRE_CONTROL ) )
2562     {
2563         ImplControlValue aValue;
2564         Rectangle aControlRegion( Point(), Size( 100, mnProgressHeight ) );
2565         Rectangle aNativeControlRegion, aNativeContentRegion;
2566         if( GetNativeControlRegion( CTRL_PROGRESS, PART_ENTIRE_CONTROL, aControlRegion,
2567                                     CTRL_STATE_ENABLED, aValue, rtl::OUString(),
2568                                     aNativeControlRegion, aNativeContentRegion ) )
2569         {
2570             mnProgressHeight = aNativeControlRegion.GetHeight();
2571         }
2572         mbNativeProgress = true;
2573     }
2574     maProgressRect = Rectangle( Point( 10, maText.GetPosPixel().Y() + maText.GetSizePixel().Height() + 8 ),
2575                                 Size( GetSizePixel().Width() - 20, mnProgressHeight ) );
2576 }
2577 
setProgress(int i_nCurrent,int i_nMax)2578 void PrintProgressDialog::setProgress( int i_nCurrent, int i_nMax )
2579 {
2580     if( maProgressRect.IsEmpty() )
2581         implCalcProgressRect();
2582 
2583     mnCur = i_nCurrent;
2584     if( i_nMax != -1 )
2585         mnMax = i_nMax;
2586 
2587     if( mnMax < 1 )
2588         mnMax = 1;
2589 
2590     rtl::OUString aNewText( searchAndReplace( maStr, "%p", 2, rtl::OUString::valueOf( mnCur ) ) );
2591     aNewText = searchAndReplace( aNewText, "%n", 2, rtl::OUString::valueOf( mnMax ) );
2592     maText.SetText( aNewText );
2593 
2594     // update progress
2595     Invalidate( maProgressRect, INVALIDATE_UPDATE );
2596 }
2597 
tick()2598 void PrintProgressDialog::tick()
2599 {
2600     if( mnCur < mnMax )
2601         setProgress( ++mnCur );
2602 }
2603 
reset()2604 void PrintProgressDialog::reset()
2605 {
2606     mbCanceled = false;
2607     setProgress( 0 );
2608 }
2609 
Paint(const Rectangle &)2610 void PrintProgressDialog::Paint( const Rectangle& )
2611 {
2612     if( maProgressRect.IsEmpty() )
2613         implCalcProgressRect();
2614 
2615     Push( PUSH_LINECOLOR | PUSH_FILLCOLOR );
2616 	const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
2617 	Color aPrgsColor = rStyleSettings.GetHighlightColor();
2618 	if ( aPrgsColor == rStyleSettings.GetFaceColor() )
2619 		aPrgsColor = rStyleSettings.GetDarkShadowColor();
2620 	SetLineColor();
2621 	SetFillColor( aPrgsColor );
2622 
2623     const long nOffset = 3;
2624     const long nWidth = 3*mnProgressHeight/2;
2625     const long nFullWidth = nWidth + nOffset;
2626     const long nMaxCount = maProgressRect.GetWidth() / nFullWidth;
2627     DrawProgress( this, maProgressRect.TopLeft(),
2628                         nOffset,
2629                         nWidth,
2630                         mnProgressHeight,
2631                         static_cast<sal_uInt16>(0),
2632                         static_cast<sal_uInt16>(10000*mnCur/mnMax),
2633                         static_cast<sal_uInt16>(10000/nMaxCount),
2634                         maProgressRect
2635                         );
2636     Pop();
2637 
2638     if( ! mbNativeProgress )
2639     {
2640         DecorationView aDecoView( this );
2641         Rectangle aFrameRect( maProgressRect );
2642         aFrameRect.Left() -= nOffset;
2643         aFrameRect.Right() += nOffset;
2644         aFrameRect.Top() -= nOffset;
2645         aFrameRect.Bottom() += nOffset;
2646         aDecoView.DrawFrame( aFrameRect );
2647     }
2648 }
2649 
2650