Salome HOME
Join modifications from branch OCC_debug_for_3_2_0b1
[modules/gui.git] / src / Qtx / QtxGroupBox.cxx
1 // Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
2 // 
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either 
6 // version 2.1 of the License.
7 // 
8 // This library is distributed in the hope that it will be useful 
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public  
14 // License along with this library; if not, write to the Free Software 
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/
18 //
19 // File:      QtxGroupBox.cxx
20 // Author:    Sergey TELKOV
21
22 #include "QtxGroupBox.h"
23
24 #include <qhbox.h>
25 #include <qlayout.h>
26 #include <qtoolbutton.h>
27 #include <qapplication.h>
28 #include <qobjectlist.h>
29
30 /*!
31   Constructor
32 */
33 QtxGroupBox::QtxGroupBox( QWidget* parent, const char* name )
34 : QGroupBox( parent, name ),
35 myContainer( 0 )
36 {
37 }
38
39 /*!
40   Constructor
41 */
42 QtxGroupBox::QtxGroupBox( const QString& title, QWidget* parent, const char* name )
43 : QGroupBox( title, parent, name ),
44 myContainer( 0 )
45 {
46   initialize();
47 }
48
49 /*!
50   Constructor
51 */
52 QtxGroupBox::QtxGroupBox( int strips, Orientation o, QWidget* parent, const char* name )
53 : QGroupBox( strips, o, parent, name ),
54 myContainer( 0 )
55 {
56   initialize();
57 }
58
59 /*!
60   Constructor
61 */
62 QtxGroupBox::QtxGroupBox( int strips, Orientation o, const QString& title,
63                                           QWidget* parent, const char* name )
64 : QGroupBox( strips, o, title, parent, name ),
65 myContainer( 0 )
66 {
67   initialize();
68 }
69
70 /*!
71   Destructor
72 */
73 QtxGroupBox::~QtxGroupBox()
74 {
75   delete myContainer;
76 }
77
78 /*!
79   Creates horizontal box as container
80 */
81 void QtxGroupBox::initialize()
82 {
83   myContainer = new QHBox( this, 0, WStyle_Customize | WStyle_NoBorderEx | WStyle_Tool );
84
85   updateTitle();
86 }
87
88 #if QT_VER < 3
89
90 /*!
91   \return the width of the empty space between the items in the group and the frame of the group
92 */
93 int QtxGroupBox::insideMargin() const
94 {
95   int m = 0;
96   if ( layout() )
97     m = layout()->margin();
98   return m;
99 }
100
101 /*!
102   \return the width of the empty space between each of the items in the group
103 */
104 int QtxGroupBox::insideSpacing() const
105 {
106   int s = 0;
107   if ( layout() )
108     s = layout()->spacing();
109   return s;
110 }
111
112 /*!
113   Sets the width of the empty space between the items in the group and the frame of the group
114 */
115 void QtxGroupBox::setInsideMargin( int m )
116 {
117   if ( layout() )
118     layout()->setMargin( m );
119 }
120
121 /*!
122   Sets the width of the empty space between each of the items in the group
123 */
124 void QtxGroupBox::setInsideSpacing( int s )
125 {
126   if ( layout() )
127     layout()->setSpacing( s );
128 }
129
130 #endif
131
132 /*!
133   Inserts title widget
134   \param wid - new title widget
135 */
136 void QtxGroupBox::insertTitleWidget( QWidget* wid )
137 {
138   if ( !myContainer )
139     return;
140
141   wid->reparent( myContainer, QPoint( 0, 0 ), true );
142   wid->installEventFilter( this );
143
144   updateTitle();
145 }
146
147 /*!
148   Removes title widget
149   \param wid - title widget
150 */
151 void QtxGroupBox::removeTitleWidget( QWidget* wid )
152 {
153   if ( !myContainer || wid->parentWidget() != myContainer )
154     return;
155
156   wid->reparent( 0, QPoint( 0, 0 ), false );
157   wid->removeEventFilter( this );
158
159   updateTitle();
160 }
161
162 /*!
163   Calculates margin
164 */
165 void QtxGroupBox::adjustInsideMargin()
166 {
167   QApplication::sendPostedEvents( myContainer, QEvent::ChildInserted );
168
169   myContainer->resize( myContainer->minimumSizeHint() );
170
171   setInsideMargin( myContainer->height() );
172 }
173
174 /*!
175   Sets the alignment of the group box title
176 */
177 void QtxGroupBox::setAlignment( int align )
178 {
179   QGroupBox::setAlignment( align );
180
181   updateTitle();
182 }
183
184 /*!
185   Sets title of groop box
186 */
187 void QtxGroupBox::setTitle( const QString& title )
188 {
189   QGroupBox::setTitle( title );
190
191   updateTitle();
192 }
193
194 /*!
195   Changes the layout of the group box
196   \param strips - number of column/rows
197   \param o - orientation
198 */
199 void QtxGroupBox::setColumnLayout( int strips, Orientation o )
200 {
201   if ( myContainer )
202     myContainer->reparent( 0, QPoint( 0, 0 ), false );
203
204   QGroupBox::setColumnLayout( strips, o );
205
206   if ( myContainer )
207     myContainer->reparent( this, QPoint( 0, 0 ), false );
208
209   updateTitle();
210 }
211
212 /*!
213   Shows group box
214 */
215 void QtxGroupBox::show()
216 {
217   QGroupBox::show();
218
219   updateTitle();
220 }
221
222 /*!
223   Updates group box
224 */
225 void QtxGroupBox::update()
226 {
227   QGroupBox::update();
228
229   updateTitle();
230 }
231
232 /*!
233   \return the recommended size for the widget
234 */
235 QSize QtxGroupBox::sizeHint() const
236 {
237   QSize sz = QGroupBox::sizeHint();
238
239   int sw = titleSize().width();
240
241   if ( myContainer )
242   {
243     if ( alignment() == AlignCenter )
244       sw += 2 * ( myContainer->width() + 5 );
245     else
246       sw += 1 * ( myContainer->width() + 5 );
247   }
248
249   sw += frameRect().left();
250
251   return QSize( QMAX( sz.width(), sw ), sz.height() );
252 }
253
254 /*!
255   \return the recommended minimum size for the widget
256 */
257 QSize QtxGroupBox::minimumSizeHint() const
258 {
259   QSize sz = QGroupBox::minimumSizeHint();
260
261   int sw = titleSize().width() + myContainer ? myContainer->width() + 5 : 0;
262
263   if ( myContainer )
264   {
265     if ( alignment() == AlignCenter )
266       sw += 2 * ( myContainer->width() + 5 );
267     else
268       sw += 1 * ( myContainer->width() + 5 );
269   }
270
271   sw += frameRect().left();
272
273   return QSize( QMAX( sz.width(), sw ), sz.height() );
274 }
275
276 /*!
277   Custom event filter
278 */
279 bool QtxGroupBox::eventFilter( QObject* obj, QEvent* e )
280 {
281   QEvent::Type type = e->type();
282   if ( myContainer && obj->parent() == myContainer &&
283        ( type == QEvent::Show || type == QEvent::ShowToParent ||
284          type == QEvent::Hide || type == QEvent::HideToParent ) )
285     QApplication::postEvent( this, new QCustomEvent( QEvent::User ) );
286
287   return QGroupBox::eventFilter( obj, e );
288 }
289
290 /*!
291   Custom resize event filter
292 */
293 void QtxGroupBox::resizeEvent( QResizeEvent* e )
294 {
295   QGroupBox::resizeEvent( e );
296
297   updateTitle();
298 }
299
300 /*!
301   Custom child event filter
302 */
303 void QtxGroupBox::childEvent( QChildEvent* e )
304 {
305   if ( e->type() == QEvent::ChildInserted && e->child() == myContainer )
306     return;
307
308   QGroupBox::childEvent( e );
309 }
310
311 /*!
312   Event filter of custom items
313 */
314 void QtxGroupBox::customEvent( QCustomEvent* )
315 {
316   updateTitle();
317 }
318
319 /*!
320   On frame changed
321 */
322 void QtxGroupBox::frameChanged()
323 {
324   updateTitle();
325 }
326
327 /*!
328   \return size of title
329 */
330 QSize QtxGroupBox::titleSize() const
331 {
332   QSize sz( 0, 0 );
333
334   if ( layout() )
335   {
336     QSpacerItem* si = 0;
337     for ( QLayoutIterator it = layout()->iterator(); it.current() && !si; ++it )
338       si = it.current()->spacerItem();
339     if ( si )
340       sz = si->sizeHint();
341   }
342
343   int w = sz.width();
344   int h = sz.height() + insideMargin();
345
346   return QSize( w, h );
347 }
348
349 /*!
350   Updates title
351 */
352 void QtxGroupBox::updateTitle()
353 {
354   if ( !myContainer )
355     return;
356
357   int align = alignment();
358   if ( align == AlignAuto )
359     align = QApplication::reverseLayout() ? AlignRight : AlignLeft;
360
361   if ( title().isEmpty() )
362     align = AlignRight;
363
364   QSize ts = titleSize();
365
366   int m = 5;
367
368   int w = frameRect().width() - ts.width();
369   if ( align == AlignCenter )
370     w = w / 2;
371
372   w -= m;
373
374   QApplication::sendPostedEvents( myContainer, QEvent::ChildInserted );
375   myContainer->resize( myContainer->minimumSizeHint() );
376
377   bool vis = false;
378   const QObjectList* list = myContainer->children();
379   if ( list )
380   {
381     for ( QObjectListIt it( *list ); it.current() && !vis; ++it )
382       vis = it.current()->isWidgetType() &&
383             ((QWidget*)it.current())->isVisibleTo( myContainer );
384   }
385
386   if ( myContainer->height() > ts.height() || myContainer->width() > w || !vis )
387     myContainer->hide();
388   else
389   {
390     int x = 0;
391     if ( align == AlignRight )
392       x = frameRect().left() + m;
393     else
394       x = frameRect().right() - myContainer->width() - m;
395
396     int y = frameRect().top() - ( myContainer->height() - frameWidth() ) / 2;
397
398     QPoint pos( x, QMAX( 0, y ) );
399     pos = mapToGlobal( pos );
400     if ( myContainer->parentWidget() )
401       pos = myContainer->parentWidget()->mapFromGlobal( pos );
402     myContainer->move( pos );
403     myContainer->show();
404   }
405
406   updateGeometry();
407 }