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 constexpr OUStringLiteral FIXEDTEXT_SERVICENAME = u"com.sun.star.awt.UnoControlFixedText";
43 constexpr OUStringLiteral FIXEDTEXT_MODELNAME = u"com.sun.star.awt.UnoControlFixedTextModel";
44 constexpr OUStringLiteral CONTROLNAME_TEXT = u"Text"; // identifier the control in container
45 constexpr OUStringLiteral CONTROLNAME_PROGRESSBAR = u"ProgressBar";
46 constexpr OUStringLiteral BUTTON_SERVICENAME = u"com.sun.star.awt.UnoControlButton";
47 constexpr OUStringLiteral CONTROLNAME_BUTTON = u"Button";
48 constexpr OUStringLiteral BUTTON_MODELNAME = u"com.sun.star.awt.UnoControlButtonModel";
49 constexpr OUStringLiteral DEFAULT_BUTTONLABEL = u"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() noexcept
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() noexcept
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  // Ready for multithreading
196  MutexGuard aGuard ( m_aMutex );
197 
198  // Safe impossible cases
199  // Check valid call of this method.
200  DBG_ASSERT ( impl_debug_checkParameter ( rTopic, rText ), "ProgressMonitor::addText()\nCall without valid parameters!\n");
201  DBG_ASSERT ( !(impl_searchTopic ( rTopic, bbeforeProgress ) != nullptr ), "ProgressMonitor::addText()\nThe text already exist.\n" );
202 
203  // Do nothing (in Release), if topic already exist.
204  if ( impl_searchTopic ( rTopic, bbeforeProgress ) != nullptr )
205  {
206  return;
207  }
208 
209  // Else ... take memory for new item ...
210  IMPL_TextlistItem aTextItem;
211 
212  // Set values ...
213  aTextItem.sTopic = rTopic;
214  aTextItem.sText = rText;
215 
216  // ... and insert it in right list.
217  if ( bbeforeProgress )
218  {
219  maTextlist_Top.push_back( aTextItem );
220  }
221  else
222  {
223  maTextlist_Bottom.push_back( aTextItem );
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  // Ready for multithreading
239  MutexGuard aGuard ( m_aMutex );
240 
241  // Search the topic ...
242  IMPL_TextlistItem* pSearchItem = impl_searchTopic ( rTopic, bbeforeProgress );
243 
244  if ( pSearchItem == nullptr )
245  return;
246 
247  // ... delete item from right list ...
248  if ( bbeforeProgress )
249  {
250  auto itr = std::find_if( maTextlist_Top.begin(), maTextlist_Top.end(),
251  [&] (IMPL_TextlistItem const &p)
252  { return &p == 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  [&] (IMPL_TextlistItem const &p)
260  { return &p == pSearchItem; } );
261  if (itr != maTextlist_Bottom.end())
262  maTextlist_Bottom.erase(itr);
263  }
264 
265  // ... and update window.
268 }
269 
270 // XProgressMonitor
272  const OUString& rTopic,
273  const OUString& rText,
274  sal_Bool bbeforeProgress
275 )
276 {
277  // Safe impossible cases
278  // Check valid call of this method.
279  DBG_ASSERT ( impl_debug_checkParameter ( rTopic, rText ), "ProgressMonitor::updateText()\nCall without valid parameters!\n" );
280 
281  // Ready for multithreading
282  MutexGuard aGuard ( m_aMutex );
283 
284  // Search topic ...
285  IMPL_TextlistItem* pSearchItem = impl_searchTopic ( rTopic, bbeforeProgress );
286 
287  if ( pSearchItem != nullptr )
288  {
289  // ... update text ...
290  pSearchItem->sText = rText;
291 
292  // ... and update window.
295  }
296 }
297 
298 // XProgressBar
299 void SAL_CALL ProgressMonitor::setForegroundColor ( sal_Int32 nColor )
300 {
301  // Ready for multithreading
302  MutexGuard aGuard ( m_aMutex );
303 
304  m_xProgressBar->setForegroundColor ( nColor );
305 }
306 
307 // XProgressBar
308 void SAL_CALL ProgressMonitor::setBackgroundColor ( sal_Int32 nColor )
309 {
310  // Ready for multithreading
311  MutexGuard aGuard ( m_aMutex );
312 
313  m_xProgressBar->setBackgroundColor ( nColor );
314 }
315 
316 // XProgressBar
317 void SAL_CALL ProgressMonitor::setValue ( sal_Int32 nValue )
318 {
319  // Ready for multithreading
320  MutexGuard aGuard ( m_aMutex );
321 
322  m_xProgressBar->setValue ( nValue );
323 }
324 
325 // XProgressBar
326 void SAL_CALL ProgressMonitor::setRange ( sal_Int32 nMin, sal_Int32 nMax )
327 {
328  // Ready for multithreading
329  MutexGuard aGuard ( m_aMutex );
330 
331  m_xProgressBar->setRange ( nMin, nMax );
332 }
333 
334 // XProgressBar
335 sal_Int32 SAL_CALL ProgressMonitor::getValue ()
336 {
337  // Ready for multithreading
338  MutexGuard aGuard ( m_aMutex );
339 
340  return m_xProgressBar->getValue ();
341 }
342 
343 // XButton
344 void SAL_CALL ProgressMonitor::addActionListener ( const css::uno::Reference< XActionListener > & rListener )
345 {
346  // Ready for multithreading
347  MutexGuard aGuard ( m_aMutex );
348 
349  if ( m_xButton.is () )
350  {
351  m_xButton->addActionListener ( rListener );
352  }
353 }
354 
355 // XButton
356 void SAL_CALL ProgressMonitor::removeActionListener ( const css::uno::Reference< XActionListener > & rListener )
357 {
358  // Ready for multithreading
359  MutexGuard aGuard ( m_aMutex );
360 
361  if ( m_xButton.is () )
362  {
363  m_xButton->removeActionListener ( rListener );
364  }
365 }
366 
367 // XButton
368 void SAL_CALL ProgressMonitor::setLabel ( const OUString& rLabel )
369 {
370  // Ready for multithreading
371  MutexGuard aGuard ( m_aMutex );
372 
373  if ( m_xButton.is () )
374  {
375  m_xButton->setLabel ( rLabel );
376  }
377 }
378 
379 // XButton
380 void SAL_CALL ProgressMonitor::setActionCommand ( const OUString& rCommand )
381 {
382  // Ready for multithreading
383  MutexGuard aGuard ( m_aMutex );
384 
385  if ( m_xButton.is () )
386  {
387  m_xButton->setActionCommand ( rCommand );
388  }
389 }
390 
391 // XLayoutConstrains
393 {
395 }
396 
397 // XLayoutConstrains
399 {
400  // Ready for multithreading
401  ClearableMutexGuard aGuard ( m_aMutex );
402 
403  // get information about required place of child controls
404  css::uno::Reference< XLayoutConstrains > xTopicLayout_Top ( m_xTopic_Top , UNO_QUERY );
405  css::uno::Reference< XLayoutConstrains > xTopicLayout_Bottom ( m_xTopic_Bottom , UNO_QUERY );
406  css::uno::Reference< XLayoutConstrains > xButtonLayout ( m_xButton , UNO_QUERY );
407 
408  Size aTopicSize_Top = xTopicLayout_Top->getPreferredSize ();
409  Size aTopicSize_Bottom = xTopicLayout_Bottom->getPreferredSize ();
410  Size aButtonSize = xButtonLayout->getPreferredSize ();
411  Rectangle aTempRectangle = m_xProgressBar->getPosSize();
412  Size aProgressBarSize( aTempRectangle.Width, aTempRectangle.Height );
413 
414  aGuard.clear ();
415 
416  // calc preferred size of progressmonitor
417  sal_Int32 nWidth = 3 * PROGRESSMONITOR_FREEBORDER;
418  nWidth += aProgressBarSize.Width;
419 
420  sal_Int32 nHeight = 6 * PROGRESSMONITOR_FREEBORDER;
421  nHeight += aTopicSize_Top.Height;
422  nHeight += aProgressBarSize.Height;
423  nHeight += aTopicSize_Bottom.Height;
424  nHeight += 2; // 1 for black line, 1 for white line = 3D-Line!
425  nHeight += aButtonSize.Height;
426 
427  // norm to minimum
428  if ( nWidth < PROGRESSMONITOR_DEFAULT_WIDTH )
429  {
431  }
432  if ( nHeight < PROGRESSMONITOR_DEFAULT_HEIGHT )
433  {
435  }
436 
437  // return to caller
438  return Size ( nWidth, nHeight );
439 }
440 
441 // XLayoutConstrains
442 Size SAL_CALL ProgressMonitor::calcAdjustedSize ( const Size& /*rNewSize*/ )
443 {
444  return getPreferredSize ();
445 }
446 
447 // XControl
448 void SAL_CALL ProgressMonitor::createPeer ( const css::uno::Reference< XToolkit > & rToolkit, const css::uno::Reference< XWindowPeer > & rParent )
449 {
450  if (!getPeer().is())
451  {
452  BaseContainerControl::createPeer ( rToolkit, rParent );
453 
454  // If user forget to call "setPosSize()", we have still a correct size.
455  // And a "MinimumSize" IS A "MinimumSize"!
456  // We change not the position of control at this point.
457  Size aDefaultSize = getMinimumSize ();
458  setPosSize ( 0, 0, aDefaultSize.Width, aDefaultSize.Height, PosSize::SIZE );
459  }
460 }
461 
462 // XControl
463 sal_Bool SAL_CALL ProgressMonitor::setModel ( const css::uno::Reference< XControlModel > & /*rModel*/ )
464 {
465  // We have no model.
466  return false;
467 }
468 
469 // XControl
470 css::uno::Reference< XControlModel > SAL_CALL ProgressMonitor::getModel ()
471 {
472  // We have no model.
473  // return (XControlModel*)this;
474  return css::uno::Reference< XControlModel > ();
475 }
476 
477 // XComponent
478 void SAL_CALL ProgressMonitor::dispose ()
479 {
480  // Ready for multithreading
481  MutexGuard aGuard ( m_aMutex );
482 
483  // "removeControl()" control the state of a reference
484  css::uno::Reference< XControl > xRef_Topic_Top ( m_xTopic_Top , UNO_QUERY );
485  css::uno::Reference< XControl > xRef_Text_Top ( m_xText_Top , UNO_QUERY );
486  css::uno::Reference< XControl > xRef_Topic_Bottom ( m_xTopic_Bottom , UNO_QUERY );
487  css::uno::Reference< XControl > xRef_Text_Bottom ( m_xText_Bottom , UNO_QUERY );
488  css::uno::Reference< XControl > xRef_Button ( m_xButton , UNO_QUERY );
489 
490  removeControl ( xRef_Topic_Top );
491  removeControl ( xRef_Text_Top );
492  removeControl ( xRef_Topic_Bottom );
493  removeControl ( xRef_Text_Bottom );
494  removeControl ( xRef_Button );
496 
497  // don't use "...->clear ()" or "... = XFixedText ()"
498  // when other hold a reference at this object !!!
499  xRef_Topic_Top->dispose ();
500  xRef_Text_Top->dispose ();
501  xRef_Topic_Bottom->dispose ();
502  xRef_Text_Bottom->dispose ();
503  xRef_Button->dispose ();
504  m_xProgressBar->dispose();
505 
507 }
508 
509 // XWindow
510 void SAL_CALL ProgressMonitor::setPosSize ( sal_Int32 nX, sal_Int32 nY, sal_Int32 nWidth, sal_Int32 nHeight, sal_Int16 nFlags )
511 {
512  Rectangle aBasePosSize = getPosSize ();
513  BaseContainerControl::setPosSize (nX, nY, nWidth, nHeight, nFlags);
514 
515  // if position or size changed
516  if (
517  ( nWidth != aBasePosSize.Width ) ||
518  ( nHeight != aBasePosSize.Height)
519  )
520  {
521  // calc new layout for controls
523  // clear background (!)
524  // [Children were repainted in "recalcLayout" by setPosSize() automatically!]
525  getPeer()->invalidate(2);
526  // and repaint the control
527  impl_paint ( 0, 0, impl_getGraphicsPeer() );
528  }
529 }
530 
531 // protected method
532 void ProgressMonitor::impl_paint ( sal_Int32 nX, sal_Int32 nY, const css::uno::Reference< XGraphics > & rGraphics )
533 {
534  if (!rGraphics.is())
535  return;
536 
537  // Ready for multithreading
538  MutexGuard aGuard ( m_aMutex );
539 
540  // paint shadowed border around the progressmonitor
541  rGraphics->setLineColor ( PROGRESSMONITOR_LINECOLOR_SHADOW );
542  rGraphics->drawLine ( impl_getWidth()-1, impl_getHeight()-1, impl_getWidth()-1, nY );
543  rGraphics->drawLine ( impl_getWidth()-1, impl_getHeight()-1, nX , impl_getHeight()-1 );
544 
545  rGraphics->setLineColor ( PROGRESSMONITOR_LINECOLOR_BRIGHT );
546  rGraphics->drawLine ( nX, nY, impl_getWidth(), nY );
547  rGraphics->drawLine ( nX, nY, nX , impl_getHeight() );
548 
549  // Paint 3D-line
550  rGraphics->setLineColor ( PROGRESSMONITOR_LINECOLOR_SHADOW );
551  rGraphics->drawLine ( m_a3DLine.X, m_a3DLine.Y, m_a3DLine.X+m_a3DLine.Width, m_a3DLine.Y );
552 
553  rGraphics->setLineColor ( PROGRESSMONITOR_LINECOLOR_BRIGHT );
554  rGraphics->drawLine ( m_a3DLine.X, m_a3DLine.Y+1, m_a3DLine.X+m_a3DLine.Width, m_a3DLine.Y+1 );
555 }
556 
557 // private method
559 {
560  sal_Int32 nX_Button;
561  sal_Int32 nY_Button;
562  sal_Int32 nWidth_Button;
563  sal_Int32 nHeight_Button;
564 
565  sal_Int32 nX_ProgressBar;
566  sal_Int32 nY_ProgressBar;
567  sal_Int32 nWidth_ProgressBar;
568  sal_Int32 nHeight_ProgressBar;
569 
570  sal_Int32 nX_Text_Top;
571  sal_Int32 nY_Text_Top;
572  sal_Int32 nWidth_Text_Top;
573  sal_Int32 nHeight_Text_Top;
574 
575  sal_Int32 nX_Topic_Top;
576  sal_Int32 nY_Topic_Top;
577  sal_Int32 nWidth_Topic_Top;
578  sal_Int32 nHeight_Topic_Top;
579 
580  sal_Int32 nX_Text_Bottom;
581  sal_Int32 nY_Text_Bottom;
582  sal_Int32 nWidth_Text_Bottom;
583  sal_Int32 nHeight_Text_Bottom;
584 
585  sal_Int32 nX_Topic_Bottom;
586  sal_Int32 nY_Topic_Bottom;
587  sal_Int32 nWidth_Topic_Bottom;
588  sal_Int32 nHeight_Topic_Bottom;
589 
590  // Ready for multithreading
591  MutexGuard aGuard ( m_aMutex );
592 
593  // get information about required place of child controls
594  css::uno::Reference< XLayoutConstrains > xTopicLayout_Top ( m_xTopic_Top , UNO_QUERY );
595  css::uno::Reference< XLayoutConstrains > xTextLayout_Top ( m_xText_Top , UNO_QUERY );
596  css::uno::Reference< XLayoutConstrains > xTopicLayout_Bottom ( m_xTopic_Bottom , UNO_QUERY );
597  css::uno::Reference< XLayoutConstrains > xTextLayout_Bottom ( m_xText_Bottom , UNO_QUERY );
598  css::uno::Reference< XLayoutConstrains > xButtonLayout ( m_xButton , UNO_QUERY );
599 
600  Size aTopicSize_Top = xTopicLayout_Top->getPreferredSize ();
601  Size aTextSize_Top = xTextLayout_Top->getPreferredSize ();
602  Size aTopicSize_Bottom = xTopicLayout_Bottom->getPreferredSize ();
603  Size aTextSize_Bottom = xTextLayout_Bottom->getPreferredSize ();
604  Size aButtonSize = xButtonLayout->getPreferredSize ();
605 
606  // calc position and size of child controls
607  // Button has preferred size!
608  nWidth_Button = aButtonSize.Width;
609  nHeight_Button = aButtonSize.Height;
610 
611  // Left column before progressbar has preferred size and fixed position.
612  // But "Width" is oriented on left column below progressbar to!!! "max(...)"
613  nX_Topic_Top = PROGRESSMONITOR_FREEBORDER;
614  nY_Topic_Top = PROGRESSMONITOR_FREEBORDER;
615  nWidth_Topic_Top = std::max( aTopicSize_Top.Width, aTopicSize_Bottom.Width );
616  nHeight_Topic_Top = aTopicSize_Top.Height;
617 
618  // Right column before progressbar has relative position to left column ...
619  // ... and a size as rest of dialog size!
620  nX_Text_Top = nX_Topic_Top+nWidth_Topic_Top+PROGRESSMONITOR_FREEBORDER;
621  nY_Text_Top = nY_Topic_Top;
622  nWidth_Text_Top = std::max ( aTextSize_Top.Width, aTextSize_Bottom.Width );
623  // Fix size of this column to minimum!
624  sal_Int32 nSummaryWidth = nWidth_Text_Top+nWidth_Topic_Top+(3*PROGRESSMONITOR_FREEBORDER);
625  if ( nSummaryWidth < PROGRESSMONITOR_DEFAULT_WIDTH )
626  nWidth_Text_Top = PROGRESSMONITOR_DEFAULT_WIDTH-nWidth_Topic_Top-(3*PROGRESSMONITOR_FREEBORDER);
627  // Fix size of column to maximum!
628  if ( nSummaryWidth > impl_getWidth() )
629  nWidth_Text_Top = impl_getWidth()-nWidth_Topic_Top-(3*PROGRESSMONITOR_FREEBORDER);
630  nHeight_Text_Top = nHeight_Topic_Top;
631 
632  // Position of progressbar is relative to columns before.
633  // Progressbar.Width = Dialog.Width !!!
634  // Progressbar.Height = Button.Height
635  nX_ProgressBar = nX_Topic_Top;
636  nY_ProgressBar = nY_Topic_Top+nHeight_Topic_Top+PROGRESSMONITOR_FREEBORDER;
637  nWidth_ProgressBar = PROGRESSMONITOR_FREEBORDER+nWidth_Topic_Top+nWidth_Text_Top;
638  nHeight_ProgressBar = nHeight_Button;
639 
640  // Oriented by left column before progressbar.
641  nX_Topic_Bottom = nX_Topic_Top;
642  nY_Topic_Bottom = nY_ProgressBar+nHeight_ProgressBar+PROGRESSMONITOR_FREEBORDER;
643  nWidth_Topic_Bottom = nWidth_Topic_Top;
644  nHeight_Topic_Bottom = aTopicSize_Bottom.Height;
645 
646  // Oriented by right column before progressbar.
647  nX_Text_Bottom = nX_Topic_Bottom+nWidth_Topic_Bottom+PROGRESSMONITOR_FREEBORDER;
648  nY_Text_Bottom = nY_Topic_Bottom;
649  nWidth_Text_Bottom = nWidth_Text_Top;
650  nHeight_Text_Bottom = nHeight_Topic_Bottom;
651 
652  // Oriented by progressbar.
653  nX_Button = nX_ProgressBar+nWidth_ProgressBar-nWidth_Button;
654  nY_Button = nY_Topic_Bottom+nHeight_Topic_Bottom+PROGRESSMONITOR_FREEBORDER;
655 
656  // Calc offsets to center controls
657  sal_Int32 nDx;
658  sal_Int32 nDy;
659 
660  nDx = ( (2*PROGRESSMONITOR_FREEBORDER)+nWidth_ProgressBar );
661  nDy = ( (6*PROGRESSMONITOR_FREEBORDER)+nHeight_Topic_Top+nHeight_ProgressBar+nHeight_Topic_Bottom+2+nHeight_Button );
662 
663  // At this point use original dialog size to center controls!
664  nDx = (impl_getWidth ()/2)-(nDx/2);
665  nDy = (impl_getHeight()/2)-(nDy/2);
666 
667  if ( nDx<0 )
668  {
669  nDx=0;
670  }
671  if ( nDy<0 )
672  {
673  nDy=0;
674  }
675 
676  // Set new position and size on all controls
677  css::uno::Reference< XWindow > xRef_Topic_Top ( m_xTopic_Top , UNO_QUERY );
678  css::uno::Reference< XWindow > xRef_Text_Top ( m_xText_Top , UNO_QUERY );
679  css::uno::Reference< XWindow > xRef_Topic_Bottom ( m_xTopic_Bottom , UNO_QUERY );
680  css::uno::Reference< XWindow > xRef_Text_Bottom ( m_xText_Bottom , UNO_QUERY );
681  css::uno::Reference< XWindow > xRef_Button ( m_xButton , UNO_QUERY );
682 
683  xRef_Topic_Top->setPosSize ( nDx+nX_Topic_Top , nDy+nY_Topic_Top , nWidth_Topic_Top , nHeight_Topic_Top , 15 );
684  xRef_Text_Top->setPosSize ( nDx+nX_Text_Top , nDy+nY_Text_Top , nWidth_Text_Top , nHeight_Text_Top , 15 );
685  xRef_Topic_Bottom->setPosSize ( nDx+nX_Topic_Bottom , nDy+nY_Topic_Bottom , nWidth_Topic_Bottom , nHeight_Topic_Bottom , 15 );
686  xRef_Text_Bottom->setPosSize ( nDx+nX_Text_Bottom , nDy+nY_Text_Bottom , nWidth_Text_Bottom , nHeight_Text_Bottom , 15 );
687  xRef_Button->setPosSize ( nDx+nX_Button , nDy+nY_Button , nWidth_Button , nHeight_Button , 15 );
688  m_xProgressBar->setPosSize( nDx+nX_ProgressBar, nDy+nY_ProgressBar, nWidth_ProgressBar, nHeight_ProgressBar, 15 );
689 
690  m_a3DLine.X = nDx+nX_Topic_Top;
691  m_a3DLine.Y = nDy+nY_Topic_Bottom+nHeight_Topic_Bottom+(PROGRESSMONITOR_FREEBORDER/2);
692  m_a3DLine.Width = nWidth_ProgressBar;
693  m_a3DLine.Height = nHeight_ProgressBar;
694 
695  // All childcontrols make an implicit repaint in setPosSize()!
696  // Make it also for this 3D-line ...
697  css::uno::Reference< XGraphics > xGraphics = impl_getGraphicsPeer ();
698 
699  xGraphics->setLineColor ( PROGRESSMONITOR_LINECOLOR_SHADOW );
700  xGraphics->drawLine ( m_a3DLine.X, m_a3DLine.Y, m_a3DLine.X+m_a3DLine.Width, m_a3DLine.Y );
701 
702  xGraphics->setLineColor ( PROGRESSMONITOR_LINECOLOR_BRIGHT );
703  xGraphics->drawLine ( m_a3DLine.X, m_a3DLine.Y+1, m_a3DLine.X+m_a3DLine.Width, m_a3DLine.Y+1 );
704 }
705 
706 // private method
708 {
709  // Ready for multithreading
710  MutexGuard aGuard ( m_aMutex );
711 
712  // Rebuild fixedtext before progress
713 
714  // Rebuild left site of text
715  if (m_xTopic_Top.is())
716  {
717  OUStringBuffer aCollectString;
718 
719  // Collect all topics from list and format text.
720  // "\n" MUST BE at the end of line!!! => Else ... topic and his text are not in the same line!!!
721  for (auto const & rSearchItem : maTextlist_Top)
722  {
723  aCollectString.append(rSearchItem.sTopic + "\n");
724  }
725 
726  m_xTopic_Top->setText ( aCollectString.makeStringAndClear() );
727  }
728 
729  // Rebuild right site of text
730  if (m_xText_Top.is())
731  {
732  OUStringBuffer aCollectString;
733 
734  // Collect all topics from list and format text.
735  // "\n" MUST BE at the end of line!!! => Else ... topic and his text are not in the same line!!!
736  for (auto const & rSearchItem : maTextlist_Top)
737  {
738  aCollectString.append(rSearchItem.sText + "\n");
739  }
740 
741  m_xText_Top->setText ( aCollectString.makeStringAndClear() );
742  }
743 
744  // Rebuild fixedtext below progress
745 
746  // Rebuild left site of text
747  if (m_xTopic_Bottom.is())
748  {
749  OUStringBuffer aCollectString;
750 
751  // Collect all topics from list and format text.
752  // "\n" MUST BE at the end of line!!! => Else ... topic and his text are not in the same line!!!
753  for (auto const & rSearchItem : maTextlist_Bottom)
754  {
755  aCollectString.append(rSearchItem.sTopic + "\n");
756  }
757 
758  m_xTopic_Bottom->setText ( aCollectString.makeStringAndClear() );
759  }
760 
761  // Rebuild right site of text
762  if (!m_xText_Bottom.is())
763  return;
764 
765  OUStringBuffer aCollectString;
766 
767  // Collect all topics from list and format text.
768  // "\n" MUST BE at the end of line!!! => Else ... topic and his text are not in the same line!!!
769  for (auto const & rSearchItem : maTextlist_Bottom)
770  {
771  aCollectString.append(rSearchItem.sText + "\n");
772  }
773 
774  m_xText_Bottom->setText ( aCollectString.makeStringAndClear() );
775 }
776 
777 // private method
779 {
780  // Ready for multithreading
781  MutexGuard aGuard ( m_aMutex );
782 
783  // Delete all of lists.
784  maTextlist_Top.clear();
785  maTextlist_Bottom.clear();
786 }
787 
788 // private method
789 IMPL_TextlistItem* ProgressMonitor::impl_searchTopic ( std::u16string_view rTopic, bool bbeforeProgress )
790 {
791  // Get right textlist for following operations.
792  ::std::vector< IMPL_TextlistItem >* pTextList;
793 
794  if (bbeforeProgress)
795  {
796  pTextList = &maTextlist_Top;
797  }
798  else
799  {
800  pTextList = &maTextlist_Bottom;
801  }
802 
803  // Search the topic in textlist.
804  size_t nPosition = 0;
805  size_t nCount = pTextList->size();
806 
807  for ( nPosition = 0; nPosition < nCount; ++nPosition )
808  {
809  auto& rSearchItem = pTextList->at( nPosition );
810 
811  if ( rSearchItem.sTopic == rTopic )
812  {
813  // We have found this topic... return a valid pointer.
814  return &rSearchItem;
815  }
816  }
817 
818  // We haven't found this topic... return a nonvalid pointer.
819  return nullptr;
820 }
821 
822 // debug methods
823 
824 // addText, updateText
826  std::u16string_view rTopic,
827  std::u16string_view rText
828 ) {
829  if ( rTopic.empty() ) return false; // ""
830 
831  if ( rText.empty() ) return false; // ""
832 
833  // Parameter OK ... return true.
834  return true;
835 }
836 
837 // removeText
838 bool ProgressMonitor::impl_debug_checkParameter ( std::u16string_view rTopic )
839 {
840  if ( rTopic.empty() ) return false; // ""
841 
842  // Parameter OK ... return true.
843  return true;
844 }
845 
846 } // namespace unocontrols
847 
848 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
850  css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const&)
851 {
852  return cppu::acquire(new unocontrols::ProgressMonitor(context));
853 }
854 /* 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
virtual void SAL_CALL acquire() noexcept override
increment refcount XInterface release() A RuntimeException is thrown.
Definition: basecontrol.cxx:91
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
constexpr OUStringLiteral FIXEDTEXT_MODELNAME
#define PROGRESSMONITOR_LINECOLOR_SHADOW
OUString sText
Left site of textline in dialog.
virtual void SAL_CALL release() noexcept override
decrement refcount XInterface acquire() A RuntimeException is thrown.
#define PROGRESSMONITOR_DEFAULT_WIDTH
css::uno::Reference< css::awt::XFixedText > m_xTopic_Bottom
virtual ~ProgressMonitor() override
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
constexpr OUStringLiteral CONTROLNAME_PROGRESSBAR
virtual void SAL_CALL setValue(sal_Int32 nValue) override
constexpr tools::Long Width() const
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
::std::vector< IMPL_TextlistItem > maTextlist_Top
virtual sal_Bool SAL_CALL setModel(const css::uno::Reference< css::awt::XControlModel > &xModel) override
#define DBG_ASSERT(sCon, aError)
static bool impl_debug_checkParameter(std::u16string_view sTopic, std::u16string_view sText)
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
IMPL_TextlistItem * impl_searchTopic(std::u16string_view sTopic, bool bbeforeProgress)
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
virtual void SAL_CALL acquire() noexcept override
increment refcount XInterface release() A RuntimeException is thrown.
sal_Int32 impl_getWidth() const
virtual void SAL_CALL release() noexcept override
decrement refcount XInterface acquire() A RuntimeException is thrown.
float u
unsigned char sal_Bool
virtual void SAL_CALL addControl(const OUString &sName, const css::uno::Reference< css::awt::XControl > &xControl) override
constexpr OUStringLiteral BUTTON_SERVICENAME
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).
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
constexpr OUStringLiteral BUTTON_MODELNAME
css::uno::Reference< css::awt::XFixedText > m_xText_Bottom
constexpr OUStringLiteral CONTROLNAME_TEXT
css::uno::Reference< css::awt::XButton > m_xButton
constexpr OUStringLiteral CONTROLNAME_BUTTON
oslInterlockedCount m_refCount
constexpr tools::Long Height() const
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
const css::uno::Reference< css::uno::XInterface > & impl_getDelegator() const
void * p
virtual css::uno::Reference< css::awt::XControlModel > SAL_CALL getModel() override
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
virtual void SAL_CALL setBackgroundColor(sal_Int32 nColor) override
virtual void SAL_CALL setRange(sal_Int32 nMin, sal_Int32 nMax) override
constexpr OUStringLiteral DEFAULT_BUTTONLABEL
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
css::uno::Any SAL_CALL queryInterface(const css::uno::Type &rType, Interface1 *p1)
rtl::Reference< ProgressBar > m_xProgressBar
constexpr OUStringLiteral FIXEDTEXT_SERVICENAME
virtual void SAL_CALL removeActionListener(const css::uno::Reference< css::awt::XActionListener > &xListener) override
::std::vector< IMPL_TextlistItem > maTextlist_Bottom