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