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