-// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
-//
+// Copyright (C) 2007-2014 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License.
-//
-// This library is distributed in the hope that it will be useful
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
-// See http://www.salome-platform.org/
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+// File: QtxLogoMgr.cxx
+// Author: Sergey TELKOV
//
#include "QtxLogoMgr.h"
-#include <qhbox.h>
-#include <qlabel.h>
-#include <qstyle.h>
-#include <qimage.h>
-#include <qbitmap.h>
-#include <qlayout.h>
-#include <qmenubar.h>
-#include <qapplication.h>
+#include <QLabel>
+#include <QImage>
+#include <QBitmap>
+#include <QHBoxLayout>
+#include <QMenuBar>
+#include <QPointer>
+#include <QApplication>
+#include <QMovie>
+
+/*!
+ \class QtxLogoMgr::LogoBox
+ \internal
+ \brief Logo images container.
+*/
+
+class QtxLogoMgr::LogoBox : public QWidget
+{
+public:
+ LogoBox( QMenuBar* );
+
+ QMenuBar* menuBar() const;
+ virtual bool eventFilter( QObject*, QEvent* );
+ void setLabels( const QList<QLabel*>& );
+
+protected:
+ virtual void customEvent( QEvent* );
+
+private:
+ void updateCorner();
+ void updateContents();
+
+private:
+ typedef QPointer<QWidget> WidgetPtr;
+
+private:
+ QMenuBar* myMB; //!< parent menu bar
+ QList<QLabel*> myLabels; //!< list of labels containing logo images
+ WidgetPtr myCornWid; //!< corner widget
+};
+
+/*!
+ \brief Constructor.
+ \param mb menu bar
+*/
+QtxLogoMgr::LogoBox::LogoBox( QMenuBar* mb )
+: QWidget( mb ),
+ myMB( mb ),
+ myCornWid( 0 )
+{
+ myMB->installEventFilter( this );
+ updateCorner();
+}
+
+/*!
+ \brief Get menu bar.
+ \return menu bar
+*/
+QMenuBar* QtxLogoMgr::LogoBox::menuBar() const
+{
+ return myMB;
+}
+
+/*!
+ \brief Custom event filter.
+ \param o event receiver object
+ \param e event sent to object
+ \return \c true if further event processing should be stopped
+*/
+bool QtxLogoMgr::LogoBox::eventFilter( QObject* o, QEvent* e )
+{
+ if ( o != menuBar() )
+ return false;
+
+ if ( e->type() == QEvent::MenubarUpdated || e->type() == QEvent::Resize )
+ updateCorner();
+
+ if ( e->type() == QEvent::ChildAdded || e->type() == QEvent::ChildRemoved )
+ {
+ updateCorner();
+ QApplication::postEvent( this, new QEvent( QEvent::User ) );
+ }
+
+ return false;
+}
+
+/*!
+ \brief Set label widgets (logo containers).
+ \param labs list of labels
+*/
+void QtxLogoMgr::LogoBox::setLabels( const QList<QLabel*>& labs )
+{
+ for ( QList<QLabel*>::iterator it = myLabels.begin(); it != myLabels.end(); ++it )
+ {
+ if ( !labs.contains( *it ) )
+ delete *it;
+ }
+
+ myLabels = labs;
+ updateContents();
+}
+
+/*!
+ \brief Custom event processing (update logo widget).
+ \param e event (not used)
+*/
+void QtxLogoMgr::LogoBox::customEvent( QEvent* /*e*/ )
+{
+ updateCorner();
+}
+
+/*!
+ \brief Update menu bar's corner widget.
+*/
+void QtxLogoMgr::LogoBox::updateCorner()
+{
+ if ( menuBar()->cornerWidget() == this )
+ return;
+
+ myCornWid = menuBar()->cornerWidget();
+ myMB->setCornerWidget( this );
+ updateContents();
+}
+
+/*!
+ \brief Update logo manager contents.
+*/
+void QtxLogoMgr::LogoBox::updateContents()
+{
+ if ( layout() )
+ delete layout();
+
+ QHBoxLayout* base = new QHBoxLayout( this );
+ base->setMargin( 0 );
+ base->setSpacing( 3 );
+
+ for ( QList<QLabel*>::const_iterator it = myLabels.begin(); it != myLabels.end(); ++it )
+ base->addWidget( *it );
+
+ if ( myCornWid )
+ base->addWidget( myCornWid );
+
+ QApplication::sendPostedEvents();
+}
+
+/*!
+ \class QtxLogoMgr
+ \brief Provides a way to install logo pictures to the application main window.
+
+ The class includes the following functionality:
+ - add the logo image
+ - remove logo image
+ - support static images and animated images (QMovie)
+ - start/stop and pause/resume the animated logos
+*/
/*!
- Constructor
+ \brief Constructor.
+ \param mb parent menu bar
*/
QtxLogoMgr::QtxLogoMgr( QMenuBar* mb )
-: QObject( mb ),
-myMenus( mb ),
-myId( 0 )
+: QObject( mb )
{
+ myBox = new LogoBox( mb );
}
/*!
- Destructor
+ \brief Destructor.
*/
QtxLogoMgr::~QtxLogoMgr()
{
}
/*!
- Returns the menubar.
+ \brief Get menu bar.
+ \return parent menu bar
*/
QMenuBar* QtxLogoMgr::menuBar() const
{
- return myMenus;
+ return myBox->menuBar();
}
/*!
- Returns the count of the existed logos.
+ \brief Get number of logo images.
+ \return current number of logo images
*/
int QtxLogoMgr::count() const
{
}
/*!
- Insert new logo to the menu bar area
+ \brief Insert new logo pixmap to the menu bar area.
+ \param id unique string identifier of the logo
+ \param pix logo pixmap
+ \param index logo position (if < 0, logo is added to the end)
*/
void QtxLogoMgr::insert( const QString& id, const QPixmap& pix, const int index )
{
if ( pix.isNull() )
return;
- LogoInfo* inf = 0;
+ LogoInfo& inf = insert( id, index );
+
+ inf.pix = pix;
+
+ generate();
+}
+
+/*!
+ \brief Insert new animated logo to the menu bar area.
+ \param id unique string identifier of the logo
+ \param pix logo movie
+ \param index logo position (if < 0, logo is added to the end)
+*/
+void QtxLogoMgr::insert( const QString& id, QMovie* movie, const int index )
+{
+ if ( !movie )
+ return;
+
+ LogoInfo& inf = insert( id, index );
+
+ inf.mov = movie;
+ movie->setParent( this );
+ movie->setCacheMode( QMovie::CacheAll );
+ movie->jumpToFrame( 0 );
+
+ generate();
+}
+
+/*!
+ \brief Insert new logo information structure into the logos list.
+ \param id unique string identifier of the logo
+ \param index logo position (if < 0, logo is added to the end)
+ \return logo information object
+*/
+QtxLogoMgr::LogoInfo& QtxLogoMgr::insert( const QString& id, const int index )
+{
+ LogoInfo empty;
+ empty.id = id;
+ empty.mov = 0;
int idx = find( id );
if ( idx < 0 )
{
idx = index < (int)myLogos.count() ? index : -1;
if ( idx < 0 )
- inf = &( *myLogos.append( LogoInfo() ) );
+ {
+ myLogos.append( empty );
+ idx = myLogos.count() - 1;
+ }
else
- inf = &( *myLogos.insert( myLogos.at( idx ), LogoInfo() ) );
+ myLogos.insert( idx, empty );
}
- else
- inf = &( *myLogos.at( idx ) );
+ LogoInfo& inf = myLogos[idx];
- inf->id = id;
- inf->pix = pix;
-
- generate();
+ return inf;
}
/*!
- Removes a logo
+ \brief Remove a logo.
+ \param id logo identifier
*/
void QtxLogoMgr::remove( const QString& id )
{
if ( idx < 0 )
return;
- myLogos.remove( myLogos.at( idx ) );
+ myLogos.removeAt( idx );
generate();
}
/*!
- Removes all logos
+ \brief Removes all logos.
*/
void QtxLogoMgr::clear()
{
}
/*!
- Inserts logo to menu bar
+ \brief Start the animation of movie logo.
+
+ If \a id is empty, all movie logos animation are started.
+
+ \param id logo identifier
*/
-void QtxLogoMgr::generate()
+void QtxLogoMgr::startAnimation( const QString& id )
{
- if ( !menuBar() )
- return;
+ QList<QMovie*> movList;
+ movies( id, movList );
- if ( myId )
- menuBar()->removeItem( myId );
+ for ( QList<QMovie*>::iterator it = movList.begin(); it != movList.end(); ++it )
+ (*it)->start();
+}
- myId = 0;
+/*!
+ \brief Stop the animation of movie logo.
- if ( myLogos.isEmpty() )
- return;
+ If \a id is empty, all movie logos animation are stopped.
- class LogoBox : public QHBox
- {
- public:
- LogoBox( QWidget* parent = 0, const char* name = 0, WFlags f = 0 ) : QHBox( parent, name, f ) {};
+ \param id logo identifier
+*/
+void QtxLogoMgr::stopAnimation( const QString& id )
+{
+ QList<QMovie*> movList;
+ movies( id, movList );
- void addSpacing( int spacing )
- {
- QApplication::sendPostedEvents( this, QEvent::ChildInserted );
- ((QHBoxLayout*)layout())->addSpacing( spacing );
- }
+ for ( QList<QMovie*>::iterator it = movList.begin(); it != movList.end(); ++it )
+ (*it)->stop();
+}
- protected:
- void drawContents( QPainter* p )
- {
- if ( parentWidget()->inherits( "QMenuBar" ) )
- style().drawControl( QStyle::CE_MenuBarEmptyArea, p, this, contentsRect(), colorGroup() );
- else
- QHBox::drawContents( p );
- }
- };
+/*!
+ \brief Pause/resume the animation of movie logo.
+
+ If \a pause is \c true, the animation is paused; otherwise
+ it is resumed.
+
+ If \a id is empty, the operation is performed for all movis logos.
- LogoBox* cnt = new LogoBox( menuBar() );
- cnt->setSpacing( 3 );
+ \param pause if \c true, pause animation, otherwise resume it
+ \param id logo identifier
+*/
+void QtxLogoMgr::pauseAnimation( const bool pause, const QString& id )
+{
+ QList<QMovie*> movList;
+ movies( id, movList );
+
+ for ( QList<QMovie*>::iterator it = movList.begin(); it != movList.end(); ++it )
+ (*it)->setPaused( pause );
+}
+
+/*!
+ \brief Regenerate logo manager widget contents.
+
+ Insert logo to menu bar if it not yet done, layout the widget.
+*/
+void QtxLogoMgr::generate()
+{
+ if ( !menuBar() )
+ return;
+ QList<QLabel*> labels;
for ( LogoList::const_iterator it = myLogos.begin(); it != myLogos.end(); ++it )
{
QPixmap pix = (*it).pix;
- if ( !pix.mask() )
+ QMovie* mov = (*it).mov;
+ if ( !pix.isNull() && !pix.mask() )
{
- QImage img = pix.convertToImage();
QBitmap bm;
- if ( img.hasAlphaBuffer() )
- bm = img.createAlphaMask();
+ QImage img = pix.toImage();
+ if ( img.hasAlphaChannel() )
+ bm = QPixmap::fromImage( img.createAlphaMask() );
else
- bm = img.createHeuristicMask();
+ bm = QPixmap::fromImage( img.createHeuristicMask() );
pix.setMask( bm );
}
- QLabel* logoLab = new QLabel( cnt );
- logoLab->setPixmap( (*it).pix );
+ QLabel* logoLab = new QLabel( myBox );
+ if ( mov )
+ logoLab->setMovie( mov );
+ else
+ {
+ logoLab->setPixmap( (*it).pix );
+// if ( !pix.mask().isNull() )
+// logoLab->setMask( pix.mask() );
+ }
+
logoLab->setScaledContents( false );
- logoLab->setAlignment( QLabel::AlignCenter );
+ logoLab->setAlignment( Qt::AlignCenter );
- if ( pix.mask() )
- logoLab->setMask( *pix.mask() );
+ labels.append( logoLab );
}
- QApplication::sendPostedEvents( cnt, QEvent::ChildInserted );
- cnt->addSpacing( 2 );
-
- myId = menuBar()->insertItem( cnt );
-
- QApplication::sendPostedEvents( menuBar()->parentWidget(), QEvent::LayoutHint );
- QApplication::postEvent( menuBar()->parentWidget(), new QEvent( QEvent::LayoutHint ) );
+ myBox->setLabels( labels );
}
/*!
- \return index of found logo
- \param id - logo id
+ \brief Search the logo by the specified \a id.
+ \param id logo identifier
+ \return index of logo or -1 if not found
*/
int QtxLogoMgr::find( const QString& id ) const
{
int idx = -1;
- for ( uint i = 0; i < myLogos.count() && idx < 0; i++ )
+ for ( int i = 0; i < myLogos.count() && idx < 0; i++ )
{
- if ( (*myLogos.at( i ) ).id == id )
+ if ( myLogos.at( i ).id == id )
idx = i;
}
return idx;
}
+
+/*!
+ \brief Get movie logos by specified \a id.
+
+ If \a id is empty, all movie logos are returned.
+
+ \param id logo identifier
+ \param lst list of movies, which satisfy the \a id
+*/
+void QtxLogoMgr::movies( const QString& id, QList<QMovie*>& lst ) const
+{
+ lst.clear();
+ for ( LogoList::const_iterator it = myLogos.begin(); it != myLogos.end(); ++it )
+ {
+ if ( (*it).mov && ( id.isEmpty() || id == (*it).id ) )
+ lst.append( (*it).mov );
+ }
+}