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