]> SALOME platform Git repositories - modules/gui.git/blob - src/Qtx/QtxGroupBox.cxx
Salome HOME
c6cccf4b363186e703808a4d7301ce7087ad8a5c
[modules/gui.git] / src / Qtx / QtxGroupBox.cxx
1 //  Copyright (C) 2007-2008  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.
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 // File:      QtxGroupBox.cxx
23 // Author:    Sergey TELKOV
24 //
25 #include "QtxGroupBox.h"
26
27 #include <QVBoxLayout>
28 #include <QHBoxLayout>
29 #include <QEvent>
30 #include <QObjectList>
31 #include <QApplication>
32
33 /*!
34   \class QtxGroupBox
35   \brief Enhanced group box widget.
36
37   The QtxGroupBox class allows inserting custom widgets in the 
38   group box title. Use insertTitleWidget() method to add
39   custom widget to the title and removeTitleWidget() to remove it.
40 */
41
42 /*!
43   \brief Constructor.
44   \param parent parent widget 
45 */
46 QtxGroupBox::QtxGroupBox( QWidget* parent )
47 : QGroupBox( parent ),
48   myContainer( 0 )
49 {
50   initialize();
51 }
52
53 /*!
54   \brief Constructor.
55   \param title group box title text
56   \param parent parent widget 
57 */
58 QtxGroupBox::QtxGroupBox( const QString& title, QWidget* parent )
59 : QGroupBox( title, parent ),
60   myContainer( 0 )
61 {
62   initialize();
63 }
64
65 /*!
66   \brief Destructor.
67 */
68 QtxGroupBox::~QtxGroupBox()
69 {
70 }
71
72 /*!
73   \brief Initialize the group box.
74
75   Creates horizontal box as container for title widgets.
76 */
77 void QtxGroupBox::initialize()
78 {
79   myContainer = new QWidget( this );
80   QHBoxLayout* base = new QHBoxLayout( myContainer );
81   base->setMargin( 0 );
82   base->setSpacing( 0 );
83
84   updateTitle();
85 }
86
87 /*!
88   \brief Add widget to the group box title.
89   \param wid widget being added to the title
90 */
91 void QtxGroupBox::insertTitleWidget( QWidget* wid )
92 {
93   if ( !myContainer )
94     return;
95
96   myContainer->layout()->addWidget( wid );
97   wid->installEventFilter( this );
98
99   updateTitle();
100 }
101
102 /*!
103   \brief Remove widget from the group box title.
104   \param wid widget to be removed from the title
105 */
106 void QtxGroupBox::removeTitleWidget( QWidget* wid )
107 {
108   if ( !myContainer || wid->parentWidget() != myContainer )
109     return;
110
111   myContainer->layout()->removeWidget( wid );
112   wid->setParent( 0 );
113   wid->removeEventFilter( this );
114   wid->hide();
115
116   updateTitle();
117 }
118
119 /*!
120   \brief Show/hide group box.
121   \param on if \c true, show group box, otherwise, hide it
122 */
123 void QtxGroupBox::setVisible( bool on )
124 {
125   if ( on )
126     updateTitle();
127
128   QGroupBox::setVisible( on );
129 }
130
131 /*!
132   \brief Get recommended size for the widget.
133   \return recommended size for the widget
134 */
135 QSize QtxGroupBox::sizeHint() const
136 {
137   return expandTo( QGroupBox::sizeHint() );
138 }
139
140 /*!
141   \brief Get recommended minimum size for the widget.
142   \return recommended minimum size for the widget
143 */
144 QSize QtxGroupBox::minimumSizeHint() const
145 {
146   return expandTo( QGroupBox::minimumSizeHint() );
147 }
148
149 /*!
150   \brief Custom event filter.
151   \param obj event receiver
152   \param e event
153   \return \c true if event processing should be stopped
154 */
155 bool QtxGroupBox::eventFilter( QObject* obj, QEvent* e )
156 {
157   QEvent::Type type = e->type();
158   if ( myContainer && obj->parent() == myContainer &&
159        ( type == QEvent::Show || type == QEvent::ShowToParent ||
160          type == QEvent::Hide || type == QEvent::HideToParent ) )
161     QApplication::postEvent( this, new QEvent( QEvent::User ) );
162
163   return QGroupBox::eventFilter( obj, e );
164 }
165 /*!
166   \brief Get central widget (or first found one).
167   \return widget
168 */
169 QWidget* QtxGroupBox::widget() const
170 {
171   if ( !layout() )
172     return 0;
173
174   QWidget* w = 0;
175   for ( int i = 0; i < (int)layout()->count() && !w; i++ )
176     w = layout()->itemAt( i )->widget();
177   return w;
178 }
179
180 /*!
181   \brief Set central widget to the group box.
182   \param wid widget being added to the group box
183 */
184 void QtxGroupBox::setWidget( QWidget* wid )
185 {
186   QWidget* w = widget();
187   if ( w == wid )
188     return;
189
190   if ( layout() )
191     layout()->removeWidget( w );
192
193   if ( !wid )
194     delete layout();
195   else if ( !layout() )
196   {
197     QLayout* bl = new QVBoxLayout( this );
198     bl->setMargin( 0 );
199     bl->setSpacing( 0 );
200   }
201
202   if ( layout() )
203     layout()->addWidget( wid );
204
205   if ( wid )
206     wid->updateGeometry();
207 }
208
209 /*!
210   \brief Customize resize event.
211   \param e resize event
212 */
213 void QtxGroupBox::resizeEvent( QResizeEvent* e )
214 {
215   QGroupBox::resizeEvent( e );
216
217   updateTitle();
218 }
219
220 /*!
221   \brief Customize child event.
222   \param e child event
223 */
224 void QtxGroupBox::childEvent( QChildEvent* e )
225 {
226 /*
227   if ( e->type() == QEvent::ChildAdded && e->child() == myContainer )
228     return;
229 */
230   QGroupBox::childEvent( e );
231 }
232
233 /*!
234   \brief Process custom events.
235   \param e custom event (not used)
236 */
237 void QtxGroupBox::customEvent( QEvent* /*e*/ )
238 {
239   updateTitle();
240 }
241
242 /*!
243   \brief Get the group box title size.
244   \return title size
245 */
246 QSize QtxGroupBox::titleSize() const
247 {
248   return QSize( fontMetrics().width( title() ), fontMetrics().height() );
249 }
250
251 /*!
252   \brief Update the group box title.
253 */
254 void QtxGroupBox::updateTitle()
255 {
256   if ( !myContainer )
257     return;
258
259   int align = alignment();
260
261   if ( title().isEmpty() )
262     align = Qt::AlignRight;
263
264   QSize ts = titleSize();
265
266   int m = 5;
267
268   int w = width() - ts.width();
269   if ( align == Qt::AlignCenter )
270     w = w / 2;
271
272   w -= m;
273
274   myContainer->resize( myContainer->minimumSizeHint() );
275
276   bool vis = false;
277   const QObjectList list = myContainer->children();
278   for ( QObjectList::const_iterator it = list.begin(); it != list.end() && !vis; ++it )
279     vis = (*it)->isWidgetType() && ((QWidget*)(*it))->isVisibleTo( myContainer );
280
281   if ( !vis )
282     myContainer->hide();
283   else
284   {
285     int x = 0;
286     if ( align == Qt::AlignRight )
287       x = rect().left() + m;
288     else
289       x = rect().right() - myContainer->width() - m;
290
291     int y = rect().top() - ( myContainer->height() - ts.height() ) / 2;
292
293     QPoint pos( x, qMax( 0, y ) );
294     myContainer->move( pos );
295     myContainer->show();
296   }
297
298   if ( layout() )
299   {
300     if ( myContainer && myContainer->isVisibleTo( this ) )
301       setInsideMargin( qMax( 0, myContainer->height() - ts.height() ) );
302     else
303       setInsideMargin( 0 );
304   }
305
306   updateGeometry();
307 }
308
309 /*!
310   \brief Expand group box to the specified size.
311   \param sz new size
312 */
313 QSize QtxGroupBox::expandTo( const QSize& sz ) const
314 {
315   int sh = 0;
316   int sw = titleSize().width();
317   if ( myContainer && myContainer->isVisibleTo( (QWidget*)this ) )
318   {
319     if ( alignment() == Qt::AlignCenter )
320       sw += 2 * ( myContainer->width() + 5 );
321     else
322       sw += 1 * ( myContainer->width() + 5 );
323     sw += 20;
324     sh = myContainer->height() + 5;
325   }
326   return QSize( qMax( sz.width(), sw ), qMax( sz.height(), sh ) );
327 }
328
329 /*!
330   \brief Set group box's inside margin size.
331   \param m new inside margin size
332 */
333 void QtxGroupBox::setInsideMargin( const int m )
334 {
335   QVBoxLayout* bl = ::qobject_cast<QVBoxLayout*>( layout() );
336
337   if ( !bl )
338     return;
339
340   QSpacerItem* spacer = 0;
341   if ( bl->count() )
342     spacer = bl->itemAt( 0 )->spacerItem();
343
344   if ( !spacer )
345     bl->insertSpacing( 0, m );
346   else
347     spacer->changeSize( 0, m );
348 }