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 <cppuhelper/queryinterface.hxx>
30 : #include <tools/debug.hxx>
31 : #include <algorithm>
32 :
33 : #include "progressbar.hxx"
34 :
35 : using namespace ::cppu;
36 : using namespace ::osl;
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 = VclPtr<ProgressBar>::Create(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 automatically visible by himself ... but not the progressbar !!!
86 : // it must be set explicitly
87 0 : m_xProgressBar->setVisible( true );
88 :
89 : // Reset to defaults !!!
90 : // (progressbar take automatically 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 ( cppu::UnoType<XLayoutConstrains>::get(),
165 0 : cppu::UnoType<XButton>::get(),
166 0 : cppu::UnoType<XProgressMonitor>::get(),
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 : // Set values ...
221 0 : pTextItem->sTopic = rTopic;
222 0 : pTextItem->sText = rText;
223 :
224 : // Ready for multithreading
225 0 : MutexGuard aGuard ( m_aMutex );
226 :
227 : // ... and insert it in right list.
228 0 : if ( bbeforeProgress )
229 : {
230 0 : maTextlist_Top.push_back( pTextItem );
231 : }
232 : else
233 : {
234 0 : maTextlist_Bottom.push_back( pTextItem );
235 : }
236 :
237 : // ... update window
238 0 : impl_rebuildFixedText ();
239 0 : impl_recalcLayout ();
240 : }
241 :
242 : // XProgressMonitor
243 0 : void SAL_CALL ProgressMonitor::removeText ( const OUString& rTopic, sal_Bool bbeforeProgress ) throw( RuntimeException, std::exception )
244 : {
245 : // Safe impossible cases
246 : // Check valid call of this method.
247 : DBG_ASSERT ( impl_debug_checkParameter ( rTopic, bbeforeProgress ), "ProgressMonitor::removeText()\nCall without valid parameters!\n" );
248 :
249 : // Search the topic ...
250 0 : IMPL_TextlistItem* pSearchItem = impl_searchTopic ( rTopic, bbeforeProgress );
251 :
252 0 : if ( pSearchItem != NULL )
253 : {
254 : // Ready for multithreading
255 0 : MutexGuard aGuard ( m_aMutex );
256 :
257 : // ... delete item from right list ...
258 0 : if ( bbeforeProgress )
259 : {
260 : vector< IMPL_TextlistItem* >::iterator
261 0 : itr = find( maTextlist_Top.begin(), maTextlist_Top.end(), pSearchItem );
262 0 : if (itr != maTextlist_Top.end())
263 0 : maTextlist_Top.erase(itr);
264 : }
265 : else
266 : {
267 : vector< IMPL_TextlistItem* >::iterator
268 0 : itr = find( maTextlist_Bottom.begin(), maTextlist_Bottom.end(), pSearchItem );
269 0 : if (itr != maTextlist_Bottom.end())
270 0 : maTextlist_Bottom.erase(itr);
271 : }
272 :
273 0 : delete pSearchItem;
274 :
275 : // ... and update window.
276 0 : impl_rebuildFixedText ();
277 0 : impl_recalcLayout ();
278 : }
279 0 : }
280 :
281 : // XProgressMonitor
282 0 : void SAL_CALL ProgressMonitor::updateText (
283 : const OUString& rTopic,
284 : const OUString& rText,
285 : sal_Bool bbeforeProgress
286 : ) throw( RuntimeException, std::exception )
287 : {
288 : // Safe impossible cases
289 : // Check valid call of this method.
290 : DBG_ASSERT ( impl_debug_checkParameter ( rTopic, rText, bbeforeProgress ), "ProgressMonitor::updateText()\nCall without valid parameters!\n" );
291 :
292 : // Search topic ...
293 0 : IMPL_TextlistItem* pSearchItem = impl_searchTopic ( rTopic, bbeforeProgress );
294 :
295 0 : if ( pSearchItem != NULL )
296 : {
297 : // Ready for multithreading
298 0 : MutexGuard aGuard ( m_aMutex );
299 :
300 : // ... update text ...
301 0 : pSearchItem->sText = rText;
302 :
303 : // ... and update window.
304 0 : impl_rebuildFixedText ();
305 0 : impl_recalcLayout ();
306 : }
307 0 : }
308 :
309 : // XProgressBar
310 0 : void SAL_CALL ProgressMonitor::setForegroundColor ( sal_Int32 nColor ) throw( RuntimeException, std::exception )
311 : {
312 : // Ready for multithreading
313 0 : MutexGuard aGuard ( m_aMutex );
314 :
315 0 : m_xProgressBar->setForegroundColor ( nColor );
316 0 : }
317 :
318 : // XProgressBar
319 0 : void SAL_CALL ProgressMonitor::setBackgroundColor ( sal_Int32 nColor ) throw( RuntimeException, std::exception )
320 : {
321 : // Ready for multithreading
322 0 : MutexGuard aGuard ( m_aMutex );
323 :
324 0 : m_xProgressBar->setBackgroundColor ( nColor );
325 0 : }
326 :
327 : // XProgressBar
328 0 : void SAL_CALL ProgressMonitor::setValue ( sal_Int32 nValue ) throw( RuntimeException, std::exception )
329 : {
330 : // Ready for multithreading
331 0 : MutexGuard aGuard ( m_aMutex );
332 :
333 0 : m_xProgressBar->setValue ( nValue );
334 0 : }
335 :
336 : // XProgressBar
337 0 : void SAL_CALL ProgressMonitor::setRange ( sal_Int32 nMin, sal_Int32 nMax ) throw( RuntimeException, std::exception )
338 : {
339 : // Ready for multithreading
340 0 : MutexGuard aGuard ( m_aMutex );
341 :
342 0 : m_xProgressBar->setRange ( nMin, nMax );
343 0 : }
344 :
345 : // XProgressBar
346 0 : sal_Int32 SAL_CALL ProgressMonitor::getValue () throw( RuntimeException, std::exception )
347 : {
348 : // Ready for multithreading
349 0 : MutexGuard aGuard ( m_aMutex );
350 :
351 0 : return m_xProgressBar->getValue ();
352 : }
353 :
354 : // XButton
355 0 : void SAL_CALL ProgressMonitor::addActionListener ( const css::uno::Reference< XActionListener > & rListener ) throw( RuntimeException, std::exception )
356 : {
357 : // Ready for multithreading
358 0 : MutexGuard aGuard ( m_aMutex );
359 :
360 0 : if ( m_xButton.is () )
361 : {
362 0 : m_xButton->addActionListener ( rListener );
363 0 : }
364 0 : }
365 :
366 : // XButton
367 0 : void SAL_CALL ProgressMonitor::removeActionListener ( const css::uno::Reference< XActionListener > & rListener ) throw( RuntimeException, std::exception )
368 : {
369 : // Ready for multithreading
370 0 : MutexGuard aGuard ( m_aMutex );
371 :
372 0 : if ( m_xButton.is () )
373 : {
374 0 : m_xButton->removeActionListener ( rListener );
375 0 : }
376 0 : }
377 :
378 : // XButton
379 0 : void SAL_CALL ProgressMonitor::setLabel ( const OUString& rLabel ) throw( RuntimeException, std::exception )
380 : {
381 : // Ready for multithreading
382 0 : MutexGuard aGuard ( m_aMutex );
383 :
384 0 : if ( m_xButton.is () )
385 : {
386 0 : m_xButton->setLabel ( rLabel );
387 0 : }
388 0 : }
389 :
390 : // XButton
391 0 : void SAL_CALL ProgressMonitor::setActionCommand ( const OUString& rCommand ) throw( RuntimeException, std::exception )
392 : {
393 : // Ready for multithreading
394 0 : MutexGuard aGuard ( m_aMutex );
395 :
396 0 : if ( m_xButton.is () )
397 : {
398 0 : m_xButton->setActionCommand ( rCommand );
399 0 : }
400 0 : }
401 :
402 : // XLayoutConstrains
403 0 : Size SAL_CALL ProgressMonitor::getMinimumSize () throw( RuntimeException, std::exception )
404 : {
405 0 : return Size (PROGRESSMONITOR_DEFAULT_WIDTH, PROGRESSMONITOR_DEFAULT_HEIGHT);
406 : }
407 :
408 : // XLayoutConstrains
409 0 : Size SAL_CALL ProgressMonitor::getPreferredSize () throw( RuntimeException, std::exception )
410 : {
411 : // Ready for multithreading
412 0 : ClearableMutexGuard aGuard ( m_aMutex );
413 :
414 : // get information about required place of child controls
415 0 : css::uno::Reference< XLayoutConstrains > xTopicLayout_Top ( m_xTopic_Top , UNO_QUERY );
416 0 : css::uno::Reference< XLayoutConstrains > xTopicLayout_Bottom ( m_xTopic_Bottom , UNO_QUERY );
417 0 : css::uno::Reference< XLayoutConstrains > xButtonLayout ( m_xButton , UNO_QUERY );
418 :
419 0 : Size aTopicSize_Top = xTopicLayout_Top->getPreferredSize ();
420 0 : Size aTopicSize_Bottom = xTopicLayout_Bottom->getPreferredSize ();
421 0 : Size aButtonSize = xButtonLayout->getPreferredSize ();
422 0 : Rectangle aTempRectangle = m_xProgressBar->getPosSize();
423 0 : Size aProgressBarSize = Size( aTempRectangle.Width, aTempRectangle.Height );
424 :
425 0 : aGuard.clear ();
426 :
427 : // calc preferred size of progressmonitor
428 0 : sal_Int32 nWidth = 3 * PROGRESSMONITOR_FREEBORDER;
429 0 : nWidth += aProgressBarSize.Width;
430 :
431 0 : sal_Int32 nHeight = 6 * PROGRESSMONITOR_FREEBORDER;
432 0 : nHeight += aTopicSize_Top.Height;
433 0 : nHeight += aProgressBarSize.Height;
434 0 : nHeight += aTopicSize_Bottom.Height;
435 0 : nHeight += 2; // 1 for black line, 1 for white line = 3D-Line!
436 0 : nHeight += aButtonSize.Height;
437 :
438 : // norm to minimum
439 0 : if ( nWidth < PROGRESSMONITOR_DEFAULT_WIDTH )
440 : {
441 0 : nWidth = PROGRESSMONITOR_DEFAULT_WIDTH;
442 : }
443 0 : if ( nHeight < PROGRESSMONITOR_DEFAULT_HEIGHT )
444 : {
445 0 : nHeight = PROGRESSMONITOR_DEFAULT_HEIGHT;
446 : }
447 :
448 : // return to caller
449 0 : return Size ( nWidth, nHeight );
450 : }
451 :
452 : // XLayoutConstrains
453 0 : Size SAL_CALL ProgressMonitor::calcAdjustedSize ( const Size& /*rNewSize*/ ) throw( RuntimeException, std::exception )
454 : {
455 0 : return getPreferredSize ();
456 : }
457 :
458 : // XControl
459 0 : void SAL_CALL ProgressMonitor::createPeer ( const css::uno::Reference< XToolkit > & rToolkit, const css::uno::Reference< XWindowPeer > & rParent ) throw( RuntimeException, std::exception )
460 : {
461 0 : if (!getPeer().is())
462 : {
463 0 : BaseContainerControl::createPeer ( rToolkit, rParent );
464 :
465 : // If user forget to call "setPosSize()", we have still a correct size.
466 : // And a "MinimumSize" IS A "MinimumSize"!
467 : // We change not the position of control at this point.
468 0 : Size aDefaultSize = getMinimumSize ();
469 0 : setPosSize ( 0, 0, aDefaultSize.Width, aDefaultSize.Height, PosSize::SIZE );
470 : }
471 0 : }
472 :
473 : // XControl
474 0 : sal_Bool SAL_CALL ProgressMonitor::setModel ( const css::uno::Reference< XControlModel > & /*rModel*/ ) throw( RuntimeException, std::exception )
475 : {
476 : // We have no model.
477 0 : return false;
478 : }
479 :
480 : // XControl
481 0 : css::uno::Reference< XControlModel > SAL_CALL ProgressMonitor::getModel () throw( RuntimeException, std::exception )
482 : {
483 : // We have no model.
484 : // return (XControlModel*)this;
485 0 : return css::uno::Reference< XControlModel > ();
486 : }
487 :
488 : // XComponent
489 0 : void SAL_CALL ProgressMonitor::dispose () throw( RuntimeException, std::exception )
490 : {
491 : // Ready for multithreading
492 0 : MutexGuard aGuard ( m_aMutex );
493 :
494 : // "removeControl()" control the state of a reference
495 0 : css::uno::Reference< XControl > xRef_Topic_Top ( m_xTopic_Top , UNO_QUERY );
496 0 : css::uno::Reference< XControl > xRef_Text_Top ( m_xText_Top , UNO_QUERY );
497 0 : css::uno::Reference< XControl > xRef_Topic_Bottom ( m_xTopic_Bottom , UNO_QUERY );
498 0 : css::uno::Reference< XControl > xRef_Text_Bottom ( m_xText_Bottom , UNO_QUERY );
499 0 : css::uno::Reference< XControl > xRef_Button ( m_xButton , UNO_QUERY );
500 :
501 0 : removeControl ( xRef_Topic_Top );
502 0 : removeControl ( xRef_Text_Top );
503 0 : removeControl ( xRef_Topic_Bottom );
504 0 : removeControl ( xRef_Text_Bottom );
505 0 : removeControl ( xRef_Button );
506 0 : removeControl ( m_xProgressBar.get() );
507 :
508 : // do'nt use "...->clear ()" or "... = XFixedText ()"
509 : // when other hold a reference at this object !!!
510 0 : xRef_Topic_Top->dispose ();
511 0 : xRef_Text_Top->dispose ();
512 0 : xRef_Topic_Bottom->dispose ();
513 0 : xRef_Text_Bottom->dispose ();
514 0 : xRef_Button->dispose ();
515 0 : m_xProgressBar->dispose();
516 :
517 0 : BaseContainerControl::dispose ();
518 0 : }
519 :
520 : // XWindow
521 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 )
522 : {
523 0 : Rectangle aBasePosSize = getPosSize ();
524 0 : BaseContainerControl::setPosSize (nX, nY, nWidth, nHeight, nFlags);
525 :
526 : // if position or size changed
527 0 : if (
528 0 : ( nWidth != aBasePosSize.Width ) ||
529 0 : ( nHeight != aBasePosSize.Height)
530 : )
531 : {
532 : // calc new layout for controls
533 0 : impl_recalcLayout ();
534 : // clear background (!)
535 : // [Children were repainted in "recalcLayout" by setPosSize() automatically!]
536 0 : getPeer()->invalidate(2);
537 : // and repaint the control
538 0 : impl_paint ( 0, 0, impl_getGraphicsPeer() );
539 : }
540 0 : }
541 :
542 : // impl but public method to register service
543 0 : const Sequence< OUString > ProgressMonitor::impl_getStaticSupportedServiceNames()
544 : {
545 0 : return css::uno::Sequence<OUString>();
546 : }
547 :
548 : // impl but public method to register service
549 0 : const OUString ProgressMonitor::impl_getStaticImplementationName()
550 : {
551 0 : return OUString("stardiv.UnoControls.ProgressMonitor");
552 : }
553 :
554 : // protected method
555 0 : void ProgressMonitor::impl_paint ( sal_Int32 nX, sal_Int32 nY, const css::uno::Reference< XGraphics > & rGraphics )
556 : {
557 0 : if (rGraphics.is())
558 : {
559 : // Ready for multithreading
560 0 : MutexGuard aGuard ( m_aMutex );
561 :
562 : // paint shadowed border around the progressmonitor
563 0 : rGraphics->setLineColor ( PROGRESSMONITOR_LINECOLOR_SHADOW );
564 0 : rGraphics->drawLine ( impl_getWidth()-1, impl_getHeight()-1, impl_getWidth()-1, nY );
565 0 : rGraphics->drawLine ( impl_getWidth()-1, impl_getHeight()-1, nX , impl_getHeight()-1 );
566 :
567 0 : rGraphics->setLineColor ( PROGRESSMONITOR_LINECOLOR_BRIGHT );
568 0 : rGraphics->drawLine ( nX, nY, impl_getWidth(), nY );
569 0 : rGraphics->drawLine ( nX, nY, nX , impl_getHeight() );
570 :
571 : // Paint 3D-line
572 0 : rGraphics->setLineColor ( PROGRESSMONITOR_LINECOLOR_SHADOW );
573 0 : rGraphics->drawLine ( m_a3DLine.X, m_a3DLine.Y, m_a3DLine.X+m_a3DLine.Width, m_a3DLine.Y );
574 :
575 0 : rGraphics->setLineColor ( PROGRESSMONITOR_LINECOLOR_BRIGHT );
576 0 : rGraphics->drawLine ( m_a3DLine.X, m_a3DLine.Y+1, m_a3DLine.X+m_a3DLine.Width, m_a3DLine.Y+1 );
577 : }
578 0 : }
579 :
580 : // private method
581 0 : void ProgressMonitor::impl_recalcLayout ()
582 : {
583 : sal_Int32 nX_Button;
584 : sal_Int32 nY_Button;
585 : sal_Int32 nWidth_Button;
586 : sal_Int32 nHeight_Button;
587 :
588 : sal_Int32 nX_ProgressBar;
589 : sal_Int32 nY_ProgressBar;
590 : sal_Int32 nWidth_ProgressBar;
591 : sal_Int32 nHeight_ProgressBar;
592 :
593 : sal_Int32 nX_Text_Top;
594 : sal_Int32 nY_Text_Top;
595 : sal_Int32 nWidth_Text_Top;
596 : sal_Int32 nHeight_Text_Top;
597 :
598 : sal_Int32 nX_Topic_Top;
599 : sal_Int32 nY_Topic_Top;
600 : sal_Int32 nWidth_Topic_Top;
601 : sal_Int32 nHeight_Topic_Top;
602 :
603 : sal_Int32 nX_Text_Bottom;
604 : sal_Int32 nY_Text_Bottom;
605 : sal_Int32 nWidth_Text_Bottom;
606 : sal_Int32 nHeight_Text_Bottom;
607 :
608 : sal_Int32 nX_Topic_Bottom;
609 : sal_Int32 nY_Topic_Bottom;
610 : sal_Int32 nWidth_Topic_Bottom;
611 : sal_Int32 nHeight_Topic_Bottom;
612 :
613 : // Ready for multithreading
614 0 : MutexGuard aGuard ( m_aMutex );
615 :
616 : // get information about required place of child controls
617 0 : css::uno::Reference< XLayoutConstrains > xTopicLayout_Top ( m_xTopic_Top , UNO_QUERY );
618 0 : css::uno::Reference< XLayoutConstrains > xTextLayout_Top ( m_xText_Top , UNO_QUERY );
619 0 : css::uno::Reference< XLayoutConstrains > xTopicLayout_Bottom ( m_xTopic_Bottom , UNO_QUERY );
620 0 : css::uno::Reference< XLayoutConstrains > xTextLayout_Bottom ( m_xText_Bottom , UNO_QUERY );
621 0 : css::uno::Reference< XLayoutConstrains > xButtonLayout ( m_xButton , UNO_QUERY );
622 :
623 0 : Size aTopicSize_Top = xTopicLayout_Top->getPreferredSize ();
624 0 : Size aTextSize_Top = xTextLayout_Top->getPreferredSize ();
625 0 : Size aTopicSize_Bottom = xTopicLayout_Bottom->getPreferredSize ();
626 0 : Size aTextSize_Bottom = xTextLayout_Bottom->getPreferredSize ();
627 0 : Size aButtonSize = xButtonLayout->getPreferredSize ();
628 :
629 : // calc position and size of child controls
630 : // Button has preferred size!
631 0 : nWidth_Button = aButtonSize.Width;
632 0 : nHeight_Button = aButtonSize.Height;
633 :
634 : // Left column before progressbar has preferred size and fixed position.
635 : // But "Width" is oriented on left column below progressbar to!!! "max(...)"
636 0 : nX_Topic_Top = PROGRESSMONITOR_FREEBORDER;
637 0 : nY_Topic_Top = PROGRESSMONITOR_FREEBORDER;
638 0 : nWidth_Topic_Top = std::max( aTopicSize_Top.Width, aTopicSize_Bottom.Width );
639 0 : nHeight_Topic_Top = aTopicSize_Top.Height;
640 :
641 : // Right column before progressbar has relativ position to left column ...
642 : // ... and a size as rest of dialog size!
643 0 : nX_Text_Top = nX_Topic_Top+nWidth_Topic_Top+PROGRESSMONITOR_FREEBORDER;
644 0 : nY_Text_Top = nY_Topic_Top;
645 0 : nWidth_Text_Top = std::max ( aTextSize_Top.Width, aTextSize_Bottom.Width );
646 : // Fix size of this column to minimum!
647 0 : sal_Int32 nSummaryWidth = nWidth_Text_Top+nWidth_Topic_Top+(3*PROGRESSMONITOR_FREEBORDER);
648 0 : if ( nSummaryWidth < PROGRESSMONITOR_DEFAULT_WIDTH )
649 0 : nWidth_Text_Top = PROGRESSMONITOR_DEFAULT_WIDTH-nWidth_Topic_Top-(3*PROGRESSMONITOR_FREEBORDER);
650 : // Fix size of column to maximum!
651 0 : if ( nSummaryWidth > impl_getWidth() )
652 0 : nWidth_Text_Top = impl_getWidth()-nWidth_Topic_Top-(3*PROGRESSMONITOR_FREEBORDER);
653 0 : nHeight_Text_Top = nHeight_Topic_Top;
654 :
655 : // Position of progressbar is relativ to columns before.
656 : // Progressbar.Width = Dialog.Width !!!
657 : // Progressbar.Height = Button.Height
658 0 : nX_ProgressBar = nX_Topic_Top;
659 0 : nY_ProgressBar = nY_Topic_Top+nHeight_Topic_Top+PROGRESSMONITOR_FREEBORDER;
660 0 : nWidth_ProgressBar = PROGRESSMONITOR_FREEBORDER+nWidth_Topic_Top+nWidth_Text_Top;
661 0 : nHeight_ProgressBar = nHeight_Button;
662 :
663 : // Oriented by left column before progressbar.
664 0 : nX_Topic_Bottom = nX_Topic_Top;
665 0 : nY_Topic_Bottom = nY_ProgressBar+nHeight_ProgressBar+PROGRESSMONITOR_FREEBORDER;
666 0 : nWidth_Topic_Bottom = nWidth_Topic_Top;
667 0 : nHeight_Topic_Bottom = aTopicSize_Bottom.Height;
668 :
669 : // Oriented by right column before progressbar.
670 0 : nX_Text_Bottom = nX_Topic_Bottom+nWidth_Topic_Bottom+PROGRESSMONITOR_FREEBORDER;
671 0 : nY_Text_Bottom = nY_Topic_Bottom;
672 0 : nWidth_Text_Bottom = nWidth_Text_Top;
673 0 : nHeight_Text_Bottom = nHeight_Topic_Bottom;
674 :
675 : // Oriented by progressbar.
676 0 : nX_Button = nX_ProgressBar+nWidth_ProgressBar-nWidth_Button;
677 0 : nY_Button = nY_Topic_Bottom+nHeight_Topic_Bottom+PROGRESSMONITOR_FREEBORDER;
678 :
679 : // Calc offsets to center controls
680 : sal_Int32 nDx;
681 : sal_Int32 nDy;
682 :
683 0 : nDx = ( (2*PROGRESSMONITOR_FREEBORDER)+nWidth_ProgressBar );
684 0 : nDy = ( (6*PROGRESSMONITOR_FREEBORDER)+nHeight_Topic_Top+nHeight_ProgressBar+nHeight_Topic_Bottom+2+nHeight_Button );
685 :
686 : // At this point use original dialog size to center controls!
687 0 : nDx = (impl_getWidth ()/2)-(nDx/2);
688 0 : nDy = (impl_getHeight()/2)-(nDy/2);
689 :
690 0 : if ( nDx<0 )
691 : {
692 0 : nDx=0;
693 : }
694 0 : if ( nDy<0 )
695 : {
696 0 : nDy=0;
697 : }
698 :
699 : // Set new position and size on all controls
700 0 : css::uno::Reference< XWindow > xRef_Topic_Top ( m_xTopic_Top , UNO_QUERY );
701 0 : css::uno::Reference< XWindow > xRef_Text_Top ( m_xText_Top , UNO_QUERY );
702 0 : css::uno::Reference< XWindow > xRef_Topic_Bottom ( m_xTopic_Bottom , UNO_QUERY );
703 0 : css::uno::Reference< XWindow > xRef_Text_Bottom ( m_xText_Bottom , UNO_QUERY );
704 0 : css::uno::Reference< XWindow > xRef_Button ( m_xButton , UNO_QUERY );
705 :
706 0 : xRef_Topic_Top->setPosSize ( nDx+nX_Topic_Top , nDy+nY_Topic_Top , nWidth_Topic_Top , nHeight_Topic_Top , 15 );
707 0 : xRef_Text_Top->setPosSize ( nDx+nX_Text_Top , nDy+nY_Text_Top , nWidth_Text_Top , nHeight_Text_Top , 15 );
708 0 : xRef_Topic_Bottom->setPosSize ( nDx+nX_Topic_Bottom , nDy+nY_Topic_Bottom , nWidth_Topic_Bottom , nHeight_Topic_Bottom , 15 );
709 0 : xRef_Text_Bottom->setPosSize ( nDx+nX_Text_Bottom , nDy+nY_Text_Bottom , nWidth_Text_Bottom , nHeight_Text_Bottom , 15 );
710 0 : xRef_Button->setPosSize ( nDx+nX_Button , nDy+nY_Button , nWidth_Button , nHeight_Button , 15 );
711 0 : m_xProgressBar->setPosSize( nDx+nX_ProgressBar, nDy+nY_ProgressBar, nWidth_ProgressBar, nHeight_ProgressBar, 15 );
712 :
713 0 : m_a3DLine.X = nDx+nX_Topic_Top;
714 0 : m_a3DLine.Y = nDy+nY_Topic_Bottom+nHeight_Topic_Bottom+(PROGRESSMONITOR_FREEBORDER/2);
715 0 : m_a3DLine.Width = nWidth_ProgressBar;
716 0 : m_a3DLine.Height = nHeight_ProgressBar;
717 :
718 : // All childcontrols make an implicit repaint in setPosSize()!
719 : // Make it also for this 3D-line ...
720 0 : css::uno::Reference< XGraphics > xGraphics = impl_getGraphicsPeer ();
721 :
722 0 : xGraphics->setLineColor ( PROGRESSMONITOR_LINECOLOR_SHADOW );
723 0 : xGraphics->drawLine ( m_a3DLine.X, m_a3DLine.Y, m_a3DLine.X+m_a3DLine.Width, m_a3DLine.Y );
724 :
725 0 : xGraphics->setLineColor ( PROGRESSMONITOR_LINECOLOR_BRIGHT );
726 0 : xGraphics->drawLine ( m_a3DLine.X, m_a3DLine.Y+1, m_a3DLine.X+m_a3DLine.Width, m_a3DLine.Y+1 );
727 0 : }
728 :
729 : // private method
730 0 : void ProgressMonitor::impl_rebuildFixedText ()
731 : {
732 : // Ready for multithreading
733 0 : MutexGuard aGuard ( m_aMutex );
734 :
735 : // Rebuild fixedtext before progress
736 :
737 : // Rebuild left site of text
738 0 : if (m_xTopic_Top.is())
739 : {
740 0 : OUString aCollectString;
741 :
742 : // Collect all topics from list and format text.
743 : // "\n" MUST BE at the end of line!!! => Else ... topic and his text are not in the same line!!!
744 0 : for ( size_t n = 0; n < maTextlist_Top.size(); ++n )
745 : {
746 0 : IMPL_TextlistItem* pSearchItem = maTextlist_Top[ n ];
747 0 : aCollectString += pSearchItem->sTopic;
748 0 : aCollectString += "\n";
749 : }
750 :
751 0 : m_xTopic_Top->setText ( aCollectString );
752 : }
753 :
754 : // Rebuild right site of text
755 0 : if (m_xText_Top.is())
756 : {
757 0 : OUString aCollectString;
758 :
759 : // Collect all topics from list and format text.
760 : // "\n" MUST BE at the end of line!!! => Else ... topic and his text are not in the same line!!!
761 0 : for ( size_t n = 0; n < maTextlist_Top.size(); ++n )
762 : {
763 0 : IMPL_TextlistItem* pSearchItem = maTextlist_Top[ n ];
764 0 : aCollectString += pSearchItem->sText;
765 0 : aCollectString += "\n";
766 : }
767 :
768 0 : m_xText_Top->setText ( aCollectString );
769 : }
770 :
771 : // Rebuild fixedtext below progress
772 :
773 : // Rebuild left site of text
774 0 : if (m_xTopic_Bottom.is())
775 : {
776 0 : OUString aCollectString;
777 :
778 : // Collect all topics from list and format text.
779 : // "\n" MUST BE at the end of line!!! => Else ... topic and his text are not in the same line!!!
780 0 : for ( size_t n = 0; n < maTextlist_Bottom.size(); ++n )
781 : {
782 0 : IMPL_TextlistItem* pSearchItem = maTextlist_Bottom[ n ];
783 0 : aCollectString += pSearchItem->sTopic;
784 0 : aCollectString += "\n";
785 : }
786 :
787 0 : m_xTopic_Bottom->setText ( aCollectString );
788 : }
789 :
790 : // Rebuild right site of text
791 0 : if (m_xText_Bottom.is())
792 : {
793 0 : OUString aCollectString;
794 :
795 : // Collect all topics from list and format text.
796 : // "\n" MUST BE at the end of line!!! => Else ... topic and his text are not in the same line!!!
797 0 : for ( size_t n = 0; n < maTextlist_Bottom.size(); ++n )
798 : {
799 0 : IMPL_TextlistItem* pSearchItem = maTextlist_Bottom[ n ];
800 0 : aCollectString += pSearchItem->sText;
801 0 : aCollectString += "\n";
802 : }
803 :
804 0 : m_xText_Bottom->setText ( aCollectString );
805 0 : }
806 0 : }
807 :
808 : // private method
809 0 : void ProgressMonitor::impl_cleanMemory ()
810 : {
811 : // Ready for multithreading
812 0 : MutexGuard aGuard ( m_aMutex );
813 :
814 : // Delete all of lists.
815 :
816 0 : for ( size_t nPosition = 0; nPosition < maTextlist_Top.size(); ++nPosition )
817 : {
818 0 : IMPL_TextlistItem* pSearchItem = maTextlist_Top[ nPosition ];
819 0 : delete pSearchItem;
820 : }
821 0 : maTextlist_Top.clear();
822 :
823 0 : for ( size_t nPosition = 0; nPosition < maTextlist_Bottom.size(); ++nPosition )
824 : {
825 0 : IMPL_TextlistItem* pSearchItem = maTextlist_Bottom[ nPosition ];
826 0 : delete pSearchItem;
827 : }
828 0 : maTextlist_Bottom.clear();
829 0 : }
830 :
831 : // private method
832 0 : IMPL_TextlistItem* ProgressMonitor::impl_searchTopic ( const OUString& rTopic, bool bbeforeProgress )
833 : {
834 : // Get right textlist for following operations.
835 : ::std::vector< IMPL_TextlistItem* >* pTextList;
836 :
837 : // Ready for multithreading
838 0 : ClearableMutexGuard aGuard ( m_aMutex );
839 :
840 0 : if ( bbeforeProgress )
841 : {
842 0 : pTextList = &maTextlist_Top;
843 : }
844 : else
845 : {
846 0 : pTextList = &maTextlist_Bottom;
847 : }
848 :
849 : // Switch off guard.
850 0 : aGuard.clear ();
851 :
852 : // Search the topic in textlist.
853 0 : size_t nPosition = 0;
854 0 : size_t nCount = pTextList->size();
855 :
856 0 : for ( nPosition = 0; nPosition < nCount; ++nPosition )
857 : {
858 0 : IMPL_TextlistItem* pSearchItem = pTextList->at( nPosition );
859 :
860 0 : if ( pSearchItem->sTopic == rTopic )
861 : {
862 : // We have found this topic... return a valid pointer.
863 0 : return pSearchItem;
864 : }
865 : }
866 :
867 : // We haven't found this topic... return a nonvalid pointer.
868 0 : return NULL;
869 : }
870 :
871 : // debug methods
872 : #ifdef DBG_UTIL
873 :
874 : // addText, updateText
875 : bool ProgressMonitor::impl_debug_checkParameter (
876 : const OUString& rTopic,
877 : const OUString& rText,
878 : bool /*bbeforeProgress*/
879 : ) {
880 : if ( rTopic.isEmpty() ) return false; // ""
881 :
882 : if ( rText.isEmpty() ) return false; // ""
883 :
884 : // "bbeforeProgress" is valid in everyway!
885 :
886 : // Parameter OK ... return true.
887 : return true;
888 : }
889 :
890 : // removeText
891 : bool ProgressMonitor::impl_debug_checkParameter ( const OUString& rTopic, bool /*bbeforeProgress*/ )
892 : {
893 : if ( rTopic.isEmpty() ) return false; // ""
894 :
895 : // "bbeforeProgress" is valid in everyway!
896 :
897 : // Parameter OK ... return true.
898 : return true;
899 : }
900 :
901 : #endif // #ifdef DBG_UTIL
902 :
903 : } // namespace unocontrols
904 :
905 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|