xref: /aoo41x/main/padmin/source/padialog.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <unistd.h>
31 #include <string.h>
32 #include <math.h>
33 
34 #include "padialog.hrc"
35 #include "fontentry.hxx"
36 #include "helper.hxx"
37 #include "padialog.hxx"
38 #include "adddlg.hxx"
39 #include "prtsetup.hxx"
40 
41 #include "vcl/msgbox.hxx"
42 #include "vcl/print.hxx"
43 #include "vcl/gradient.hxx"
44 #include "vcl/bitmap.hxx"
45 #include "vcl/lineinfo.hxx"
46 #include "vcl/svapp.hxx"
47 #include "vcl/event.hxx"
48 #include "vcl/printerinfomanager.hxx"
49 
50 #include "tools/stream.hxx"
51 #include "tools/color.hxx"
52 
53 #include "osl/file.hxx"
54 
55 #include "rtl/ustrbuf.hxx"
56 
57 #include "unotools/localedatawrapper.hxx"
58 #include "unotools/configitem.hxx"
59 #include "unotools/configmgr.hxx"
60 
61 #include "com/sun/star/awt/Size.hpp"
62 
63 using namespace psp;
64 using namespace rtl;
65 using namespace padmin;
66 using namespace osl;
67 using namespace com::sun::star;
68 using namespace com::sun::star::uno;
69 using namespace com::sun::star::beans;
70 
71 PADialog* PADialog::Create( Window* pParent, sal_Bool bAdmin )
72 {
73 	return new PADialog( pParent, bAdmin );
74 }
75 
76 PADialog::PADialog( Window* pParent, sal_Bool /*bAdmin*/ ) :
77 		ModalDialog( pParent, PaResId( RID_PADIALOG ) ),
78 		m_aDevicesLB( this, PaResId( RID_PA_LB_DEV ) ),
79 		m_aConfPB( this, PaResId( RID_PA_BTN_CONF ) ),
80 		m_aRenamePB( this, PaResId( RID_PA_BTN_RENAME ) ),
81 		m_aStdPB( this, PaResId( RID_PA_BTN_STD ) ),
82 		m_aRemPB( this, PaResId( RID_PA_BTN_DEL ) ),
83 		m_aTestPagePB( this, PaResId( RID_PA_TESTPAGE ) ),
84 		m_aPrintersFL( this, PaResId( RID_PA_FL_PRINTERS ) ),
85 		m_aDriverTxt( this, PaResId( RID_PA_TXT_DRIVER ) ),
86 		m_aDriver( this, PaResId( RID_PA_TXT_DRIVER_STRING ) ),
87 		m_aLocationTxt( this, PaResId( RID_PA_TXT_LOCATION ) ),
88 		m_aLocation( this, PaResId( RID_PA_TXT_LOCATION_STRING ) ),
89 		m_aCommandTxt( this, PaResId( RID_PA_TXT_COMMAND ) ),
90 		m_aCommand( this, PaResId( RID_PA_TXT_COMMAND_STRING ) ),
91 		m_aCommentTxt( this, PaResId( RID_PA_TXT_COMMENT ) ),
92 		m_aComment( this, PaResId( RID_PA_TXT_COMMENT_STRING ) ),
93         m_aCUPSFL( this, PaResId( RID_PA_FL_CUPSUSAGE ) ),
94         m_aCUPSCB( this, PaResId( RID_PA_CB_CUPSUSAGE ) ),
95         m_aSepButtonFL( this, PaResId( RID_PA_FL_SEPBUTTON ) ),
96 		m_aAddPB( this, PaResId( RID_PA_BTN_ADD ) ),
97 		m_aFontsPB( this, PaResId( RID_PA_BTN_FONTS ) ),
98 		m_aCancelButton( this, PaResId( RID_PA_BTN_CANCEL ) ),
99 		m_aDefPrt( PaResId( RID_PA_STR_DEFPRT ) ),
100 		m_aRenameStr( PaResId( RID_PA_STR_RENAME ) ),
101 		m_rPIManager( PrinterInfoManager::get() )
102 {
103 	FreeResource();
104     updateSettings();
105 	Init();
106 }
107 
108 void PADialog::updateSettings()
109 {
110     if( ! GetSettings().GetStyleSettings().GetHighContrastMode() )
111     {
112         m_aPrinterImg = Image( BitmapEx( PaResId( RID_BMP_SMALL_PRINTER ) ) );
113         m_aFaxImg = Image( BitmapEx( PaResId( RID_BMP_SMALL_FAX ) ) );
114         m_aPdfImg = Image( BitmapEx( PaResId( RID_BMP_SMALL_PDF ) ) );
115     }
116     else
117     {
118         m_aPrinterImg = Image( BitmapEx( PaResId( RID_BMP_SMALL_PRINTER_HC ) ) );
119         m_aFaxImg = Image( BitmapEx( PaResId( RID_BMP_SMALL_FAX_HC ) ) );
120         m_aPdfImg = Image( BitmapEx( PaResId( RID_BMP_SMALL_PDF_HC ) ) );
121     }
122 }
123 
124 void PADialog::Init()
125 {
126     // #i79787# initially ensure printer discovery has ended
127     m_rPIManager.checkPrintersChanged( true );
128     m_aCUPSCB.Check( m_rPIManager.isCUPSDisabled() );
129 
130 	UpdateDevice();
131 	UpdateText();
132 
133 	m_aRemPB.Enable( sal_False );
134 
135 	m_aDevicesLB.SetDoubleClickHdl( LINK( this, PADialog, DoubleClickHdl ) );
136 	m_aDevicesLB.SetSelectHdl( LINK( this, PADialog, SelectHdl ) );
137 	m_aStdPB.SetClickHdl( LINK( this, PADialog, ClickBtnHdl ) );
138 	m_aRemPB.SetClickHdl( LINK( this, PADialog, ClickBtnHdl ) );
139 	m_aConfPB.SetClickHdl( LINK( this, PADialog, ClickBtnHdl ) );
140 	m_aRenamePB.SetClickHdl( LINK( this, PADialog, ClickBtnHdl ) );
141 	m_aTestPagePB.SetClickHdl( LINK( this, PADialog, ClickBtnHdl ) );
142 	m_aFontsPB.SetClickHdl( LINK( this, PADialog, ClickBtnHdl ) );
143 	m_aAddPB.SetClickHdl( LINK( this, PADialog, ClickBtnHdl ) );
144 	m_aDevicesLB.setDelPressedLink( LINK( this, PADialog, DelPressedHdl ) );
145     m_aCUPSCB.SetClickHdl( LINK( this, PADialog, ClickBtnHdl ) );
146 
147 	::psp::PrintFontManager& rFontManager( ::psp::PrintFontManager::get() );
148 	if( ! rFontManager.checkImportPossible() )
149 		m_aFontsPB.Enable( sal_False );
150     if( rFontManager.hasFontconfig() )
151     {
152         m_aFontsPB.Enable( sal_False );
153         m_aFontsPB.Show( sal_False );
154     }
155 
156     // at this point no actual changes will be  written
157     // but the write will have checked whether any writeable config exists
158     if( ! m_rPIManager.writePrinterConfig() )
159     {
160         m_aAddPB.Enable( sal_False );
161         m_aRemPB.Enable( sal_False );
162         m_aConfPB.Enable( sal_False );
163         m_aRenamePB.Enable( sal_False );
164         m_aStdPB.Enable( sal_False );
165         m_aCUPSCB.Enable( sal_False );
166         ErrorBox aBox( GetParent(), WB_OK | WB_DEF_OK, String( PaResId( RID_ERR_NOWRITE ) ) );
167         aBox.Execute();
168     }
169 }
170 
171 PADialog::~PADialog()
172 {
173 	m_rPIManager.writePrinterConfig();
174 	freePadminRC();
175 }
176 
177 long PADialog::Notify( NotifyEvent& rEv )
178 {
179     if( IsVisible() &&
180         (rEv.GetType() == EVENT_GETFOCUS || rEv.GetType() == EVENT_LOSEFOCUS )
181       )
182     {
183         if( m_rPIManager.checkPrintersChanged( true ) )
184         {
185             String aSelectEntry = m_aDevicesLB.GetSelectEntry();
186             UpdateDevice();
187             UpdateText();
188             m_aDevicesLB.SelectEntry( aSelectEntry );
189         }
190     }
191     return ModalDialog::Notify( rEv );
192 }
193 
194 void PADialog::DataChanged( const DataChangedEvent& rEv )
195 {
196     ModalDialog::DataChanged( rEv );
197     if( (rEv.GetType() == DATACHANGED_SETTINGS) &&
198         (rEv.GetFlags() & SETTINGS_STYLE) )
199     {
200         updateSettings();
201         // push the new images into the listbox
202         UpdateDevice();
203     }
204 }
205 
206 String PADialog::getSelectedDevice()
207 {
208 	int nPos = m_aDevicesLB.GetSelectEntryPos();
209 	int nLen = (int)(sal_IntPtr)m_aDevicesLB.GetEntryData( nPos );
210 	return m_aDevicesLB.GetEntry( nPos ).Copy( 0, nLen );
211 }
212 
213 IMPL_LINK( PADialog, DelPressedHdl, ListBox*, pBox )
214 {
215 	if( pBox == &m_aDevicesLB && m_aRemPB.IsEnabled() )
216 		ClickBtnHdl( &m_aRemPB );
217 	return 0;
218 }
219 
220 IMPL_LINK( PADialog, ClickBtnHdl, PushButton*, pButton )
221 {
222 	if( pButton == &m_aStdPB )
223 		UpdateDefPrt();
224 	else if( pButton == &m_aRemPB && AreYouSure( this, RID_QUERY_REMOVEPRINTER ) )
225 		RemDevice();
226 	else if( pButton == &m_aConfPB )
227 		ConfigureDevice();
228 	else if( pButton == &m_aRenamePB )
229 		RenameDevice();
230 	else if( pButton == &m_aTestPagePB )
231 		PrintTestPage();
232 	else if( pButton == &m_aAddPB )
233 		AddDevice();
234 	else if( pButton == &m_aFontsPB )
235 	{
236 		FontNameDlg aDialog( this );
237 		aDialog.Execute();
238 	}
239     else if( static_cast<Button*>(pButton) == &m_aCUPSCB )
240     {
241         m_rPIManager.setCUPSDisabled( m_aCUPSCB.IsChecked() );
242             UpdateDevice();
243             UpdateText();
244     }
245 
246 	return 0;
247 }
248 
249 IMPL_LINK( PADialog, DoubleClickHdl, ListBox*, pListBox )
250 {
251 	if( pListBox == &m_aDevicesLB )
252 		UpdateDefPrt();
253 	return 0;
254 }
255 
256 IMPL_LINK( PADialog, SelectHdl, ListBox*, pListBox )
257 {
258 	if( pListBox == &m_aDevicesLB )
259 	{
260 		String sSelect = getSelectedDevice();
261 		String sDefPrt = m_rPIManager.getDefaultPrinter();
262 		if( sDefPrt == sSelect || ! m_rPIManager.removePrinter( sSelect, true ) )
263 			m_aRemPB.Enable( sal_False );
264 		else
265 			m_aRemPB.Enable( sal_True );
266 		UpdateText();
267 	}
268 	return 0;
269 }
270 
271 void PADialog::UpdateDefPrt()
272 {
273     m_rPIManager.setDefaultPrinter( getSelectedDevice() );
274 
275     UpdateDevice();
276     UpdateText();
277 
278     if( m_aRemPB.HasFocus() )
279         m_aDevicesLB.GetFocus();
280     m_aRemPB.Enable( sal_False );
281 }
282 
283 void PADialog::UpdateText()
284 {
285     OUString aDev( getSelectedDevice() );
286     if( aDev.getLength() )
287     {
288         const PrinterInfo& rInfo = m_rPIManager.getPrinterInfo( aDev );
289         String aDriver( rInfo.m_aPrinterName );
290         aDriver.AppendAscii( " (" );
291         aDriver += String( rInfo.m_aDriverName );
292         aDriver.Append( ')' );
293         m_aDriver.SetText( aDriver );
294         m_aCommand.SetText( rInfo.m_aCommand );
295         m_aComment.SetText( rInfo.m_aComment );
296         m_aLocation.SetText( rInfo.m_aLocation );
297     }
298     else // nothing selected
299     {
300         String aEmpty;
301         m_aDriver.SetText( aEmpty );
302         m_aCommand.SetText( aEmpty );
303         m_aComment.SetText( aEmpty );
304         m_aLocation.SetText( aEmpty );
305     }
306 }
307 
308 static Point project( const Point& rPoint )
309 {
310 	const double angle_x = M_PI / 6.0;
311 	const double angle_z = M_PI / 6.0;
312 
313 	// transform planar coordinates to 3d
314 	double x = rPoint.X();
315 	double y = rPoint.Y();
316 	//double z = 0;
317 
318 	// rotate around X axis
319 	double x1 = x;
320 	double y1 = y * cos( angle_x );
321 	double z1 = y * sin( angle_x );
322 
323 	// rotate around Z axis
324 	double x2 = x1 * cos( angle_z ) + y1 * sin( angle_z );
325 	//double y2 = y1 * cos( angle_z ) - x1 * sin( angle_z );
326 	double z2 = z1;
327 
328 	return Point( (sal_Int32)x2, (sal_Int32)z2 );
329 }
330 
331 static Color approachColor( const Color& rFrom, const Color& rTo )
332 {
333 	Color aColor;
334 	sal_uInt8 nDiff;
335 	// approach red
336 	if( rFrom.GetRed() < rTo.GetRed() )
337 	{
338 		nDiff = rTo.GetRed() - rFrom.GetRed();
339 		aColor.SetRed( rFrom.GetRed() + ( nDiff < 10 ? nDiff : 10 ) );
340 	}
341 	else if( rFrom.GetRed() > rTo.GetRed() )
342 	{
343 		nDiff = rFrom.GetRed() - rTo.GetRed();
344 		aColor.SetRed( rFrom.GetRed() - ( nDiff < 10 ? nDiff : 10 ) );
345 	}
346 	else
347 		aColor.SetRed( rFrom.GetRed() );
348 
349 	// approach Green
350 	if( rFrom.GetGreen() < rTo.GetGreen() )
351 	{
352 		nDiff = rTo.GetGreen() - rFrom.GetGreen();
353 		aColor.SetGreen( rFrom.GetGreen() + ( nDiff < 10 ? nDiff : 10 ) );
354 	}
355 	else if( rFrom.GetGreen() > rTo.GetGreen() )
356 	{
357 		nDiff = rFrom.GetGreen() - rTo.GetGreen();
358 		aColor.SetGreen( rFrom.GetGreen() - ( nDiff < 10 ? nDiff : 10 ) );
359 	}
360 	else
361 		aColor.SetGreen( rFrom.GetGreen() );
362 
363 	// approach blue
364 	if( rFrom.GetBlue() < rTo.GetBlue() )
365 	{
366 		nDiff = rTo.GetBlue() - rFrom.GetBlue();
367 		aColor.SetBlue( rFrom.GetBlue() + ( nDiff < 10 ? nDiff : 10 ) );
368 	}
369 	else if( rFrom.GetBlue() > rTo.GetBlue() )
370 	{
371 		nDiff = rFrom.GetBlue() - rTo.GetBlue();
372 		aColor.SetBlue( rFrom.GetBlue() - ( nDiff < 10 ? nDiff : 10 ) );
373 	}
374 	else
375 		aColor.SetBlue( rFrom.GetBlue() );
376 
377 	return aColor;
378 }
379 
380 class SpaPrinterController : public vcl::PrinterController
381 {
382 public:
383     SpaPrinterController( const boost::shared_ptr<Printer>& i_pPrinter )
384     : vcl::PrinterController( i_pPrinter )
385     {}
386     virtual ~SpaPrinterController()
387     {}
388 
389     virtual int getPageCount() const { return 1; }
390     virtual Sequence< PropertyValue > getPageParameters( int i_nPage ) const;
391     virtual void printPage( int i_nPage ) const;
392     virtual void jobFinished( com::sun::star::view::PrintableState );
393 };
394 
395 Sequence< PropertyValue > SpaPrinterController::getPageParameters( int ) const
396 {
397     Sequence< PropertyValue > aRet( 1 );
398 
399     Size aPageSize( getPrinter()->GetPaperSizePixel() );
400     aPageSize = getPrinter()->PixelToLogic( aPageSize, MapMode( MAP_100TH_MM ) );
401 
402     awt::Size aSize;
403     aSize.Width = aPageSize.Width();
404     aSize.Height = aPageSize.Height();
405     aRet[0].Value = makeAny(aSize);
406 
407     return aRet;
408 }
409 
410 void SpaPrinterController::printPage( int ) const
411 {
412     const double DELTA = 5.0;
413 
414     boost::shared_ptr<Printer> pPrinter( getPrinter() );
415 
416 	PrinterInfo aInfo( psp::PrinterInfoManager::get().getPrinterInfo( pPrinter->GetName() ) );
417 	const PPDParser* pPrintParser = aInfo.m_pParser;
418 
419 	MapMode aMapMode( MAP_100TH_MM );
420 
421 	Bitmap aButterfly( PaResId( RID_BUTTERFLY ) );
422 
423 	pPrinter->SetMapMode( aMapMode );
424 
425     Any aRet = utl::ConfigManager::GetDirectConfigProperty( utl::ConfigManager::PRODUCTNAME );
426     OUString aJobName;
427     aRet >>= aJobName;
428 
429 	aJobName = aJobName + OUString( RTL_CONSTASCII_USTRINGPARAM( " Testpage" ) );
430 
431 	Size aPaperSize=pPrinter->GetOutputSize();
432 	Point aCenter( aPaperSize.Width()/2-300,
433 				   aPaperSize.Height() - aPaperSize.Width()/2 );
434 	Point aP1( aPaperSize.Width()/48, 0), aP2( aPaperSize.Width()/40, 0 ), aPoint;
435 
436 	pPrinter->DrawRect( Rectangle( Point( 0,0 ), aPaperSize ) );
437 	pPrinter->DrawRect( Rectangle( Point( 100,100 ),
438 									Size( aPaperSize.Width()-200,
439 										  aPaperSize.Height()-200 ) ) );
440 	pPrinter->DrawRect( Rectangle( Point( 200,200 ),
441 									Size( aPaperSize.Width()-400,
442 										  aPaperSize.Height()-400 ) ) );
443 	pPrinter->DrawRect( Rectangle( Point( 300,300 ),
444 									Size( aPaperSize.Width()-600,
445 										  aPaperSize.Height()-600 ) ) );
446 
447 	Font aFont( String( RTL_CONSTASCII_USTRINGPARAM( "Courier" ) ), Size( 0, 400 ) );
448 	aFont.SetWeight( WEIGHT_NORMAL );
449 	aFont.SetItalic( ITALIC_NONE );
450 	pPrinter->SetFont( aFont );
451 
452 	OUStringBuffer aPrintText(1024);
453 	long nWidth = 0, nMaxWidth = 0;
454 	String aToken;
455 
456     static const struct
457     {
458             const char* const pDirect;
459             sal_uInt16 nResId;
460     } aResIds[] =
461         {
462             { NULL, RID_TXT_TESTPAGE_NAME },
463             { NULL, RID_TXT_TESTPAGE_MODEL },
464             { "PPD", 0 },
465             { NULL, RID_TXT_TESTPAGE_QUEUE },
466             { NULL, RID_TXT_TESTPAGE_COMMENT },
467             { NULL, RID_TXT_TESTPAGE_DATE },
468             { NULL, RID_TXT_TESTPAGE_TIME }
469         };
470 
471     for( unsigned int i = 0; i < sizeof(aResIds)/sizeof(aResIds[0]); i++ )
472     {
473         if( aResIds[i].pDirect )
474             aToken = String::CreateFromAscii( aResIds[i].pDirect );
475         else
476             aToken = String( PaResId( aResIds[i].nResId ) );
477         nMaxWidth = ( nWidth = pPrinter->GetTextWidth( aToken ) ) > nMaxWidth ? nWidth : nMaxWidth;
478         aPrintText.append( aToken );
479         aPrintText.append( (sal_Unicode)'\n' );
480     };
481 
482 	pPrinter->DrawText( Rectangle( Point( 1000, 1000 ),
483 									Size( aPaperSize.Width() - 2000,
484 										  aPaperSize.Height() - 4000 ) ),
485                           aPrintText.makeStringAndClear(),
486                           TEXT_DRAW_MULTILINE );
487 
488     AllSettings aSettings( Application::GetSettings() );
489     const LocaleDataWrapper& rLocaleWrapper( aSettings.GetLocaleDataWrapper() );
490 
491 	aPrintText.appendAscii( ": " );
492 	aPrintText.append( pPrinter->GetName() );
493 	aPrintText.appendAscii( "\n: " );
494     if( pPrintParser )
495         aPrintText.append( pPrintParser->getPrinterName() );
496 	aPrintText.appendAscii( "\n: " );
497 	INetURLObject aDriverPath( pPrintParser ? pPrintParser->getFilename() : String( RTL_CONSTASCII_USTRINGPARAM( "<undef>" ) ),
498                                INET_PROT_FILE, INetURLObject::ENCODE_ALL );
499 	aPrintText.append( aDriverPath.GetName() );
500 	aPrintText.appendAscii( "\n: " );
501 	aPrintText.append( aInfo.m_aCommand );
502 	aPrintText.appendAscii( "\n: " );
503 	aPrintText.append( aInfo.m_aComment );
504 	aPrintText.appendAscii( "\n: " );
505 	aPrintText.append( rLocaleWrapper.getDate( Date() ) );
506 	aPrintText.appendAscii( "\n: " );
507 	aPrintText.append( rLocaleWrapper.getTime( Time() ) );
508 
509 	pPrinter->DrawText( Rectangle( Point( 1100 + nMaxWidth, 1000 ),
510 									Size( aPaperSize.Width() - 2100 - nMaxWidth,
511 										  aPaperSize.Height() - 4000 ) ),
512 						 aPrintText.makeStringAndClear(),
513 						 TEXT_DRAW_MULTILINE );
514 
515 	pPrinter->DrawBitmap( Point( aPaperSize.Width() - 4000, 1000 ),
516 						   Size( 3000,3000 ),
517 						   aButterfly );
518 	pPrinter->SetFillColor();
519 	pPrinter->DrawRect( Rectangle( Point( aPaperSize.Width() - 4000, 1000 ),
520 									 Size( 3000,3000 ) ) );
521 
522 	Color aWhite( 0xff, 0xff, 0xff );
523 	Color aBlack( 0, 0, 0 );
524 	Color aLightRed( 0xff, 0, 0 );
525 	Color aDarkRed( 0x40, 0, 0 );
526 	Color aLightBlue( 0, 0, 0xff );
527 	Color aDarkBlue( 0,0,0x40 );
528 	Color aLightGreen( 0, 0xff, 0 );
529 	Color aDarkGreen( 0, 0x40, 0 );
530 
531 	Gradient aGradient( GRADIENT_LINEAR, aBlack, aWhite );
532 	aGradient.SetAngle( 900 );
533 	pPrinter->DrawGradient( Rectangle( Point( 1000, 5500 ),
534 										Size( aPaperSize.Width() - 2000,
535 											  500 ) ), aGradient );
536 	aGradient.SetStartColor( aDarkRed );
537 	aGradient.SetEndColor( aLightBlue );
538 	pPrinter->DrawGradient( Rectangle( Point( 1000, 6300 ),
539 										Size( aPaperSize.Width() - 2000,
540 											  500 ) ), aGradient );
541 	aGradient.SetStartColor( aDarkBlue );
542 	aGradient.SetEndColor( aLightGreen );
543 	pPrinter->DrawGradient( Rectangle( Point( 1000, 7100 ),
544 										Size( aPaperSize.Width() - 2000,
545 											  500 ) ), aGradient );
546 	aGradient.SetStartColor( aDarkGreen );
547 	aGradient.SetEndColor( aLightRed );
548 	pPrinter->DrawGradient( Rectangle( Point( 1000, 7900 ),
549 										Size( aPaperSize.Width() - 2000,
550 											  500 ) ), aGradient );
551 
552 
553 
554 	LineInfo aLineInfo( LINE_SOLID, 200 );
555 	double sind = sin( DELTA*M_PI/180.0 );
556 	double cosd = cos( DELTA*M_PI/180.0 );
557 	double factor = 1 + (DELTA/1000.0);
558 	int n=0;
559 	Color aLineColor( 0, 0, 0 );
560 	Color aApproachColor( 0, 0, 200 );
561 	while ( aP2.X() < aCenter.X() && n++ < 680 )
562 	{
563 		aLineInfo.SetWidth( n/3 );
564 		aLineColor = approachColor( aLineColor, aApproachColor );
565 		pPrinter->SetLineColor( aLineColor );
566 
567 		// switch aproach color
568 		if( aApproachColor.IsRGBEqual( aLineColor ) )
569 		{
570 			if( aApproachColor.GetRed() )
571 				aApproachColor = Color( 0, 0, 200 );
572 			else if( aApproachColor.GetGreen() )
573 				aApproachColor = Color( 200, 0, 0 );
574 			else
575 				aApproachColor = Color( 0, 200, 0 );
576 		}
577 
578 		pPrinter->DrawLine( project( aP1 ) + aCenter,
579 							 project( aP2 ) + aCenter,
580 							 aLineInfo );
581 		aPoint.X() = (int)((((double)aP1.X())*cosd - ((double)aP1.Y())*sind)*factor);
582 		aPoint.Y() = (int)((((double)aP1.Y())*cosd + ((double)aP1.X())*sind)*factor);
583 		aP1 = aPoint;
584 		aPoint.X() = (int)((((double)aP2.X())*cosd - ((double)aP2.Y())*sind)*factor);
585 		aPoint.Y() = (int)((((double)aP2.Y())*cosd + ((double)aP2.X())*sind)*factor);
586 		aP2 = aPoint;
587 	}
588 #if (OSL_DEBUG_LEVEL > 1) || defined DBG_UTIL
589 	fprintf( stderr, "%d lines\n",n );
590 #endif
591 }
592 
593 void SpaPrinterController::jobFinished( com::sun::star::view::PrintableState )
594 {
595 	String aInfoString( PaResId( RID_PA_TXT_TESTPAGE_PRINTED ) );
596 	InfoBox aInfoBox( NULL, aInfoString );
597 	aInfoBox.SetText( String( PaResId( RID_BXT_TESTPAGE ) ) );
598 	aInfoBox.Execute();
599 }
600 
601 void PADialog::PrintTestPage()
602 {
603 	String sPrinter( getSelectedDevice() );
604 
605     boost::shared_ptr<Printer> pPrinter( new Printer( sPrinter ) );
606 
607 	if( pPrinter->GetName() != sPrinter )
608 	{
609 		String aString( PaResId( RID_ERR_NOPRINTER ) );
610 		aString.SearchAndReplaceAscii( "%s", sPrinter );
611 
612 		ErrorBox aErrorBox( this, WB_OK | WB_DEF_OK, aString );
613 		aErrorBox.SetText( String( PaResId( RID_BXT_ENVIRONMENT ) ) );
614 		aErrorBox.Execute();
615 		return;
616 	}
617 
618     boost::shared_ptr<vcl::PrinterController> pController( new SpaPrinterController( pPrinter ) );
619     JobSetup aJobSetup( pPrinter->GetJobSetup() );
620     aJobSetup.SetValue( String( RTL_CONSTASCII_USTRINGPARAM( "IsQuickJob" ) ),
621                         String( RTL_CONSTASCII_USTRINGPARAM( "true" ) ) );
622     Printer::PrintJob( pController, aJobSetup );
623 }
624 
625 void PADialog::AddDevice()
626 {
627 	AddPrinterDialog aDlg( this );
628 
629 	if( aDlg.Execute() )
630 		UpdateDevice();
631 }
632 
633 void PADialog::RemDevice()
634 {
635 	String aPrinter( getSelectedDevice() );
636 	String aDefPrinter( m_rPIManager.getDefaultPrinter() );
637 	// do not remove the default printer
638 	if( aPrinter.Equals( aDefPrinter ) )
639 		return;
640 
641 	if( ! m_rPIManager.removePrinter( aPrinter ) )
642 	{
643 		String aText( PaResId( RID_ERR_PRINTERNOTREMOVEABLE ) );
644 		aText.SearchAndReplace( String( RTL_CONSTASCII_USTRINGPARAM( "%s" ) ), aPrinter );
645 		ErrorBox aBox( this, WB_OK | WB_DEF_OK, aText );
646 		aBox.Execute();
647 		return;
648 	}
649 	m_aPrinters.remove( aPrinter );
650 
651 	m_aDevicesLB.RemoveEntry( m_aDevicesLB.GetSelectEntryPos() );
652 	for( int i=0; i < m_aDevicesLB.GetEntryCount(); i++ )
653 	{
654 		if( m_aDevicesLB.GetEntry( i ).CompareTo( aDefPrinter, aDefPrinter.Len() ) == COMPARE_EQUAL )
655 		{
656 			m_aDevicesLB.SelectEntryPos( i, sal_True );
657 			UpdateText();
658 			break;
659 		}
660 	}
661 
662 	m_aDevicesLB.GetFocus();
663 
664 	if( m_aDevicesLB.GetEntryCount() < 2 )
665 		m_aRemPB.Enable( sal_False );
666 }
667 
668 void PADialog::ConfigureDevice()
669 {
670 	String aPrinter( getSelectedDevice() );
671 
672 	if( ! aPrinter.Len() )
673 		return;
674 
675 	PrinterInfo aInfo( m_rPIManager.getPrinterInfo( aPrinter ) );
676 	RTSDialog aDialog( aInfo, aPrinter, true, this );
677 
678 	if( aDialog.Execute() )
679 		m_rPIManager.changePrinterInfo( aPrinter, aDialog.getSetup() );
680 
681 	UpdateText();
682 }
683 
684 void PADialog::RenameDevice()
685 {
686 	String aPrinter( getSelectedDevice() );
687 	OUString aOldPrinter( aPrinter );
688 
689 	if( ! aPrinter.Len() )
690 		return;
691 
692     String aTmpString( PaResId( RID_QRY_PRTNAME ) );
693 	QueryString aQuery( this,
694 						aTmpString,
695 						aPrinter );
696 	aQuery.SetText( m_aRenameStr );
697 	aQuery.Execute();
698 
699 	if( aPrinter.Len() )
700 	{
701 		PrinterInfo aInfo( m_rPIManager.getPrinterInfo( aOldPrinter ) );
702 		aInfo.m_aPrinterName = aPrinter;
703 		if( m_rPIManager.addPrinter( aPrinter, aInfo.m_aDriverName ) )
704 		{
705             bool bWasDefault = m_rPIManager.getDefaultPrinter() == aOldPrinter;
706 			m_aPrinters.push_back( aPrinter );
707 			if( m_rPIManager.removePrinter( aOldPrinter ) )
708 				m_aPrinters.remove( aOldPrinter );
709 			m_rPIManager.changePrinterInfo( aPrinter, aInfo );
710 			if( bWasDefault )
711 			{
712 				m_rPIManager.setDefaultPrinter( aPrinter );
713 				UpdateDefPrt();
714 			}
715 			UpdateDevice();
716 		}
717 	}
718 }
719 
720 void PADialog::UpdateDevice()
721 {
722 	m_aDevicesLB.Clear();
723 
724 	m_rPIManager.listPrinters( m_aPrinters );
725 	::std::list< OUString >::iterator it;
726 	for( it = m_aPrinters.begin(); it != m_aPrinters.end(); ++it )
727 	{
728         const PrinterInfo& rInfo( m_rPIManager.getPrinterInfo( *it ) );
729         sal_Int32 nIndex = 0;
730         bool bAutoQueue = false;
731         bool bFax = false;
732         bool bPdf = false;
733         while( nIndex != -1 && ! bAutoQueue )
734         {
735             OUString aToken( rInfo.m_aFeatures.getToken( 0, ',', nIndex ) );
736             if( aToken.getLength() )
737             {
738                 if( aToken.compareToAscii( "autoqueue" ) == 0 )
739                     bAutoQueue = true;
740                 else if( aToken.compareToAscii( "pdf=", 4 ) == 0 )
741                     bPdf = true;
742                 else if( aToken.compareToAscii( "fax", 3 ) == 0 )
743                     bFax = true;
744             }
745         }
746         if( bAutoQueue )
747             continue;
748 
749 		String aEntry( *it );
750 		if( *it == m_rPIManager.getDefaultPrinter() )
751 		{
752 			aEntry.AppendAscii( " (" );
753 			aEntry += m_aDefPrt;
754 			aEntry.AppendAscii( ")" );
755 		}
756 		int nPos =
757             m_aDevicesLB.InsertEntry( aEntry,
758                                       bFax ? m_aFaxImg :
759                                       bPdf ? m_aPdfImg : m_aPrinterImg
760                                       );
761 		m_aDevicesLB.SetEntryData( nPos, (void*)it->getLength() );
762 		if( *it == m_rPIManager.getDefaultPrinter() )
763 		{
764 			m_aDevicesLB.SelectEntryPos( nPos );
765 			UpdateText();
766 		}
767 	}
768 }
769 
770