xref: /trunk/main/UnoControls/source/controls/progressmonitor.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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 //____________________________________________________________________________________________________________
29 //  my own includes
30 //____________________________________________________________________________________________________________
31 
32 #include "progressmonitor.hxx"
33 
34 //____________________________________________________________________________________________________________
35 //  includes of other projects
36 //____________________________________________________________________________________________________________
37 #include <com/sun/star/awt/GradientStyle.hpp>
38 #include <com/sun/star/awt/RasterOperation.hpp>
39 #include <com/sun/star/awt/Gradient.hpp>
40 #include <com/sun/star/awt/XGraphics.hpp>
41 #include <com/sun/star/awt/PosSize.hpp>
42 #include <cppuhelper/typeprovider.hxx>
43 #include <tools/debug.hxx>
44 #include <tools/solar.h>
45 
46 //____________________________________________________________________________________________________________
47 //  includes of my project
48 //____________________________________________________________________________________________________________
49 #include "progressbar.hxx"
50 
51 //____________________________________________________________________________________________________________
52 //  namespace
53 //____________________________________________________________________________________________________________
54 
55 using namespace ::cppu                  ;
56 using namespace ::osl                   ;
57 using namespace ::rtl                   ;
58 using namespace ::com::sun::star::uno   ;
59 using namespace ::com::sun::star::lang  ;
60 using namespace ::com::sun::star::awt   ;
61 
62 namespace unocontrols{
63 
64 //____________________________________________________________________________________________________________
65 //  construct/destruct
66 //____________________________________________________________________________________________________________
67 
68 ProgressMonitor::ProgressMonitor( const Reference< XMultiServiceFactory >& xFactory )
69     : BaseContainerControl  ( xFactory  )
70 {
71     // Its not allowed to work with member in this method (refcounter !!!)
72     // But with a HACK (++refcount) its "OK" :-(
73     ++m_refCount ;
74 
75     // Create instances for fixedtext, button and progress ...
76     m_xTopic_Top    = Reference< XFixedText >       ( xFactory->createInstance ( OUString::createFromAscii( FIXEDTEXT_SERVICENAME   ) ), UNO_QUERY ) ;
77     m_xText_Top     = Reference< XFixedText >       ( xFactory->createInstance ( OUString::createFromAscii( FIXEDTEXT_SERVICENAME   ) ), UNO_QUERY ) ;
78     m_xTopic_Bottom = Reference< XFixedText >       ( xFactory->createInstance ( OUString::createFromAscii( FIXEDTEXT_SERVICENAME   ) ), UNO_QUERY ) ;
79     m_xText_Bottom  = Reference< XFixedText >       ( xFactory->createInstance ( OUString::createFromAscii( FIXEDTEXT_SERVICENAME   ) ), UNO_QUERY ) ;
80     m_xButton       = Reference< XButton >          ( xFactory->createInstance ( OUString::createFromAscii( BUTTON_SERVICENAME      ) ), UNO_QUERY ) ;
81     m_xProgressBar  = Reference< XProgressBar >     ( xFactory->createInstance ( OUString::createFromAscii( SERVICENAME_PROGRESSBAR ) ), UNO_QUERY ) ;
82 
83     // ... cast controls to Reference< XControl >  (for "setModel"!) ...
84     Reference< XControl >   xRef_Topic_Top      ( m_xTopic_Top    , UNO_QUERY ) ;
85     Reference< XControl >   xRef_Text_Top       ( m_xText_Top     , UNO_QUERY ) ;
86     Reference< XControl >   xRef_Topic_Bottom   ( m_xTopic_Bottom , UNO_QUERY ) ;
87     Reference< XControl >   xRef_Text_Bottom    ( m_xText_Bottom  , UNO_QUERY ) ;
88     Reference< XControl >   xRef_Button         ( m_xButton       , UNO_QUERY ) ;
89     Reference< XControl >   xRef_ProgressBar    ( m_xProgressBar  , UNO_QUERY ) ;
90 
91     // ... set models ...
92     xRef_Topic_Top->setModel        ( Reference< XControlModel >  ( xFactory->createInstance ( OUString::createFromAscii( FIXEDTEXT_MODELNAME   ) ), UNO_QUERY ) ) ;
93     xRef_Text_Top->setModel         ( Reference< XControlModel >  ( xFactory->createInstance ( OUString::createFromAscii( FIXEDTEXT_MODELNAME   ) ), UNO_QUERY ) ) ;
94     xRef_Topic_Bottom->setModel     ( Reference< XControlModel >  ( xFactory->createInstance ( OUString::createFromAscii( FIXEDTEXT_MODELNAME   ) ), UNO_QUERY ) ) ;
95     xRef_Text_Bottom->setModel      ( Reference< XControlModel >  ( xFactory->createInstance ( OUString::createFromAscii( FIXEDTEXT_MODELNAME   ) ), UNO_QUERY ) ) ;
96     xRef_Button->setModel           ( Reference< XControlModel >  ( xFactory->createInstance ( OUString::createFromAscii( BUTTON_MODELNAME      ) ), UNO_QUERY ) ) ;
97     // ProgressBar has no model !!!
98 
99     // ... and add controls to basecontainercontrol!
100     addControl ( OUString::createFromAscii( CONTROLNAME_TEXT        ) , xRef_Topic_Top      ) ;
101     addControl ( OUString::createFromAscii( CONTROLNAME_TEXT        ) , xRef_Text_Top       ) ;
102     addControl ( OUString::createFromAscii( CONTROLNAME_TEXT        ) , xRef_Topic_Bottom   ) ;
103     addControl ( OUString::createFromAscii( CONTROLNAME_TEXT        ) , xRef_Text_Bottom    ) ;
104     addControl ( OUString::createFromAscii( CONTROLNAME_BUTTON      ) , xRef_Button         ) ;
105     addControl ( OUString::createFromAscii( CONTROLNAME_PROGRESSBAR ) , xRef_ProgressBar    ) ;
106 
107     // FixedText make it automaticly visible by himself ... but not the progressbar !!!
108     // it must be set explicitly
109     Reference< XWindow > xWindowRef_ProgressBar( m_xProgressBar, UNO_QUERY );
110     xWindowRef_ProgressBar->setVisible( sal_True );
111 
112     // Reset to defaults !!!
113     // (progressbar take automaticly its own defaults)
114     m_xButton->setLabel         ( OUString::createFromAscii( DEFAULT_BUTTONLABEL    ) ) ;
115     m_xTopic_Top->setText       ( OUString::createFromAscii( DEFAULT_TOPIC          ) ) ;
116     m_xText_Top->setText        ( OUString::createFromAscii( DEFAULT_TEXT           ) ) ;
117     m_xTopic_Bottom->setText    ( OUString::createFromAscii( DEFAULT_TOPIC          ) ) ;
118     m_xText_Bottom->setText     ( OUString::createFromAscii( DEFAULT_TEXT           ) ) ;
119 
120     --m_refCount ;
121 
122     // Initialize info lists for fixedtext's
123     m_pTextlist_Top     = new IMPL_Textlist ;
124     m_pTextlist_Bottom  = new IMPL_Textlist ;
125 }
126 
127 ProgressMonitor::~ProgressMonitor()
128 {
129     impl_cleanMemory () ;
130 }
131 
132 //____________________________________________________________________________________________________________
133 //  XInterface
134 //____________________________________________________________________________________________________________
135 
136 Any SAL_CALL ProgressMonitor::queryInterface( const Type& rType ) throw( RuntimeException )
137 {
138     // Attention:
139     //  Don't use mutex or guard in this method!!! Is a method of XInterface.
140     Any aReturn ;
141     Reference< XInterface > xDel = BaseContainerControl::impl_getDelegator();
142     if ( xDel.is() )
143     {
144         // If an delegator exist, forward question to his queryInterface.
145         // Delegator will ask his own queryAggregation!
146         aReturn = xDel->queryInterface( rType );
147     }
148     else
149     {
150         // If an delegator unknown, forward question to own queryAggregation.
151         aReturn = queryAggregation( rType );
152     }
153 
154     return aReturn ;
155 }
156 
157 //____________________________________________________________________________________________________________
158 //  XInterface
159 //____________________________________________________________________________________________________________
160 
161 void SAL_CALL ProgressMonitor::acquire() throw()
162 {
163     // Attention:
164     //  Don't use mutex or guard in this method!!! Is a method of XInterface.
165 
166     // Forward to baseclass
167     BaseControl::acquire();
168 }
169 
170 //____________________________________________________________________________________________________________
171 //  XInterface
172 //____________________________________________________________________________________________________________
173 
174 void SAL_CALL ProgressMonitor::release() throw()
175 {
176     // Attention:
177     //  Don't use mutex or guard in this method!!! Is a method of XInterface.
178 
179     // Forward to baseclass
180     BaseControl::release();
181 }
182 
183 //____________________________________________________________________________________________________________
184 //  XTypeProvider
185 //____________________________________________________________________________________________________________
186 
187 Sequence< Type > SAL_CALL ProgressMonitor::getTypes() throw( RuntimeException )
188 {
189     // Optimize this method !
190     // We initialize a static variable only one time. And we don't must use a mutex at every call!
191     // For the first call; pTypeCollection is NULL - for the second call pTypeCollection is different from NULL!
192     static OTypeCollection* pTypeCollection = NULL ;
193 
194     if ( pTypeCollection == NULL )
195     {
196         // Ready for multithreading; get global mutex for first call of this method only! see before
197         MutexGuard aGuard( Mutex::getGlobalMutex() );
198 
199         // Control these pointer again ... it can be, that another instance will be faster then these!
200         if ( pTypeCollection == NULL )
201         {
202             // Create a static typecollection ...
203             static OTypeCollection aTypeCollection  (   ::getCppuType(( const Reference< XLayoutConstrains  >*)NULL )   ,
204                                                         ::getCppuType(( const Reference< XButton            >*)NULL )   ,
205                                                         ::getCppuType(( const Reference< XProgressMonitor   >*)NULL )   ,
206                                                         BaseContainerControl::getTypes()
207                                                     );
208             // ... and set his address to static pointer!
209             pTypeCollection = &aTypeCollection ;
210         }
211     }
212 
213     return pTypeCollection->getTypes();
214 }
215 
216 //____________________________________________________________________________________________________________
217 //  XAggregation
218 //____________________________________________________________________________________________________________
219 
220 Any SAL_CALL ProgressMonitor::queryAggregation( const Type& aType ) throw( RuntimeException )
221 {
222     // Ask for my own supported interfaces ...
223     // Attention: XTypeProvider and XInterface are supported by OComponentHelper!
224     Any aReturn ( ::cppu::queryInterface(   aType                                       ,
225                                             static_cast< XLayoutConstrains* > ( this )  ,
226                                             static_cast< XButton*           > ( this )  ,
227                                             static_cast< XProgressMonitor*  > ( this )
228                                         )
229                 );
230 
231     // If searched interface not supported by this class ...
232     if ( aReturn.hasValue() == sal_False )
233     {
234         // ... ask baseclasses.
235         aReturn = BaseControl::queryAggregation( aType );
236     }
237 
238     return aReturn ;
239 }
240 
241 //____________________________________________________________________________________________________________
242 //  XProgressMonitor
243 //____________________________________________________________________________________________________________
244 
245 void SAL_CALL ProgressMonitor::addText( const OUString& rTopic, const OUString& rText, sal_Bool bbeforeProgress ) throw( RuntimeException )
246 {
247     // Safe impossible cases
248     // Check valid call of this method.
249     DBG_ASSERT ( impl_debug_checkParameter ( rTopic, rText, bbeforeProgress )   , "ProgressMonitor::addText()\nCall without valid parameters!\n") ;
250     DBG_ASSERT ( !(impl_searchTopic ( rTopic, bbeforeProgress ) != NULL )       , "ProgresMonitor::addText()\nThe text already exist.\n"        ) ;
251 
252     // Do nothing (in Release), if topic already exist.
253     if ( impl_searchTopic ( rTopic, bbeforeProgress ) != NULL )
254     {
255         return ;
256     }
257 
258     // Else ... take memory for new item ...
259     IMPL_TextlistItem*  pTextItem = new IMPL_TextlistItem ;
260 
261     if ( pTextItem != NULL )
262     {
263         // Set values ...
264         pTextItem->sTopic   = rTopic ;
265         pTextItem->sText    = rText ;
266 
267         // Ready for multithreading
268         MutexGuard aGuard ( m_aMutex ) ;
269 
270         // ... and insert it in right list.
271         if ( bbeforeProgress == sal_True )
272         {
273             m_pTextlist_Top->Insert    ( pTextItem, LIST_APPEND ) ;
274         }
275         else
276         {
277             m_pTextlist_Bottom->Insert ( pTextItem, LIST_APPEND ) ;
278         }
279     }
280 
281     // ... update window
282     impl_rebuildFixedText   () ;
283     impl_recalcLayout       () ;
284 }
285 
286 //____________________________________________________________________________________________________________
287 //  XProgressMonitor
288 //____________________________________________________________________________________________________________
289 
290 void SAL_CALL ProgressMonitor::removeText ( const OUString& rTopic, sal_Bool bbeforeProgress ) throw( RuntimeException )
291 {
292     // Safe impossible cases
293     // Check valid call of this method.
294     DBG_ASSERT ( impl_debug_checkParameter ( rTopic, bbeforeProgress ), "ProgressMonitor::removeText()\nCall without valid parameters!\n" ) ;
295 
296     // Search the topic ...
297     IMPL_TextlistItem* pSearchItem = impl_searchTopic ( rTopic, bbeforeProgress ) ;
298 
299     if ( pSearchItem != NULL )
300     {
301         // Ready for multithreading
302         MutexGuard aGuard ( m_aMutex ) ;
303 
304         // ... delete item from right list ...
305         if ( bbeforeProgress == sal_True )
306         {
307             m_pTextlist_Top->Remove    ( pSearchItem ) ;
308         }
309         else
310         {
311             m_pTextlist_Bottom->Remove ( pSearchItem ) ;
312         }
313 
314         delete pSearchItem ;
315 
316         // ... and update window.
317         impl_rebuildFixedText   () ;
318         impl_recalcLayout       () ;
319     }
320 }
321 
322 //____________________________________________________________________________________________________________
323 //  XProgressMonitor
324 //____________________________________________________________________________________________________________
325 
326 void SAL_CALL ProgressMonitor::updateText ( const OUString& rTopic, const OUString& rText, sal_Bool bbeforeProgress ) throw( RuntimeException )
327 {
328     // Safe impossible cases
329     // Check valid call of this method.
330     DBG_ASSERT ( impl_debug_checkParameter ( rTopic, rText, bbeforeProgress ), "ProgressMonitor::updateText()\nCall without valid parameters!\n" ) ;
331 
332     // Search topic ...
333     IMPL_TextlistItem* pSearchItem = impl_searchTopic ( rTopic, bbeforeProgress ) ;
334 
335     if ( pSearchItem != NULL )
336     {
337         // Ready for multithreading
338         MutexGuard aGuard ( m_aMutex ) ;
339 
340         // ... update text ...
341         pSearchItem->sText = rText ;
342 
343         // ... and update window.
344         impl_rebuildFixedText   () ;
345         impl_recalcLayout       () ;
346     }
347 }
348 
349 //____________________________________________________________________________________________________________
350 //  XProgressBar
351 //____________________________________________________________________________________________________________
352 
353 void SAL_CALL ProgressMonitor::setForegroundColor ( sal_Int32 nColor ) throw( RuntimeException )
354 {
355     // Ready for multithreading
356     MutexGuard aGuard ( m_aMutex ) ;
357 
358     if ( m_xProgressBar.is () )
359     {
360         m_xProgressBar->setForegroundColor ( nColor ) ;
361     }
362 }
363 
364 //____________________________________________________________________________________________________________
365 //  XProgressBar
366 //____________________________________________________________________________________________________________
367 
368 void SAL_CALL ProgressMonitor::setBackgroundColor ( sal_Int32 nColor ) throw( RuntimeException )
369 {
370     // Ready for multithreading
371     MutexGuard aGuard ( m_aMutex ) ;
372 
373     if ( m_xProgressBar.is () )
374     {
375         m_xProgressBar->setBackgroundColor ( nColor ) ;
376     }
377 }
378 
379 //____________________________________________________________________________________________________________
380 //  XProgressBar
381 //____________________________________________________________________________________________________________
382 
383 void SAL_CALL ProgressMonitor::setValue ( sal_Int32 nValue ) throw( RuntimeException )
384 {
385     // Ready for multithreading
386     MutexGuard aGuard ( m_aMutex ) ;
387 
388     if ( m_xProgressBar.is () )
389     {
390         m_xProgressBar->setValue ( nValue ) ;
391     }
392 }
393 
394 //____________________________________________________________________________________________________________
395 //  XProgressBar
396 //____________________________________________________________________________________________________________
397 
398 void SAL_CALL ProgressMonitor::setRange ( sal_Int32 nMin, sal_Int32 nMax ) throw( RuntimeException )
399 {
400     // Ready for multithreading
401     MutexGuard aGuard ( m_aMutex ) ;
402 
403     if ( m_xProgressBar.is () )
404     {
405         m_xProgressBar->setRange ( nMin, nMax ) ;
406     }
407 }
408 
409 //____________________________________________________________________________________________________________
410 //  XProgressBar
411 //____________________________________________________________________________________________________________
412 
413 sal_Int32 SAL_CALL ProgressMonitor::getValue () throw( RuntimeException )
414 {
415     // Ready for multithreading
416     MutexGuard aGuard ( m_aMutex ) ;
417 
418     if (m_xProgressBar.is())
419     {
420         return m_xProgressBar->getValue () ;
421     }
422 
423     return 0 ;
424 }
425 
426 //____________________________________________________________________________________________________________
427 //  XButton
428 //____________________________________________________________________________________________________________
429 
430 void SAL_CALL ProgressMonitor::addActionListener ( const Reference< XActionListener > & rListener ) throw( RuntimeException )
431 {
432     // Ready for multithreading
433     MutexGuard aGuard ( m_aMutex ) ;
434 
435     if ( m_xButton.is () )
436     {
437         m_xButton->addActionListener ( rListener ) ;
438     }
439 }
440 
441 //____________________________________________________________________________________________________________
442 //  XButton
443 //____________________________________________________________________________________________________________
444 
445 void SAL_CALL ProgressMonitor::removeActionListener ( const Reference< XActionListener > & rListener ) throw( RuntimeException )
446 {
447     // Ready for multithreading
448     MutexGuard aGuard ( m_aMutex ) ;
449 
450     if ( m_xButton.is () )
451     {
452         m_xButton->removeActionListener ( rListener ) ;
453     }
454 }
455 
456 //____________________________________________________________________________________________________________
457 //  XButton
458 //____________________________________________________________________________________________________________
459 
460 void SAL_CALL ProgressMonitor::setLabel ( const OUString& rLabel ) throw( RuntimeException )
461 {
462     // Ready for multithreading
463     MutexGuard aGuard ( m_aMutex ) ;
464 
465     if ( m_xButton.is () )
466     {
467         m_xButton->setLabel ( rLabel ) ;
468     }
469 }
470 
471 //____________________________________________________________________________________________________________
472 //  XButton
473 //____________________________________________________________________________________________________________
474 
475 void SAL_CALL ProgressMonitor::setActionCommand ( const OUString& rCommand ) throw( RuntimeException )
476 {
477     // Ready for multithreading
478     MutexGuard aGuard ( m_aMutex ) ;
479 
480     if ( m_xButton.is () )
481     {
482         m_xButton->setActionCommand ( rCommand ) ;
483     }
484 }
485 
486 //____________________________________________________________________________________________________________
487 //  XLayoutConstrains
488 //____________________________________________________________________________________________________________
489 
490 Size SAL_CALL ProgressMonitor::getMinimumSize () throw( RuntimeException )
491 {
492     return Size (DEFAULT_WIDTH, DEFAULT_HEIGHT) ;
493 }
494 
495 //____________________________________________________________________________________________________________
496 //  XLayoutConstrains
497 //____________________________________________________________________________________________________________
498 
499 Size SAL_CALL ProgressMonitor::getPreferredSize () throw( RuntimeException )
500 {
501     // Ready for multithreading
502     ClearableMutexGuard aGuard ( m_aMutex ) ;
503 
504     // get information about required place of child controls
505     Reference< XLayoutConstrains >  xTopicLayout_Top        ( m_xTopic_Top      , UNO_QUERY ) ;
506     Reference< XLayoutConstrains >  xTopicLayout_Bottom     ( m_xTopic_Bottom   , UNO_QUERY ) ;
507     Reference< XLayoutConstrains >  xButtonLayout           ( m_xButton         , UNO_QUERY ) ;
508     Reference< XWindow >            xProgressBarWindow      ( m_xProgressBar    , UNO_QUERY ) ;
509 
510     Size        aTopicSize_Top      =   xTopicLayout_Top->getPreferredSize          ();
511     Size        aTopicSize_Bottom   =   xTopicLayout_Bottom->getPreferredSize       ();
512     Size        aButtonSize         =   xButtonLayout->getPreferredSize             ();
513     Rectangle   aTempRectangle      =   xProgressBarWindow->getPosSize              ();
514     Size        aProgressBarSize    =   Size( aTempRectangle.Width, aTempRectangle.Height );
515 
516     aGuard.clear () ;
517 
518     // calc preferred size of progressmonitor
519     sal_Int32   nWidth  =   0 ;
520     sal_Int32   nHeight =   0 ;
521 
522     nWidth   =  3 * FREEBORDER          ;
523     nWidth  +=  aProgressBarSize.Width  ;
524 
525     nHeight  =  6 * FREEBORDER          ;
526     nHeight +=  aTopicSize_Top.Height   ;
527     nHeight +=  aProgressBarSize.Height ;
528     nHeight +=  aTopicSize_Bottom.Height;
529     nHeight +=  2                       ;   // 1 for black line, 1 for white line = 3D-Line!
530     nHeight +=  aButtonSize.Height      ;
531 
532     // norm to minimum
533     if ( nWidth<DEFAULT_WIDTH )
534     {
535         nWidth = DEFAULT_WIDTH ;
536     }
537     if ( nHeight<DEFAULT_HEIGHT )
538     {
539         nHeight = DEFAULT_HEIGHT ;
540     }
541 
542     // return to caller
543     return Size ( nWidth, nHeight ) ;
544 }
545 
546 //____________________________________________________________________________________________________________
547 //  XLayoutConstrains
548 //____________________________________________________________________________________________________________
549 
550 Size SAL_CALL ProgressMonitor::calcAdjustedSize ( const Size& /*rNewSize*/ ) throw( RuntimeException )
551 {
552     return getPreferredSize () ;
553 }
554 
555 //____________________________________________________________________________________________________________
556 //  XControl
557 //____________________________________________________________________________________________________________
558 
559 void SAL_CALL ProgressMonitor::createPeer ( const Reference< XToolkit > & rToolkit, const Reference< XWindowPeer > & rParent    ) throw( RuntimeException )
560 {
561     if (!getPeer().is())
562     {
563         BaseContainerControl::createPeer ( rToolkit, rParent ) ;
564 
565         // If user forget to call "setPosSize()", we have still a correct size.
566         // And a "MinimumSize" IS A "MinimumSize"!
567         // We change not the position of control at this point.
568         Size aDefaultSize = getMinimumSize () ;
569         setPosSize ( 0, 0, aDefaultSize.Width, aDefaultSize.Height, PosSize::SIZE ) ;
570     }
571 }
572 
573 //____________________________________________________________________________________________________________
574 //  XControl
575 //____________________________________________________________________________________________________________
576 
577 sal_Bool SAL_CALL ProgressMonitor::setModel ( const Reference< XControlModel > & /*rModel*/ ) throw( RuntimeException )
578 {
579     // We have no model.
580     return sal_False ;
581 }
582 
583 //____________________________________________________________________________________________________________
584 //  XControl
585 //____________________________________________________________________________________________________________
586 
587 Reference< XControlModel > SAL_CALL ProgressMonitor::getModel () throw( RuntimeException )
588 {
589     // We have no model.
590     // return (XControlModel*)this ;
591     return Reference< XControlModel >  () ;
592 }
593 
594 //____________________________________________________________________________________________________________
595 //  XComponent
596 //____________________________________________________________________________________________________________
597 
598 void SAL_CALL ProgressMonitor::dispose () throw( RuntimeException )
599 {
600     // Ready for multithreading
601     MutexGuard aGuard ( m_aMutex ) ;
602 
603     // "removeControl()" control the state of a reference
604     Reference< XControl >  xRef_Topic_Top       ( m_xTopic_Top      , UNO_QUERY ) ;
605     Reference< XControl >  xRef_Text_Top        ( m_xText_Top       , UNO_QUERY ) ;
606     Reference< XControl >  xRef_Topic_Bottom    ( m_xTopic_Bottom   , UNO_QUERY ) ;
607     Reference< XControl >  xRef_Text_Bottom     ( m_xText_Bottom    , UNO_QUERY ) ;
608     Reference< XControl >  xRef_Button          ( m_xButton         , UNO_QUERY ) ;
609     Reference< XControl >  xRef_ProgressBar     ( m_xProgressBar    , UNO_QUERY ) ;
610 
611     removeControl ( xRef_Topic_Top      ) ;
612     removeControl ( xRef_Text_Top       ) ;
613     removeControl ( xRef_Topic_Bottom   ) ;
614     removeControl ( xRef_Text_Bottom    ) ;
615     removeControl ( xRef_Button         ) ;
616     removeControl ( xRef_ProgressBar    ) ;
617 
618     // do'nt use "...->clear ()" or "... = XFixedText ()"
619     // when other hold a reference at this object !!!
620     xRef_Topic_Top->dispose     () ;
621     xRef_Text_Top->dispose      () ;
622     xRef_Topic_Bottom->dispose  () ;
623     xRef_Text_Bottom->dispose   () ;
624     xRef_Button->dispose        () ;
625     xRef_ProgressBar->dispose   () ;
626 
627     BaseContainerControl::dispose () ;
628 }
629 
630 //____________________________________________________________________________________________________________
631 //  XWindow
632 //____________________________________________________________________________________________________________
633 
634 void SAL_CALL ProgressMonitor::setPosSize ( sal_Int32 nX, sal_Int32 nY, sal_Int32 nWidth, sal_Int32 nHeight, sal_Int16 nFlags ) throw( RuntimeException )
635 {
636     Rectangle   aBasePosSize = getPosSize () ;
637     BaseContainerControl::setPosSize (nX, nY, nWidth, nHeight, nFlags) ;
638 
639     // if position or size changed
640     if (
641         ( nWidth  != aBasePosSize.Width ) ||
642         ( nHeight != aBasePosSize.Height)
643        )
644     {
645         // calc new layout for controls
646         impl_recalcLayout () ;
647         // clear background (!)
648         // [Childs was repainted in "recalcLayout" by setPosSize() automaticly!]
649         getPeer()->invalidate(2);
650         // and repaint the control
651         impl_paint ( 0, 0, impl_getGraphicsPeer() ) ;
652     }
653 }
654 
655 //____________________________________________________________________________________________________________
656 //  impl but public method to register service
657 //____________________________________________________________________________________________________________
658 
659 const Sequence< OUString > ProgressMonitor::impl_getStaticSupportedServiceNames()
660 {
661     MutexGuard aGuard( Mutex::getGlobalMutex() );
662     Sequence< OUString > seqServiceNames( 1 );
663     seqServiceNames.getArray() [0] = OUString::createFromAscii( SERVICENAME_PROGRESSMONITOR );
664     return seqServiceNames ;
665 }
666 
667 //____________________________________________________________________________________________________________
668 //  impl but public method to register service
669 //____________________________________________________________________________________________________________
670 
671 const OUString ProgressMonitor::impl_getStaticImplementationName()
672 {
673     return OUString::createFromAscii( IMPLEMENTATIONNAME_PROGRESSMONITOR );
674 }
675 
676 //____________________________________________________________________________________________________________
677 //  protected method
678 //____________________________________________________________________________________________________________
679 
680 void ProgressMonitor::impl_paint ( sal_Int32 nX, sal_Int32 nY, const Reference< XGraphics > & rGraphics )
681 {
682     if (rGraphics.is())
683     {
684         // Ready for multithreading
685         MutexGuard aGuard ( m_aMutex ) ;
686 
687         // paint shadowed border around the progressmonitor
688         rGraphics->setLineColor ( LINECOLOR_SHADOW                                                              ) ;
689         rGraphics->drawLine     ( impl_getWidth()-1, impl_getHeight()-1, impl_getWidth()-1, nY                  ) ;
690         rGraphics->drawLine     ( impl_getWidth()-1, impl_getHeight()-1, nX               , impl_getHeight()-1  ) ;
691 
692         rGraphics->setLineColor ( LINECOLOR_BRIGHT                          ) ;
693         rGraphics->drawLine     ( nX, nY, impl_getWidth(), nY               ) ;
694         rGraphics->drawLine     ( nX, nY, nX             , impl_getHeight() ) ;
695 
696         // Paint 3D-line
697         rGraphics->setLineColor ( LINECOLOR_SHADOW  ) ;
698         rGraphics->drawLine     ( m_a3DLine.X, m_a3DLine.Y, m_a3DLine.X+m_a3DLine.Width, m_a3DLine.Y ) ;
699 
700         rGraphics->setLineColor ( LINECOLOR_BRIGHT  ) ;
701         rGraphics->drawLine     ( m_a3DLine.X, m_a3DLine.Y+1, m_a3DLine.X+m_a3DLine.Width, m_a3DLine.Y+1 ) ;
702     }
703 }
704 
705 //____________________________________________________________________________________________________________
706 //  private method
707 //____________________________________________________________________________________________________________
708 
709 void ProgressMonitor::impl_recalcLayout ()
710 {
711     sal_Int32   nX_Button               ;
712     sal_Int32   nY_Button               ;
713     sal_Int32   nWidth_Button           ;
714     sal_Int32   nHeight_Button          ;
715 
716     sal_Int32   nX_ProgressBar          ;
717     sal_Int32   nY_ProgressBar          ;
718     sal_Int32   nWidth_ProgressBar      ;
719     sal_Int32   nHeight_ProgressBar     ;
720 
721     sal_Int32   nX_3DLine               ;
722     sal_Int32   nY_3DLine               ;
723     sal_Int32   nWidth_3DLine           ;
724     sal_Int32   nHeight_3DLine          ;
725 
726     sal_Int32   nX_Text_Top             ;
727     sal_Int32   nY_Text_Top             ;
728     sal_Int32   nWidth_Text_Top         ;
729     sal_Int32   nHeight_Text_Top        ;
730 
731     sal_Int32   nX_Topic_Top            ;
732     sal_Int32   nY_Topic_Top            ;
733     sal_Int32   nWidth_Topic_Top        ;
734     sal_Int32   nHeight_Topic_Top       ;
735 
736     sal_Int32   nX_Text_Bottom          ;
737     sal_Int32   nY_Text_Bottom          ;
738     sal_Int32   nWidth_Text_Bottom      ;
739     sal_Int32   nHeight_Text_Bottom     ;
740 
741     sal_Int32   nX_Topic_Bottom         ;
742     sal_Int32   nY_Topic_Bottom         ;
743     sal_Int32   nWidth_Topic_Bottom     ;
744     sal_Int32   nHeight_Topic_Bottom    ;
745 
746     // Ready for multithreading
747     MutexGuard aGuard ( m_aMutex ) ;
748 
749     // get information about required place of child controls
750     Reference< XLayoutConstrains >  xTopicLayout_Top    ( m_xTopic_Top      , UNO_QUERY ) ;
751     Reference< XLayoutConstrains >  xTextLayout_Top     ( m_xText_Top       , UNO_QUERY ) ;
752     Reference< XLayoutConstrains >  xTopicLayout_Bottom ( m_xTopic_Bottom   , UNO_QUERY ) ;
753     Reference< XLayoutConstrains >  xTextLayout_Bottom  ( m_xText_Bottom    , UNO_QUERY ) ;
754     Reference< XLayoutConstrains >  xButtonLayout       ( m_xButton         , UNO_QUERY ) ;
755 
756     Size    aTopicSize_Top      =   xTopicLayout_Top->getPreferredSize      () ;
757     Size    aTextSize_Top       =   xTextLayout_Top->getPreferredSize       () ;
758     Size    aTopicSize_Bottom   =   xTopicLayout_Bottom->getPreferredSize   () ;
759     Size    aTextSize_Bottom    =   xTextLayout_Bottom->getPreferredSize    () ;
760     Size    aButtonSize         =   xButtonLayout->getPreferredSize         () ;
761 
762     // calc position and size of child controls
763     // Button has preferred size!
764     nWidth_Button           =   aButtonSize.Width                                               ;
765     nHeight_Button          =   aButtonSize.Height                                              ;
766 
767     // Left column before progressbar has preferred size and fixed position.
768     // But "Width" is oriented on left column below progressbar to!!! "max(...)"
769     nX_Topic_Top            =   FREEBORDER                                                      ;
770     nY_Topic_Top            =   FREEBORDER                                                      ;
771     nWidth_Topic_Top        =   Max ( aTopicSize_Top.Width, aTopicSize_Bottom.Width )           ;
772     nHeight_Topic_Top       =   aTopicSize_Top.Height                                           ;
773 
774     // Right column before progressbar has relativ position to left column ...
775     // ... and a size as rest of dialog size!
776     nX_Text_Top             =   nX_Topic_Top+nWidth_Topic_Top+FREEBORDER                        ;
777     nY_Text_Top             =   nY_Topic_Top                                                    ;
778     nWidth_Text_Top         =   Max ( aTextSize_Top.Width, aTextSize_Bottom.Width )             ;
779     // Fix size of this column to minimum!
780     sal_Int32 nSummaryWidth = nWidth_Text_Top+nWidth_Topic_Top+(3*FREEBORDER) ;
781     if ( nSummaryWidth < DEFAULT_WIDTH )
782         nWidth_Text_Top     =   DEFAULT_WIDTH-nWidth_Topic_Top-(3*FREEBORDER);
783     // Fix size of column to maximum!
784     if ( nSummaryWidth > impl_getWidth() )
785         nWidth_Text_Top     =   impl_getWidth()-nWidth_Topic_Top-(3*FREEBORDER)                 ;
786     nHeight_Text_Top        =   nHeight_Topic_Top                                               ;
787 
788     // Position of progressbar is relativ to columns before.
789     // Progressbar.Width  = Dialog.Width !!!
790     // Progressbar.Height = Button.Height
791     nX_ProgressBar          =   nX_Topic_Top                                                    ;
792     nY_ProgressBar          =   nY_Topic_Top+nHeight_Topic_Top+FREEBORDER                       ;
793     nWidth_ProgressBar      =   FREEBORDER+nWidth_Topic_Top+nWidth_Text_Top                     ;
794     nHeight_ProgressBar     =   nHeight_Button                                                  ;
795 
796     // Oriented by left column before progressbar.
797     nX_Topic_Bottom         =   nX_Topic_Top                                                    ;
798     nY_Topic_Bottom         =   nY_ProgressBar+nHeight_ProgressBar+FREEBORDER                   ;
799     nWidth_Topic_Bottom     =   nWidth_Topic_Top                                                ;
800     nHeight_Topic_Bottom    =   aTopicSize_Bottom.Height                                        ;
801 
802     // Oriented by right column before progressbar.
803     nX_Text_Bottom          =   nX_Topic_Bottom+nWidth_Topic_Bottom+FREEBORDER                  ;
804     nY_Text_Bottom          =   nY_Topic_Bottom                                                 ;
805     nWidth_Text_Bottom      =   nWidth_Text_Top                                                 ;
806     nHeight_Text_Bottom     =   nHeight_Topic_Bottom                                            ;
807 
808     // Oriented by progressbar.
809     nX_3DLine               =   nX_Topic_Top                                                    ;
810     nY_3DLine               =   nY_Topic_Bottom+nHeight_Topic_Bottom+(FREEBORDER/2)             ;
811     nWidth_3DLine           =   nWidth_ProgressBar                                              ;
812     nHeight_3DLine          =   1                                                               ;   // Height for ONE line ! (But we paint two lines!)
813 
814     // Oriented by progressbar.
815     nX_Button               =   nX_ProgressBar+nWidth_ProgressBar-nWidth_Button                 ;
816     nY_Button               =   nY_Topic_Bottom+nHeight_Topic_Bottom+FREEBORDER                 ;
817 
818     // Calc offsets to center controls
819     sal_Int32   nDx ;
820     sal_Int32   nDy ;
821 
822     nDx =   ( (2*FREEBORDER)+nWidth_ProgressBar                                                             ) ;
823     nDy =   ( (6*FREEBORDER)+nHeight_Topic_Top+nHeight_ProgressBar+nHeight_Topic_Bottom+2+nHeight_Button    ) ;
824 
825     // At this point use original dialog size to center controls!
826     nDx =   (impl_getWidth ()/2)-(nDx/2)    ;
827     nDy =   (impl_getHeight()/2)-(nDy/2)    ;
828 
829     if ( nDx<0 )
830     {
831         nDx=0 ;
832     }
833     if ( nDy<0 )
834     {
835         nDy=0 ;
836     }
837 
838     // Set new position and size on all controls
839     Reference< XWindow >  xRef_Topic_Top        ( m_xTopic_Top      , UNO_QUERY ) ;
840     Reference< XWindow >  xRef_Text_Top         ( m_xText_Top       , UNO_QUERY ) ;
841     Reference< XWindow >  xRef_Topic_Bottom     ( m_xTopic_Bottom   , UNO_QUERY ) ;
842     Reference< XWindow >  xRef_Text_Bottom      ( m_xText_Bottom    , UNO_QUERY ) ;
843     Reference< XWindow >  xRef_Button           ( m_xButton         , UNO_QUERY ) ;
844     Reference< XWindow >  xRef_ProgressBar      ( m_xProgressBar    , UNO_QUERY ) ;
845 
846     xRef_Topic_Top->setPosSize      ( nDx+nX_Topic_Top      , nDy+nY_Topic_Top      , nWidth_Topic_Top      , nHeight_Topic_Top     , 15 ) ;
847     xRef_Text_Top->setPosSize       ( nDx+nX_Text_Top       , nDy+nY_Text_Top       , nWidth_Text_Top       , nHeight_Text_Top      , 15 ) ;
848     xRef_Topic_Bottom->setPosSize   ( nDx+nX_Topic_Bottom   , nDy+nY_Topic_Bottom   , nWidth_Topic_Bottom   , nHeight_Topic_Bottom  , 15 ) ;
849     xRef_Text_Bottom->setPosSize    ( nDx+nX_Text_Bottom    , nDy+nY_Text_Bottom    , nWidth_Text_Bottom    , nHeight_Text_Bottom   , 15 ) ;
850     xRef_Button->setPosSize         ( nDx+nX_Button         , nDy+nY_Button         , nWidth_Button         , nHeight_Button        , 15 ) ;
851     xRef_ProgressBar->setPosSize    ( nDx+nX_ProgressBar    , nDy+nY_ProgressBar    , nWidth_ProgressBar    , nHeight_ProgressBar   , 15 ) ;
852 
853     m_a3DLine.X         = nDx+nX_Topic_Top                                          ;
854     m_a3DLine.Y         = nDy+nY_Topic_Bottom+nHeight_Topic_Bottom+(FREEBORDER/2)   ;
855     m_a3DLine.Width     = nWidth_ProgressBar                                        ;
856     m_a3DLine.Height    = nHeight_ProgressBar                                       ;
857 
858     // All childcontrols make an implicit repaint in setPosSize()!
859     // Make it also for this 3D-line ...
860     Reference< XGraphics >  xGraphics = impl_getGraphicsPeer () ;
861 
862     xGraphics->setLineColor ( LINECOLOR_SHADOW  ) ;
863     xGraphics->drawLine     ( m_a3DLine.X, m_a3DLine.Y, m_a3DLine.X+m_a3DLine.Width, m_a3DLine.Y ) ;
864 
865     xGraphics->setLineColor ( LINECOLOR_BRIGHT  ) ;
866     xGraphics->drawLine     ( m_a3DLine.X, m_a3DLine.Y+1, m_a3DLine.X+m_a3DLine.Width, m_a3DLine.Y+1 ) ;
867 }
868 
869 //____________________________________________________________________________________________________________
870 //  private method
871 //____________________________________________________________________________________________________________
872 
873 void ProgressMonitor::impl_rebuildFixedText ()
874 {
875     // Ready for multithreading
876     MutexGuard aGuard ( m_aMutex ) ;
877 
878     // Rebuild fixedtext before progress
879 
880     // Rebuild left site of text
881     if (m_xTopic_Top.is())
882     {
883         OUString        aCollectString  ;
884 
885         // Collect all topics from list and format text.
886         // "\n" MUST BE at the end of line!!! => Else ... topic and his text are not in the same line!!!
887         for ( sal_uInt32 n=0; n<m_pTextlist_Top->Count(); ++n )
888         {
889             IMPL_TextlistItem* pSearchItem = m_pTextlist_Top->GetObject (n) ;
890             aCollectString  +=  pSearchItem->sTopic ;
891             aCollectString  +=  OUString::createFromAscii("\n")             ;
892         }
893         aCollectString  +=  OUString::createFromAscii("\0") ;   // It's better :-)
894 
895         m_xTopic_Top->setText ( aCollectString ) ;
896     }
897 
898     // Rebuild right site of text
899     if (m_xText_Top.is())
900     {
901         OUString        aCollectString  ;
902 
903         // Collect all topics from list and format text.
904         // "\n" MUST BE at the end of line!!! => Else ... topic and his text are not in the same line!!!
905         for ( sal_uInt32 n=0; n<m_pTextlist_Top->Count(); ++n )
906         {
907             IMPL_TextlistItem* pSearchItem = m_pTextlist_Top->GetObject (n) ;
908             aCollectString  +=  pSearchItem->sText ;
909             aCollectString  +=  OUString::createFromAscii("\n")            ;
910         }
911         aCollectString  +=  OUString::createFromAscii("\0") ;   // It's better :-)
912 
913         m_xText_Top->setText ( aCollectString ) ;
914     }
915 
916     // Rebuild fixedtext below progress
917 
918     // Rebuild left site of text
919     if (m_xTopic_Bottom.is())
920     {
921         OUString        aCollectString  ;
922 
923         // Collect all topics from list and format text.
924         // "\n" MUST BE at the end of line!!! => Else ... topic and his text are not in the same line!!!
925         for ( sal_uInt32 n=0; n<m_pTextlist_Bottom->Count(); ++n )
926         {
927             IMPL_TextlistItem* pSearchItem = m_pTextlist_Bottom->GetObject (n) ;
928             aCollectString  +=  pSearchItem->sTopic ;
929             aCollectString  +=  OUString::createFromAscii("\n")             ;
930         }
931         aCollectString  +=  OUString::createFromAscii("\0") ;   // It's better :-)
932 
933         m_xTopic_Bottom->setText ( aCollectString ) ;
934     }
935 
936     // Rebuild right site of text
937     if (m_xText_Bottom.is())
938     {
939         OUString        aCollectString  ;
940 
941         // Collect all topics from list and format text.
942         // "\n" MUST BE at the end of line!!! => Else ... topic and his text are not in the same line!!!
943         for ( sal_uInt32 n=0; n<m_pTextlist_Bottom->Count(); ++n )
944         {
945             IMPL_TextlistItem* pSearchItem = m_pTextlist_Bottom->GetObject (n) ;
946             aCollectString  +=  pSearchItem->sText ;
947             aCollectString  +=  OUString::createFromAscii("\n")            ;
948         }
949         aCollectString  +=  OUString::createFromAscii("\0") ;   // It's better :-)
950 
951         m_xText_Bottom->setText ( aCollectString ) ;
952     }
953 }
954 
955 //____________________________________________________________________________________________________________
956 //  private method
957 //____________________________________________________________________________________________________________
958 
959 void ProgressMonitor::impl_cleanMemory ()
960 {
961     // Ready for multithreading
962     MutexGuard aGuard ( m_aMutex ) ;
963 
964     // Delete all of lists.
965 
966     sal_uInt32 nPosition ;
967 
968     for ( nPosition = 0; nPosition < m_pTextlist_Top->Count () ; ++nPosition )
969     {
970         IMPL_TextlistItem* pSearchItem = m_pTextlist_Top->GetObject ( nPosition ) ;
971         delete pSearchItem ;
972     }
973     m_pTextlist_Top->Clear () ;
974     delete m_pTextlist_Top ;
975 
976     for ( nPosition = 0; nPosition < m_pTextlist_Bottom->Count () ; ++nPosition )
977     {
978         IMPL_TextlistItem* pSearchItem = m_pTextlist_Bottom->GetObject ( nPosition ) ;
979         delete pSearchItem ;
980     }
981     m_pTextlist_Bottom->Clear () ;
982     delete m_pTextlist_Bottom ;
983 }
984 
985 //____________________________________________________________________________________________________________
986 //  private method
987 //____________________________________________________________________________________________________________
988 
989 IMPL_TextlistItem* ProgressMonitor::impl_searchTopic ( const OUString& rTopic, sal_Bool bbeforeProgress )
990 {
991     // Get right textlist for following operations.
992     IMPL_Textlist* pTextList ;
993 
994     // Ready for multithreading
995     ClearableMutexGuard aGuard ( m_aMutex ) ;
996 
997     if ( bbeforeProgress == sal_True )
998     {
999         pTextList = m_pTextlist_Top    ;
1000     }
1001     else
1002     {
1003         pTextList = m_pTextlist_Bottom ;
1004     }
1005 
1006     // Switch off guard.
1007     aGuard.clear () ;
1008 
1009     // Search the topic in textlist.
1010     sal_uInt32  nPosition   =   0                   ;
1011     sal_uInt32  nCount      =   pTextList->Count () ;
1012 
1013     for ( nPosition = 0; nPosition < nCount ; ++nPosition )
1014     {
1015         IMPL_TextlistItem* pSearchItem = pTextList->GetObject ( nPosition ) ;
1016 
1017         if ( pSearchItem->sTopic == rTopic )
1018         {
1019             // We have found this topic ... return a valid pointer.
1020             return pSearchItem ;
1021         }
1022     }
1023 
1024     // We have'nt found this topic ... return a nonvalid pointer.
1025     return NULL ;
1026 }
1027 
1028 //____________________________________________________________________________________________________________
1029 //  debug methods
1030 //____________________________________________________________________________________________________________
1031 
1032 #ifdef DBG_UTIL
1033 
1034 // addText, updateText
1035 sal_Bool ProgressMonitor::impl_debug_checkParameter ( const OUString& rTopic, const OUString& rText, sal_Bool /*bbeforeProgress*/ )
1036 {
1037     // Check "rTopic"
1038     if ( &rTopic        ==  NULL    ) return sal_False ;    // NULL-pointer for reference ???!!!
1039     if ( rTopic.getLength ()    <   1       ) return sal_False ;    // ""
1040 
1041     // Check "rText"
1042     if ( &rText         ==  NULL    ) return sal_False ;    // NULL-pointer for reference ???!!!
1043     if ( rText.getLength () <   1       ) return sal_False ;    // ""
1044 
1045     // "bbeforeProgress" is valid in everyway!
1046 
1047     // Parameter OK ... return sal_True.
1048     return sal_True ;
1049 }
1050 
1051 // removeText
1052 sal_Bool ProgressMonitor::impl_debug_checkParameter ( const OUString& rTopic, sal_Bool /*bbeforeProgress*/ )
1053 {
1054     // Check "rTopic"
1055     if ( &rTopic        ==  NULL    ) return sal_False ;    // NULL-pointer for reference ???!!!
1056     if ( rTopic.getLength ()    <   1       ) return sal_False ;    // ""
1057 
1058     // "bbeforeProgress" is valid in everyway!
1059 
1060     // Parameter OK ... return sal_True.
1061     return sal_True ;
1062 }
1063 
1064 #endif  // #ifdef DBG_UTIL
1065 
1066 }   // namespace unocontrols
1067