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