Salome HOME
updated copyright message
[modules/gui.git] / src / Qtx / QtxLogoMgr.cxx
1 // Copyright (C) 2007-2023  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 // File:      QtxLogoMgr.cxx
24 // Author:    Sergey TELKOV
25 //
26 #include "QtxLogoMgr.h"
27
28 #include <QLabel>
29 #include <QImage>
30 #include <QBitmap>
31 #include <QHBoxLayout>
32 #include <QMenuBar>
33 #include <QPointer>
34 #include <QApplication>
35 #include <QMovie>
36
37 /*!
38   \class QtxLogoMgr::LogoBox
39   \internal
40   \brief Logo images container.
41 */
42
43 class QtxLogoMgr::LogoBox : public QWidget
44 {
45 public:
46   LogoBox( QMenuBar* );
47
48   QMenuBar*      menuBar() const;
49   virtual bool   eventFilter( QObject*, QEvent* );
50   void           setLabels( const QList<QLabel*>& );
51
52 protected:
53   virtual void   customEvent( QEvent* );
54
55 private:
56   void           updateCorner();
57   void           updateContents();
58
59 private:
60   typedef QPointer<QWidget> WidgetPtr;
61
62 private:
63   QMenuBar*      myMB;       //!< parent menu bar
64   QList<QLabel*> myLabels;   //!< list of labels containing logo images
65   WidgetPtr      myCornWid;  //!< corner widget
66 };
67
68 /*!
69   \brief Constructor.
70   \param mb menu bar
71 */
72 QtxLogoMgr::LogoBox::LogoBox( QMenuBar* mb )
73 : QWidget( mb ),
74   myMB( mb ),
75   myCornWid( 0 )
76 {
77   myMB->installEventFilter( this );
78   updateCorner();
79 }
80
81 /*!
82   \brief Get menu bar.
83   \return menu bar
84 */
85 QMenuBar* QtxLogoMgr::LogoBox::menuBar() const
86 {
87   return myMB;
88 }
89
90 /*!
91   \brief Custom event filter.
92   \param o event receiver object
93   \param e event sent to object
94   \return \c true if further event processing should be stopped
95 */
96 bool QtxLogoMgr::LogoBox::eventFilter( QObject* o, QEvent* e )
97 {
98   if ( o != menuBar() )
99     return false;
100
101   if ( e->type() == QEvent::Resize )
102     updateCorner();
103
104   if ( e->type() == QEvent::ChildAdded || e->type() == QEvent::ChildRemoved )
105   {
106     updateCorner();
107     QApplication::postEvent( this, new QEvent( QEvent::User ) );
108   }
109
110   return false;
111 }
112
113 /*!
114   \brief Set label widgets (logo containers).
115   \param labs list of labels
116 */
117 void QtxLogoMgr::LogoBox::setLabels( const QList<QLabel*>& labs )
118 {
119   for ( QList<QLabel*>::iterator it = myLabels.begin(); it != myLabels.end(); ++it )
120   {
121     if ( !labs.contains( *it ) )
122       delete *it;
123   }
124
125   myLabels = labs;
126   updateContents();
127 }
128
129 /*!
130   \brief Custom event processing (update logo widget).
131   \param e event (not used)
132 */
133 void QtxLogoMgr::LogoBox::customEvent( QEvent* /*e*/ )
134 {
135   updateCorner();
136 }
137
138 /*!
139   \brief Update menu bar's corner widget.
140 */
141 void QtxLogoMgr::LogoBox::updateCorner()
142 {
143   if ( menuBar()->cornerWidget() == this )
144     return;
145
146   myCornWid = menuBar()->cornerWidget();
147   myMB->setCornerWidget( this );
148   updateContents();
149 }
150
151 /*!
152   \brief Update logo manager contents.
153 */
154 void QtxLogoMgr::LogoBox::updateContents()
155 {
156   if ( layout() )
157     delete layout();
158
159   QHBoxLayout* base = new QHBoxLayout( this );
160   base->setMargin( 0 );
161   base->setSpacing( 3 );
162
163   for ( QList<QLabel*>::const_iterator it = myLabels.begin(); it != myLabels.end(); ++it )
164     base->addWidget( *it );
165
166   if ( myCornWid )
167     base->addWidget( myCornWid );
168
169   QApplication::sendPostedEvents();
170 }
171
172 /*!
173   \class QtxLogoMgr
174   \brief Provides a way to install logo pictures to the application main window.
175
176   The class includes the following functionality:
177   - add the logo image
178   - remove logo image
179   - support static images and animated images (QMovie)
180   - start/stop and pause/resume the animated logos
181 */
182
183 /*!
184   \brief Constructor.
185   \param mb parent menu bar
186 */
187 QtxLogoMgr::QtxLogoMgr( QMenuBar* mb )
188 : QObject( mb )
189 {
190   myBox = new LogoBox( mb );
191 }
192
193 /*!
194   \brief Destructor.
195 */
196 QtxLogoMgr::~QtxLogoMgr()
197 {
198 }
199
200 /*!
201   \brief Get menu bar.
202   \return parent menu bar
203 */
204 QMenuBar* QtxLogoMgr::menuBar() const
205 {
206   return myBox->menuBar();
207 }
208
209 /*!
210   \brief Get number of logo images.
211   \return current number of logo images
212 */
213 int QtxLogoMgr::count() const
214 {
215   return myLogos.count();
216 }
217
218 /*!
219   \brief Insert new logo pixmap to the menu bar area.
220   \param id unique string identifier of the logo
221   \param pix logo pixmap
222   \param index logo position (if < 0, logo is added to the end)
223 */
224 void QtxLogoMgr::insert( const QString& id, const QPixmap& pix, const int index )
225 {
226   if ( pix.isNull() )
227     return;
228
229   LogoInfo& inf = insert( id, index );
230
231   inf.pix = pix;
232
233   generate();
234 }
235
236 /*!
237   \brief Insert new animated logo to the menu bar area.
238   \param id unique string identifier of the logo
239   \param pix logo movie
240   \param index logo position (if < 0, logo is added to the end)
241 */
242 void QtxLogoMgr::insert( const QString& id, QMovie* movie, const int index )
243 {
244   if ( !movie )
245     return;
246
247   LogoInfo& inf = insert( id, index );
248
249   inf.mov = movie;
250   movie->setParent( this );
251   movie->setCacheMode( QMovie::CacheAll );
252   movie->jumpToFrame( 0 );
253
254   generate();
255 }
256
257 /*!
258   \brief Insert new logo information structure into the logos list.
259   \param id unique string identifier of the logo
260   \param index logo position (if < 0, logo is added to the end)
261   \return logo information object
262 */
263 QtxLogoMgr::LogoInfo& QtxLogoMgr::insert( const QString& id, const int index )
264 {
265   LogoInfo empty;
266   empty.id = id;
267   empty.mov = 0;
268
269   int idx = find( id );
270   if ( idx < 0 )
271   {
272     idx = index < (int)myLogos.count() ? index : -1;
273     if ( idx < 0 )
274     {
275       myLogos.append( empty );
276       idx = myLogos.count() - 1;
277     }
278     else
279       myLogos.insert( idx, empty );
280   }
281
282   LogoInfo& inf = myLogos[idx];
283
284   return inf;
285 }
286
287 /*!
288   \brief Remove a logo.
289   \param id logo identifier
290 */
291 void QtxLogoMgr::remove( const QString& id )
292 {
293   int idx = find( id );
294   if ( idx < 0 )
295     return;
296
297   myLogos.removeAt( idx );
298
299   generate();
300 }
301
302 /*!
303   \brief Removes all logos.
304 */
305 void QtxLogoMgr::clear()
306 {
307   myLogos.clear();
308   generate();
309 }
310
311 /*!
312   \brief Start the animation of movie logo.
313
314   If \a id is empty, all movie logos animation are started.
315
316   \param id logo identifier
317 */
318 void QtxLogoMgr::startAnimation( const QString& id )
319 {
320   QList<QMovie*> movList;
321   movies( id, movList );
322
323   for ( QList<QMovie*>::iterator it = movList.begin(); it != movList.end(); ++it )
324     (*it)->start();
325 }
326
327 /*!
328   \brief Stop the animation of movie logo.
329
330   If \a id is empty, all movie logos animation are stopped.
331
332   \param id logo identifier
333 */
334 void QtxLogoMgr::stopAnimation( const QString& id )
335 {
336   QList<QMovie*> movList;
337   movies( id, movList );
338
339   for ( QList<QMovie*>::iterator it = movList.begin(); it != movList.end(); ++it )
340     (*it)->stop();
341 }
342
343 /*!
344   \brief Pause/resume the animation of movie logo.
345
346   If \a pause is \c true, the animation is paused; otherwise
347   it is resumed.
348   
349   If \a id is empty, the operation is performed for all movis logos.
350
351   \param pause if \c true, pause animation, otherwise resume it
352   \param id logo identifier
353 */
354 void QtxLogoMgr::pauseAnimation( const bool pause, const QString& id )
355 {
356   QList<QMovie*> movList;
357   movies( id, movList );
358
359   for ( QList<QMovie*>::iterator it = movList.begin(); it != movList.end(); ++it )
360     (*it)->setPaused( pause );
361 }
362
363 /*!
364   \brief Regenerate logo manager widget contents.
365   
366   Insert logo to menu bar if it not yet done, layout the widget.
367 */
368 void QtxLogoMgr::generate()
369 {
370   if ( !menuBar() )
371     return;
372
373   QList<QLabel*> labels;
374   for ( LogoList::const_iterator it = myLogos.begin(); it != myLogos.end(); ++it )
375   {
376     QPixmap pix = (*it).pix;
377     QMovie* mov = (*it).mov;
378     if ( !pix.isNull() && !pix.mask() )
379     {
380       QBitmap bm;
381       QImage img = pix.toImage();
382       if ( img.hasAlphaChannel() )
383         bm = QPixmap::fromImage( img.createAlphaMask() );
384       else
385         bm = QPixmap::fromImage( img.createHeuristicMask() );
386       pix.setMask( bm );
387     }
388
389     QLabel* logoLab = new QLabel( myBox );
390     if ( mov )
391       logoLab->setMovie( mov );
392     else
393     {
394       logoLab->setPixmap( (*it).pix );
395 //      if ( !pix.mask().isNull() )
396 //          logoLab->setMask( pix.mask() );
397     }
398
399     logoLab->setScaledContents( false );
400     logoLab->setAlignment( Qt::AlignCenter );
401
402     labels.append( logoLab );
403   }
404
405   myBox->setLabels( labels );
406 }
407
408 /*!
409   \brief Search the logo by the specified \a id.
410   \param id logo identifier
411   \return index of logo or -1 if not found
412 */
413 int QtxLogoMgr::find( const QString& id ) const
414 {
415   int idx = -1;
416   for ( int i = 0; i < myLogos.count() && idx < 0; i++ )
417   {
418     if ( myLogos.at( i ).id == id )
419       idx = i;
420   }
421   return idx;
422 }
423
424 /*!
425   \brief Get movie logos by specified \a id.
426
427   If \a id is empty, all movie logos are returned.
428
429   \param id logo identifier
430   \param lst list of movies, which satisfy the \a id
431 */
432 void QtxLogoMgr::movies( const QString& id, QList<QMovie*>& lst ) const
433 {
434   lst.clear();
435   for ( LogoList::const_iterator it = myLogos.begin(); it != myLogos.end(); ++it )
436   {
437     if ( (*it).mov && ( id.isEmpty() || id == (*it).id ) )
438       lst.append( (*it).mov );
439   }
440 }