-// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
-//
+// Copyright (C) 2007-2020 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/ or email : webmaster.salome@opencascade.com
//
+
// File: QtxGroupBox.cxx
// Author: Sergey TELKOV
-
+//
#include "QtxGroupBox.h"
-#include <qhbox.h>
-#include <qlayout.h>
-#include <qtoolbutton.h>
-#include <qapplication.h>
-#include <qobjectlist.h>
+#include <QVBoxLayout>
+#include <QHBoxLayout>
+#include <QEvent>
+#include <QObjectList>
+#include <QApplication>
/*!
- Constructor
-*/
-QtxGroupBox::QtxGroupBox( QWidget* parent, const char* name )
-: QGroupBox( parent, name ),
-myContainer( 0 )
-{
-}
+ \class QtxGroupBox
+ \brief Enhanced group box widget.
-/*!
- Constructor
+ The QtxGroupBox class allows inserting custom widgets in the
+ group box title. Use insertTitleWidget() method to add
+ custom widget to the title and removeTitleWidget() to remove it.
*/
-QtxGroupBox::QtxGroupBox( const QString& title, QWidget* parent, const char* name )
-: QGroupBox( title, parent, name ),
-myContainer( 0 )
-{
- initialize();
-}
/*!
- Constructor
+ \brief Constructor.
+ \param parent parent widget
*/
-QtxGroupBox::QtxGroupBox( int strips, Orientation o, QWidget* parent, const char* name )
-: QGroupBox( strips, o, parent, name ),
-myContainer( 0 )
+QtxGroupBox::QtxGroupBox( QWidget* parent )
+: QGroupBox( parent ),
+ myContainer( 0 )
{
initialize();
}
/*!
- Constructor
+ \brief Constructor.
+ \param title group box title text
+ \param parent parent widget
*/
-QtxGroupBox::QtxGroupBox( int strips, Orientation o, const QString& title,
- QWidget* parent, const char* name )
-: QGroupBox( strips, o, title, parent, name ),
-myContainer( 0 )
+QtxGroupBox::QtxGroupBox( const QString& title, QWidget* parent )
+: QGroupBox( title, parent ),
+ myContainer( 0 )
{
initialize();
}
/*!
- Destructor
+ \brief Destructor.
*/
QtxGroupBox::~QtxGroupBox()
{
- delete myContainer;
}
/*!
- Creates horizontal box as container
+ \brief Initialize the group box.
+
+ Creates horizontal box as container for title widgets.
*/
void QtxGroupBox::initialize()
{
- myContainer = new QHBox( this, 0, WStyle_Customize | WStyle_NoBorderEx | WStyle_Tool );
+ myContainer = new QWidget( this );
+ QHBoxLayout* base = new QHBoxLayout( myContainer );
+ base->setMargin( 0 );
+ base->setSpacing( 0 );
updateTitle();
}
-#if QT_VER < 3
-
-/*!
- \return the width of the empty space between the items in the group and the frame of the group
-*/
-int QtxGroupBox::insideMargin() const
-{
- int m = 0;
- if ( layout() )
- m = layout()->margin();
- return m;
-}
-
-/*!
- \return the width of the empty space between each of the items in the group
-*/
-int QtxGroupBox::insideSpacing() const
-{
- int s = 0;
- if ( layout() )
- s = layout()->spacing();
- return s;
-}
-
-/*!
- Sets the width of the empty space between the items in the group and the frame of the group
-*/
-void QtxGroupBox::setInsideMargin( int m )
-{
- if ( layout() )
- layout()->setMargin( m );
-}
-
-/*!
- Sets the width of the empty space between each of the items in the group
-*/
-void QtxGroupBox::setInsideSpacing( int s )
-{
- if ( layout() )
- layout()->setSpacing( s );
-}
-
-#endif
-
/*!
- Inserts title widget
- \param wid - new title widget
+ \brief Add widget to the group box title.
+ \param wid widget being added to the title
*/
void QtxGroupBox::insertTitleWidget( QWidget* wid )
{
if ( !myContainer )
return;
- wid->reparent( myContainer, QPoint( 0, 0 ), true );
+ myContainer->layout()->addWidget( wid );
wid->installEventFilter( this );
updateTitle();
}
/*!
- Removes title widget
- \param wid - title widget
+ \brief Remove widget from the group box title.
+ \param wid widget to be removed from the title
*/
void QtxGroupBox::removeTitleWidget( QWidget* wid )
{
if ( !myContainer || wid->parentWidget() != myContainer )
return;
- wid->reparent( 0, QPoint( 0, 0 ), false );
+ myContainer->layout()->removeWidget( wid );
+ wid->setParent( 0 );
wid->removeEventFilter( this );
+ wid->hide();
updateTitle();
}
/*!
- Calculates margin
-*/
-void QtxGroupBox::adjustInsideMargin()
-{
- QApplication::sendPostedEvents( myContainer, QEvent::ChildInserted );
-
- myContainer->resize( myContainer->minimumSizeHint() );
-
- setInsideMargin( myContainer->height() );
-}
-
-/*!
- Sets the alignment of the group box title
+ \brief Show/hide group box.
+ \param on if \c true, show group box, otherwise, hide it
*/
-void QtxGroupBox::setAlignment( int align )
+void QtxGroupBox::setVisible( bool on )
{
- QGroupBox::setAlignment( align );
+ if ( on )
+ updateTitle();
- updateTitle();
+ QGroupBox::setVisible( on );
}
/*!
- Sets title of groop box
+ \brief Get recommended size for the widget.
+ \return recommended size for the widget
*/
-void QtxGroupBox::setTitle( const QString& title )
+QSize QtxGroupBox::sizeHint() const
{
- QGroupBox::setTitle( title );
-
- updateTitle();
+ return expandTo( QGroupBox::sizeHint() );
}
/*!
- Changes the layout of the group box
- \param strips - number of column/rows
- \param o - orientation
+ \brief Get recommended minimum size for the widget.
+ \return recommended minimum size for the widget
*/
-void QtxGroupBox::setColumnLayout( int strips, Orientation o )
+QSize QtxGroupBox::minimumSizeHint() const
{
- if ( myContainer )
- myContainer->reparent( 0, QPoint( 0, 0 ), false );
-
- QGroupBox::setColumnLayout( strips, o );
-
- if ( myContainer )
- myContainer->reparent( this, QPoint( 0, 0 ), false );
-
- updateTitle();
+ return expandTo( QGroupBox::minimumSizeHint() );
}
/*!
- Shows group box
+ \brief Custom event filter.
+ \param obj event receiver
+ \param e event
+ \return \c true if event processing should be stopped
*/
-void QtxGroupBox::show()
+bool QtxGroupBox::eventFilter( QObject* obj, QEvent* e )
{
- QGroupBox::show();
+ QEvent::Type type = e->type();
+ if ( myContainer && obj->parent() == myContainer &&
+ ( type == QEvent::Show || type == QEvent::ShowToParent ||
+ type == QEvent::Hide || type == QEvent::HideToParent ) )
+ QApplication::postEvent( this, new QEvent( QEvent::User ) );
- updateTitle();
+ return QGroupBox::eventFilter( obj, e );
}
-
/*!
- Updates group box
+ \brief Get central widget (or first found one).
+ \return widget
*/
-void QtxGroupBox::update()
+QWidget* QtxGroupBox::widget() const
{
- QGroupBox::update();
+ if ( !layout() )
+ return 0;
- updateTitle();
+ QWidget* w = 0;
+ for ( int i = 0; i < (int)layout()->count() && !w; i++ )
+ w = layout()->itemAt( i )->widget();
+ return w;
}
/*!
- \return the recommended size for the widget
+ \brief Set central widget to the group box.
+ \param wid widget being added to the group box
*/
-QSize QtxGroupBox::sizeHint() const
+void QtxGroupBox::setWidget( QWidget* wid )
{
- QSize sz = QGroupBox::sizeHint();
-
- int sw = titleSize().width();
-
- if ( myContainer )
- {
- if ( alignment() == AlignCenter )
- sw += 2 * ( myContainer->width() + 5 );
- else
- sw += 1 * ( myContainer->width() + 5 );
- }
-
- sw += frameRect().left();
-
- return QSize( QMAX( sz.width(), sw ), sz.height() );
-}
-
-/*!
- \return the recommended minimum size for the widget
-*/
-QSize QtxGroupBox::minimumSizeHint() const
-{
- QSize sz = QGroupBox::minimumSizeHint();
+ QWidget* w = widget();
+ if ( w == wid )
+ return;
- int sw = titleSize().width() + myContainer ? myContainer->width() + 5 : 0;
+ if ( layout() )
+ layout()->removeWidget( w );
- if ( myContainer )
+ if ( !wid )
+ delete layout();
+ else if ( !layout() )
{
- if ( alignment() == AlignCenter )
- sw += 2 * ( myContainer->width() + 5 );
- else
- sw += 1 * ( myContainer->width() + 5 );
+ QLayout* bl = new QVBoxLayout( this );
+ bl->setMargin( 0 );
+ bl->setSpacing( 0 );
}
- sw += frameRect().left();
-
- return QSize( QMAX( sz.width(), sw ), sz.height() );
-}
-
-/*!
- Custom event filter
-*/
-bool QtxGroupBox::eventFilter( QObject* obj, QEvent* e )
-{
- QEvent::Type type = e->type();
- if ( myContainer && obj->parent() == myContainer &&
- ( type == QEvent::Show || type == QEvent::ShowToParent ||
- type == QEvent::Hide || type == QEvent::HideToParent ) )
- QApplication::postEvent( this, new QCustomEvent( QEvent::User ) );
+ if ( layout() )
+ layout()->addWidget( wid );
- return QGroupBox::eventFilter( obj, e );
+ if ( wid )
+ wid->updateGeometry();
}
/*!
- Custom resize event filter
+ \brief Customize resize event.
+ \param e resize event
*/
void QtxGroupBox::resizeEvent( QResizeEvent* e )
{
}
/*!
- Custom child event filter
+ \brief Customize child event.
+ \param e child event
*/
void QtxGroupBox::childEvent( QChildEvent* e )
{
- if ( e->type() == QEvent::ChildInserted && e->child() == myContainer )
+/*
+ if ( e->type() == QEvent::ChildAdded && e->child() == myContainer )
return;
-
- QGroupBox::childEvent( e );
-}
-
-/*!
- Event filter of custom items
*/
-void QtxGroupBox::customEvent( QCustomEvent* )
-{
- updateTitle();
+ QGroupBox::childEvent( e );
}
/*!
- On frame changed
+ \brief Process custom events.
+ \param e custom event (not used)
*/
-void QtxGroupBox::frameChanged()
+void QtxGroupBox::customEvent( QEvent* /*e*/ )
{
updateTitle();
}
/*!
- \return size of title
+ \brief Get the group box title size.
+ \return title size
*/
QSize QtxGroupBox::titleSize() const
{
- QSize sz( 0, 0 );
-
- if ( layout() )
- {
- QSpacerItem* si = 0;
- for ( QLayoutIterator it = layout()->iterator(); it.current() && !si; ++it )
- si = it.current()->spacerItem();
- if ( si )
- sz = si->sizeHint();
- }
-
- int w = sz.width();
- int h = sz.height() + insideMargin();
-
- return QSize( w, h );
+ return QSize( fontMetrics().width( title() ), fontMetrics().height() );
}
/*!
- Updates title
+ \brief Update the group box title.
*/
void QtxGroupBox::updateTitle()
{
return;
int align = alignment();
- if ( align == AlignAuto )
- align = QApplication::reverseLayout() ? AlignRight : AlignLeft;
if ( title().isEmpty() )
- align = AlignRight;
+ align = Qt::AlignRight;
QSize ts = titleSize();
int m = 5;
- int w = frameRect().width() - ts.width();
- if ( align == AlignCenter )
+ int w = width() - ts.width();
+ if ( align == Qt::AlignCenter )
w = w / 2;
w -= m;
- QApplication::sendPostedEvents( myContainer, QEvent::ChildInserted );
myContainer->resize( myContainer->minimumSizeHint() );
bool vis = false;
- const QObjectList* list = myContainer->children();
- if ( list )
- {
- for ( QObjectListIt it( *list ); it.current() && !vis; ++it )
- vis = it.current()->isWidgetType() &&
- ((QWidget*)it.current())->isVisibleTo( myContainer );
- }
+ const QObjectList list = myContainer->children();
+ for ( QObjectList::const_iterator it = list.begin(); it != list.end() && !vis; ++it )
+ vis = (*it)->isWidgetType() && ((QWidget*)(*it))->isVisibleTo( myContainer );
- if ( myContainer->height() > ts.height() || myContainer->width() > w || !vis )
+ if ( !vis )
myContainer->hide();
else
{
int x = 0;
- if ( align == AlignRight )
- x = frameRect().left() + m;
+ if ( align == Qt::AlignRight )
+ x = rect().left() + m;
else
- x = frameRect().right() - myContainer->width() - m;
+ x = rect().right() - myContainer->width() - m;
- int y = frameRect().top() - ( myContainer->height() - frameWidth() ) / 2;
+ int y = rect().top() - ( myContainer->height() - ts.height() ) / 2;
- QPoint pos( x, QMAX( 0, y ) );
- pos = mapToGlobal( pos );
- if ( myContainer->parentWidget() )
- pos = myContainer->parentWidget()->mapFromGlobal( pos );
+ QPoint pos( x, qMax( 0, y ) );
myContainer->move( pos );
myContainer->show();
}
+ if ( layout() )
+ {
+ if ( myContainer && myContainer->isVisibleTo( this ) )
+ setInsideMargin( qMax( 0, myContainer->height() - ts.height() ) );
+ else
+ setInsideMargin( 0 );
+ }
+
updateGeometry();
}
+
+/*!
+ \brief Expand group box to the specified size.
+ \param sz new size
+*/
+QSize QtxGroupBox::expandTo( const QSize& sz ) const
+{
+ int sh = 0;
+ int sw = titleSize().width();
+ if ( myContainer && myContainer->isVisibleTo( (QWidget*)this ) )
+ {
+ if ( alignment() == Qt::AlignCenter )
+ sw += 2 * ( myContainer->width() + 5 );
+ else
+ sw += 1 * ( myContainer->width() + 5 );
+ sw += 20;
+ sh = myContainer->height() + 5;
+ }
+ return QSize( qMax( sz.width(), sw ), qMax( sz.height(), sh ) );
+}
+
+/*!
+ \brief Set group box's inside margin size.
+ \param m new inside margin size
+*/
+void QtxGroupBox::setInsideMargin( const int m )
+{
+ QVBoxLayout* bl = ::qobject_cast<QVBoxLayout*>( layout() );
+
+ if ( !bl )
+ return;
+
+ QSpacerItem* spacer = 0;
+ if ( bl->count() )
+ spacer = bl->itemAt( 0 )->spacerItem();
+
+ if ( !spacer )
+ bl->insertSpacing( 0, m );
+ else
+ spacer->changeSize( 0, m );
+}