1 // Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
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.
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.
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
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File: QtxDialog.cxx
23 // Author: Sergey TELKOV
25 #include "QtxDialog.h"
32 #include <QPushButton>
33 #include <QApplication>
36 \class QtxDialog::Area
38 \brief Area containing dialog box buttons.
41 class QtxDialog::Area : public QFrame
44 Area( Qt::Orientation, QtxDialog*, QWidget* = 0 );
47 bool isBorderEnabled() const;
48 void setBorderEnabled( const bool );
50 void setBorderWidget( QLabel* );
52 void insertButton( QAbstractButton* );
53 void removeButton( QAbstractButton* );
54 bool contains( QAbstractButton* ) const;
57 void setPolicy( const int );
61 const QList<QAbstractButton*>& buttons() const;
67 QtxDialog* myDlg; //!< parent dialog box
68 QLabel* myLine; //!< border widget
69 bool myBorder; //!< "has border" flag
70 int myPolicy; //!< button layout type (QtxDialog::PlacePolicy)
71 QList<QAbstractButton*> myButtons; //!< buttons list
72 Qt::Orientation myOrientation; //!< buttons orientation (Qt::Orientation)
77 \param o buttons orientation
78 \param dlg dialog box owning this area
79 \param parent parent widget
81 QtxDialog::Area::Area( Qt::Orientation o, QtxDialog* dlg, QWidget* parent )
89 if ( myOrientation == Qt::Horizontal )
90 setSizePolicy( QSizePolicy( QSizePolicy::Preferred, QSizePolicy::Maximum ) );
92 setSizePolicy( QSizePolicy( QSizePolicy::Maximum, QSizePolicy::Preferred ) );
100 QtxDialog::Area::~Area()
105 \brief Insert button to the area.
106 \param b button to be added
109 void QtxDialog::Area::insertButton( QAbstractButton* b )
111 if ( !b || myButtons.contains( b ) )
114 QWidget* parent = b->parentWidget();
115 if ( parent != this )
116 b->setParent( this );
118 myButtons.append( b );
121 myDlg->adjustButtons();
130 \brief Remove button from the area.
131 \param b button to be removed
134 void QtxDialog::Area::removeButton( QAbstractButton* b )
139 myButtons.removeAll( b );
141 if ( myButtons.isEmpty() )
147 myDlg->adjustButtons();
153 \brief Check if area owns the button specified.
154 \param b button to be checked
155 \return \c true if area contains button
157 bool QtxDialog::Area::contains( QAbstractButton* b ) const
159 return myButtons.contains( b );
163 \brief Get buttons layout policy.
164 \return policy of button layouting (Qtx::PlacePolicy)
167 int QtxDialog::Area::policy() const
173 \brief Set buttons layout policy.
176 void QtxDialog::Area::setPolicy( const int p )
186 \brief Check of the border is enabled.
187 \return \c true if border is enabled
188 \sa setBorderEnabled(), setBorderWidget()
190 bool QtxDialog::Area::isBorderEnabled() const
192 return myLine && myBorder;
196 \brief Enable/disable border (separator between main frame and button frame)
199 void QtxDialog::Area::setBorderEnabled( const bool on )
201 if ( !myLine || myBorder == on )
209 \brief Set border widget (separator between main frame and button frame).
210 \param line new separator widget
212 void QtxDialog::Area::setBorderWidget( QLabel* line )
214 if ( myLine == line )
223 \brief Get all area buttons.
224 \return const reference to the list of buttons
226 const QList<QAbstractButton*>& QtxDialog::Area::buttons() const
232 \brief Update border visibility.
234 void QtxDialog::Area::updateBorder()
239 bool isVis = isVisibleTo( parentWidget() );
240 myLine->setVisible( isVis );
242 myLine->setLineWidth( myBorder ? 1 : 0 );
246 \brief Layout buttons in the area.
248 void QtxDialog::Area::layoutButtons()
250 int aPolicy = policy();
252 QMap<QAbstractButton*, int> buttonId;
253 for ( QList<QAbstractButton*>::iterator it1 = myButtons.begin(); it1 != myButtons.end(); ++it1 )
254 buttonId.insert( *it1, 0 );
256 QList<QAbstractButton*> src;
257 for ( ButtonMap::Iterator mit = myDlg->myButton.begin(); mit != myDlg->myButton.end(); ++mit )
259 if ( buttonId.contains( mit.value() ) )
261 buttonId[mit.value()] = mit.key();
262 if ( mit.key() >= 0 )
263 src.append( mit.value() );
267 for ( QList<QAbstractButton*>::iterator it2 = myButtons.begin(); it2 != myButtons.end(); ++it2 )
269 if ( buttonId[*it2] < 0 )
273 QList<QAbstractButton*> left, right, center, other;
274 for ( QList<QAbstractButton*>::iterator it = src.begin(); it != src.end(); ++it )
276 if ( !(*it)->isVisibleTo( this ) )
279 int aPosition = myDlg->buttonPosition( *it );
280 if ( aPosition == -1 )
283 if ( aPolicy != QtxDialog::Position )
285 else if ( aPosition == QtxDialog::Left )
287 else if ( aPosition == QtxDialog::Right )
289 else if ( aPosition == QtxDialog::Center )
290 center.append( *it );
295 QBoxLayout* buttonLayout = 0;
296 if ( myOrientation == Qt::Vertical )
297 buttonLayout = new QVBoxLayout( this );
299 buttonLayout = new QHBoxLayout( this );
304 buttonLayout->setMargin( 0 );
305 buttonLayout->setSpacing( 5 );
307 if ( aPolicy == QtxDialog::Position )
309 for ( QList<QAbstractButton*>::iterator lit = left.begin(); lit != left.end(); ++lit )
310 buttonLayout->addWidget( *lit );
311 buttonLayout->addStretch( 1 );
312 for ( QList<QAbstractButton*>::iterator cit = center.begin(); cit != center.end(); ++cit )
313 buttonLayout->addWidget( *cit );
314 buttonLayout->addStretch( 1 );
315 for ( QList<QAbstractButton*>::iterator rit = right.begin(); rit != right.end(); ++rit )
316 buttonLayout->addWidget( *rit );
320 for ( int i = 0; i < (int)other.count(); i++ )
322 buttonLayout->addWidget( other[i] );
323 if ( aPolicy == QtxDialog::Uniform && i < (int)other.count() - 1 )
324 buttonLayout->addStretch( 1 );
331 for ( int i = 0; i < layout()->count(); i++ )
333 if ( !layout()->itemAt( i ) || layout()->itemAt( i )->widget() )
336 if ( QApplication::layoutDirection() == Qt::RightToLeft )
337 wids.prepend( layout()->itemAt( i )->widget() );
339 wids.append( layout()->itemAt( i )->widget() );
342 Qtx::setTabOrder( wids );
347 \class QtxDialog::Border
349 \brief Special label used as border widget (separator
350 between main frame and button frame).
353 class QtxDialog::Border : public QLabel
356 Border( QWidget* = 0 );
359 virtual void setLineWidth( int );
361 virtual QSize sizeHint() const;
362 virtual QSize minimumSizeHint() const;
367 \param parent parent widget
369 QtxDialog::Border::Border( QWidget* parent )
372 setAlignment( Qt::AlignCenter );
378 QtxDialog::Border::~Border()
383 \brief Set separator line width.
384 \param lw new line width
386 void QtxDialog::Border::setLineWidth( int lw )
388 bool isOn = lineWidth() > 0;
390 QLabel::setLineWidth( lw );
392 if ( isOn != ( lineWidth() > 0 ) )
397 \brief Get recommended size for the widget.
398 \return recommended size for the widget
400 QSize QtxDialog::Border::sizeHint() const
404 if ( lineWidth() > 0 )
406 if ( frameShape() == VLine )
407 sz += QSize( 5 + lineWidth(), 0 );
408 else if ( frameShape() == HLine )
409 sz += QSize( 0, 5 + lineWidth() );
416 \brief Get recommended minimum size for the widget.
417 \return recommended minimum size for the widget
419 QSize QtxDialog::Border::minimumSizeHint() const
426 \brief Generic dialog box class.
432 Construct a dialog with specified parent and name.
433 By default non-modal, non-resizable with the OK, Cancel and Help buttons
434 dialog box is created.
436 \param parent parent widget
437 \param modal if \c true dialog box is modal
438 \param allowResize if \c true then dialog can be resized by user
439 \param f specified control buttons for dialog box (QtxDialog::ButtonFlags)
440 \param wf dialog box flags (Qt::WindowFlags)
442 QtxDialog::QtxDialog( QWidget* parent, bool modal, bool allowResize, const int f, Qt::WindowFlags wf )
443 : QDialog( parent, (Qt::WindowFlags)( wf | Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::Dialog |
445 ( allowResize ? 0 : Qt::FramelessWindowHint ) |
449 // in qwidget_win.cpp flag WStyle_ContextHelp will be unset in WStyle_MinMax in switched ON
450 && !( wf & Qt::WindowContextHelpButtonHint )
452 ) ? Qt::WindowMaximizeButtonHint : 0 ) ) ),
456 myDialogFlags( Accept | SetFocus )
460 QVBoxLayout* base = new QVBoxLayout( this );
461 base->setMargin( 5 );
462 base->setSpacing( 0 );
464 QWidget* main = new QWidget( this );
465 base->addWidget( main );
467 QVBoxLayout* lMain = new QVBoxLayout( main );
468 lMain->setMargin( 0 );
469 lMain->setSpacing( 0 );
471 Area* topArea = new Area( Qt::Horizontal, this, main );
472 QLabel* topLine = new Border( main );
473 lMain->addWidget( topArea );
474 lMain->addWidget( topLine );
476 QWidget* midGroup = new QWidget( main );
477 lMain->addWidget( midGroup );
479 QVBoxLayout* midLyout = new QVBoxLayout( midGroup );
480 midLyout->setMargin( 0 );
481 midLyout->setSpacing( 0 );
483 QLabel* botLine = new Border( main );
484 Area* botArea = new Area( Qt::Horizontal, this, main );
485 lMain->addWidget( botLine );
486 lMain->addWidget( botArea );
488 Area* leftArea = new Area( Qt::Vertical, this, midGroup );
489 QLabel* leftLine = new Border( midGroup );
490 midLyout->addWidget( leftArea );
491 midLyout->addWidget( leftLine );
493 myMainFrame = new QFrame( midGroup );
494 midLyout->addWidget( myMainFrame );
496 QLabel* rightLine = new Border( midGroup );
497 Area* rightArea = new Area( Qt::Vertical, this, midGroup );
498 midLyout->addWidget( rightLine );
499 midLyout->addWidget( rightArea );
501 myMainFrame->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ) );
503 topLine->setFrameStyle( QFrame::Sunken | QFrame::HLine );
504 botLine->setFrameStyle( QFrame::Sunken | QFrame::HLine );
505 leftLine->setFrameStyle( QFrame::Sunken | QFrame::VLine );
506 rightLine->setFrameStyle( QFrame::Sunken | QFrame::VLine );
508 topArea->setBorderWidget( topLine );
509 botArea->setBorderWidget( botLine );
510 leftArea->setBorderWidget( leftLine );
511 rightArea->setBorderWidget( rightLine );
513 myArea.insert( TopArea, topArea );
514 myArea.insert( BottomArea, botArea );
515 myArea.insert( LeftArea, leftArea );
516 myArea.insert( RightArea, rightArea );
518 for ( AreaMap::Iterator itr = myArea.begin(); itr != myArea.end(); ++ itr )
519 itr.value()->setBorderEnabled( false );
521 myButton.insert( OK, new QPushButton( tr( "&OK" ), this ) );
522 myButton.insert( Cancel, new QPushButton( tr( "&Cancel" ), this ) );
523 myButton.insert( Close, new QPushButton( tr( "C&lose" ), this ) );
524 myButton.insert( Help, new QPushButton( tr( "&Help" ), this ) );
525 myButton.insert( Apply, new QPushButton( tr( "&Apply" ), this ) );
526 myButton.insert( Yes, new QPushButton( tr( "&Yes" ), this ) );
527 myButton.insert( No, new QPushButton( tr( "&No" ), this ) );
529 for ( ButtonMap::Iterator it = myButton.begin(); it != myButton.end(); ++it )
531 ((QPushButton*)it.value())->setAutoDefault( false );
532 connect( it.value(), SIGNAL( destroyed( QObject* ) ), this, SLOT( onDestroyed( QObject* ) ) );
535 setButtonPosition( Left, OK | Cancel | Apply );
536 setButtonPosition( Center, Yes | No | Close );
537 setButtonPosition( Right, Help );
538 setButtonPlace( BottomArea, All );
540 connect( myButton[Apply], SIGNAL( clicked() ), this, SIGNAL( dlgApply() ) );
541 connect( myButton[Help], SIGNAL( clicked() ), this, SIGNAL( dlgHelp() ) );
543 connect( myButton[OK], SIGNAL( clicked() ), this, SLOT( onAccept() ) );
544 connect( myButton[Cancel], SIGNAL( clicked() ), this, SLOT( onReject() ) );
545 connect( myButton[Yes], SIGNAL( clicked() ), this, SLOT( onAccept() ) );
546 connect( myButton[No], SIGNAL( clicked() ), this, SLOT( onReject() ) );
547 connect( myButton[Close], SIGNAL( clicked() ), this, SLOT( onReject() ) );
550 QWidget* p = parentWidget();
551 while( p && p->parentWidget() )
552 p = p->parentWidget();
555 setWindowIcon( p->windowIcon() );
561 setMaximumSize( minimumSize() );
570 QtxDialog::~QtxDialog()
575 \brief Add specified control button(s) to the dialog box.
576 \param f ORed buttons flags (Qtx::ButtonFlags)
577 \sa clearButtonFlags(), testButtonFlags()
579 void QtxDialog::setButtonFlags( const int f )
581 int old = myButtonFlags;
582 myButtonFlags = myButtonFlags | f;
583 if ( old != myButtonFlags )
588 \brief Remove specified control button(s) from the dialog box.
589 \param f ORed buttons flags (Qtx::ButtonFlags)
590 \sa setButtonFlags(), testButtonFlags()
592 void QtxDialog::clearButtonFlags( const int f )
594 int old = myButtonFlags;
595 myButtonFlags = myButtonFlags & ~f;
596 if ( old != myButtonFlags )
601 \brief Test specified buttons.
602 \return \c true if specified control buttons are used in the dialog box
603 \sa setButtonFlags(), clearButtonFlags()
605 bool QtxDialog::testButtonFlags( const int f ) const
607 return ( myButtonFlags & f ) == f;
611 \brief Set specified dialog box flags.
612 \param f dialog box flags (QtxDialog::DialogFlags)
613 \sa clearDialogFlags(), testDialogFlags(), acceptData(), rejectData()
615 void QtxDialog::setDialogFlags( const int f )
617 myDialogFlags = myDialogFlags | f;
621 \brief Clear specified the dialog flags.
622 \param f dialog box flags (QtxDialog::DialogFlags)
623 \sa setDialogFlags(), testDialogFlags()
625 void QtxDialog::clearDialogFlags( const int f )
627 myDialogFlags = myDialogFlags & ~f;
631 \brief Test specified dialog flags.
632 \return \c true if specified dialog box falgs are set
633 \sa setDialogFlags(), clearDialogFlags()
635 bool QtxDialog::testDialogFlags( const int f ) const
637 return ( myDialogFlags & f ) == f;
641 \brief Get dialog box main frame widget.
643 Main frame is an internal widget which should contains all
644 elements of dialog box except control buttons.
646 \return main frame widget
648 QFrame* QtxDialog::mainFrame() const
654 \brief Get specified control button position
655 \param id control button ID (QtxDialog::ButtonFlags)
656 \return button's position (QtxDialog::ButtonPosition) or -1 if it is not set or invalid \a id is given
657 \sa setButtonPosition()
659 int QtxDialog::buttonPosition( const int id ) const
662 if ( myPosition.contains( id ) )
663 pos = myPosition[id];
667 \brief Set the specified control button(s) position.
668 \param id control button(s) ID (QtxDialog::ButtonFlags)
669 \param pos button(s) position (QtxDialog::ButtonPosition)
671 void QtxDialog::setButtonPosition( const int pos, const int id )
673 ButtonMap map = buttons( id );
675 QMap<QObject*, int> changed;
676 for ( ButtonMap::Iterator it = map.begin(); it != map.end(); ++it )
678 if ( myPosition[it.key()] == pos )
681 myPosition[it.key()] = pos;
682 if ( button( it.key() ) )
683 changed.insert( button( it.key() )->parent(), 0 );
686 for ( AreaMap::Iterator itr = myArea.begin(); itr != myArea.end(); ++itr )
688 if ( changed.contains( itr.value() ) )
689 itr.value()->layoutButtons();
694 \brief Set button position for all buttons in specified \a area.
695 \param pos button(s) position (QtxDialog::ButtonPosition)
696 \param area buttons area (QtxDialog::ButtonArea)
697 \sa setButtonPosition()
699 void QtxDialog::setPlacePosition( const int pos, const int area )
701 if ( !myArea.contains( area ) )
704 Area* anArea = myArea[area];
706 bool changed = false;
707 for ( ButtonMap::Iterator it = myButton.begin(); it != myButton.end(); ++it )
709 if ( !anArea->contains( it.value() ) )
712 changed = changed && myPosition[it.key()] != pos;
714 myPosition[it.key()] = pos;
718 anArea->layoutButtons();
722 \brief Get buttons layouting policy for the specified \a area.
723 \param area buttons area (QtxDialog::ButtonArea)
726 int QtxDialog::placePolicy( const int area ) const
729 if ( myArea.contains( area ) )
730 res = myArea[area]->policy();
735 \brief set buttons layouting policy for the specified \a area.
736 \param policy buttons layouting policy (QtxDialog::PlacePolicy)
737 \param area buttons area (QtxDialog::ButtonArea)
740 void QtxDialog::setPlacePolicy( const int policy, const int area )
744 for ( AreaMap::Iterator itr = myArea.begin(); itr != myArea.end(); ++itr )
745 itr.value()->setPolicy( policy );
747 else if ( myArea.contains( area ) )
748 myArea[area]->setPolicy( policy );
752 \brief Move specified button(s) into specified area.
753 \param area buttons area (QtxDialog::ButtonArea)
754 \param id control button(s) ID (QtxDialog::ButtonFlags)
756 void QtxDialog::setButtonPlace( const int area, const int id )
758 if ( !myArea.contains( area ) )
761 Area* anArea = myArea[area];
762 ButtonMap map = buttons( id );
763 QMap<Area*, int> areaMap;
764 for ( AreaMap::ConstIterator aIt = myArea.begin(); aIt != myArea.end(); ++aIt )
765 areaMap.insert( aIt.value(), 0 );
767 for ( ButtonMap::Iterator it = map.begin(); it != map.end(); ++it )
769 Area* old = (Area*)it.value()->parent();
773 if ( areaMap.contains( old ) )
774 old->removeButton( it.value() );
775 anArea->insertButton( it.value() );
780 \brief Check if border is enabled.
781 \param area buttons area (QtxDialog::ButtonArea)
782 \return \c true if border is enabled for specified button area.
783 \sa setBorderEnabled()
785 bool QtxDialog::isBorderEnabled( const int area ) const
788 if ( myArea.contains( area ) )
789 res = myArea[area]->isBorderEnabled();
794 \brief Show/hide border for the specified button area.
796 Border is a line which separate main frame and control buttons.
798 \param area buttons area (QtxDialog::ButtonArea)
799 \param on enable border flag
800 \sa isBorderEnabled()
802 void QtxDialog::setBorderEnabled( const bool on, const int area )
804 if ( !myArea.contains( area ) )
807 if ( myArea[area]->isBorderEnabled() == on )
810 myArea[area]->setBorderEnabled( on );
814 QApplication::sendPostedEvents();
820 \brief Get "enabled" status of the specified button(s).
821 \param id control button(s) ID (QtxDialog::ButtonFlags)
822 \return \c true if all specified buttons are enabled.
823 \sa setButtonEnabled()
825 bool QtxDialog::isButtonEnabled( const int id ) const
827 ButtonMap map = buttons( id );
828 bool result = !map.isEmpty();
829 for ( ButtonMap::Iterator it = map.begin(); it != map.end(); ++it )
830 result = result && it.value()->isEnabled();
835 \brief Enable/disable specified button(s).
836 \param on enable button(s) flag
837 \param id control button(s) ID (QtxDialog::ButtonFlags)
838 \sa isButtonEnabled()
840 void QtxDialog::setButtonEnabled( const bool on, const int id )
842 ButtonMap map = buttons( id );
843 for ( ButtonMap::Iterator it = map.begin(); it != map.end(); ++it )
844 it.value()->setEnabled( on );
848 \brief Check if specified button has keyboard focus.
849 \param id control button ID (QtxDialog::ButtonFlags)
850 \return \c true if specified button has keyboard focus
853 bool QtxDialog::hasButtonFocus( const int id ) const
856 QAbstractButton* pb = button( id );
858 res = pb->hasFocus();
863 \brief Sets the keyboard focus to the specified button.
864 \param id control button ID (QtxDialog::ButtonFlags)
867 void QtxDialog::setButtonFocus( const int id )
869 QAbstractButton* pb = button( id );
875 \brief Get specified button's text.
876 \param id control button ID (QtxDialog::ButtonFlags)
877 \return button's text
880 QString QtxDialog::buttonText( const int id )
883 QAbstractButton* but = button( id );
885 retval = but->text();
890 \brief Set specified button's text.
891 \param id control button ID (QtxDialog::ButtonFlags)
892 \param text button's text
895 void QtxDialog::setButtonText( const int id, const QString& text )
897 QAbstractButton* but = button( id );
898 if ( but && but->text() != text )
900 but->setText( text );
906 \brief Sets alignment policy.
908 Use the function before the the dialog is first time shown.
909 If dialog flag AlignOnce is set then alignment is performed
910 only once, otherwise the dialog is aligned each time when it
912 Dialog box is aligned relatively to its parent.
913 By default, dialog box is aligned to the center of the parent
914 widget (usually desktop or another dialog box).
916 \param align alignment flag(s) (Qtx::AlignmentFlags)
917 \return previous alignment policy
919 uint QtxDialog::setAlignment( uint align )
921 uint oldAlign = myAlignment;
927 \brief Update dialog box.
929 void QtxDialog::update()
931 for ( ButtonMap::Iterator it = myButton.begin(); it != myButton.end(); ++it )
933 it.value()->setVisible( testButtonFlags( it.key() ) );
935 for ( AreaMap::Iterator itr = myArea.begin(); itr != myArea.end(); ++itr )
936 itr.value()->layoutButtons();
944 \brief Show/hide dialog box, set keyboard focus to the dialog.
946 Re-implemented from Qt.
948 \param on show/hide flag
950 void QtxDialog::setVisible( bool on )
952 resize( sizeHint() );
954 QDialog::setVisible( on );
958 if ( testDialogFlags( SetFocus ) )
963 QApplication::instance()->processEvents();
967 \brief Get user button by the specified \a id.
968 \param id user button ID
969 \return user button or 0 if it is not found
970 \sa insertButton(), removeButton(), userButtonIds()
972 QAbstractButton* QtxDialog::userButton( const int id ) const
974 QAbstractButton* b = 0;
975 if ( id < -1 && myButton.contains( id ) )
981 \brief Get all user button IDs.
982 \return list of user buttons identificators
983 \sa insertButton(), removeButton(), userButton()
985 QIntList QtxDialog::userButtonIds() const
988 for ( ButtonMap::ConstIterator it = myButton.begin(); it != myButton.end(); ++it )
990 retlist.append( it.key() );
995 \brief Add user button to the dialog box.
997 The button is inserted to the specified dialog box area.
998 if the button is added successfully, the unique identificator of
999 the added button is returned, otherwise -1 is returned.
1001 \param text text of the added button
1002 \param area buttons area (QtxDialog::ButtonArea)
1004 \sa removeButton(), userButton(), userButtonIds()
1006 int QtxDialog::insertButton( const QString& text, const int area )
1008 if ( !myArea.contains( area ) )
1012 while ( myButton.contains( id ) )
1015 Area* anArea = myArea[area];
1016 QAbstractButton* b = createButton( this );
1020 myButton.insert( id, b );
1021 myPosition.insert( id, Left );
1023 connect( b, SIGNAL( clicked() ), this, SLOT( onButton() ) );
1024 connect( b, SIGNAL( destroyed( QObject* ) ), this, SLOT( onDestroyed( QObject* ) ) );
1026 anArea->insertButton( b );
1036 \brief Remove user button.
1038 If \c id is -1, all user buttons are removed.
1040 \param id user button ID
1041 \sa insertButton(), userButton(), userButtonIds()
1043 void QtxDialog::removeButton( const int id )
1051 for ( ButtonMap::Iterator it = myButton.begin(); it != myButton.end(); ++it )
1054 map.insert( it.key(), it.value() );
1057 else if ( myButton.contains( id ) )
1058 map.insert( id, myButton[id] );
1060 for ( ButtonMap::Iterator itr = map.begin(); itr != map.end(); ++itr )
1062 for ( AreaMap::Iterator it = myArea.begin(); it != myArea.end(); ++it )
1063 it.value()->removeButton( itr.value() );
1065 myButton.remove( itr.key() );
1066 myPosition.remove( itr.key() );
1074 \brief Set measure units to the specified label.
1076 In the dialog box label the measure units are closed in braces.
1077 If measure units do not exist they will be added.
1081 // create label "Radius"
1082 QLabel* aLabel = new QLabel( "Radius", mainFrame() );
1083 // set measure units to "mm"
1084 setUnits( aLabel, "mm" ) // => aLabel contains 'Radius (mm)'
1085 // set measure units to "cm"
1086 setUnits( aLabel, "cm" ) // => aLabel contains 'Radius (cm)'
1088 // create label "Radius" with initially not set measure units
1089 QLabel* aLabel = new QLabel( "Radius ():", mainFrame() );
1090 // set measure units to "mm"
1091 setUnits( aLabel, "mm" ) // => aLabel contains 'Radius (mm):'
1092 // set measure units to "cm"
1093 setUnits( aLabel, "cm" ) // => aLabel contains 'Radius (cm):'
1096 \param aLabel label widget
1097 \param aUnits measure units
1099 void QtxDialog::setUnits( QLabel* aLabel, const QString& aUnits )
1101 QString label = aLabel->text();
1104 int end = label.lastIndexOf( ')' );
1106 QString startLabel = label;
1111 begin = label.left( end ).lastIndexOf( '(' );
1114 startLabel = label.mid( 0, begin );
1115 finalLabel = label.mid( end + 1 );
1120 startLabel = startLabel.trimmed();
1121 if ( startLabel.at( startLabel.length() - 1 ) == ':' )
1123 finalLabel = startLabel.mid( startLabel.length() - 1 );
1124 startLabel = startLabel.mid( 0, startLabel.length() - 1 );
1127 if ( aUnits.length() )
1128 label = startLabel.trimmed() + " (" + aUnits + ") " + finalLabel.trimmed();
1130 label = startLabel.trimmed() + " " + finalLabel.trimmed();
1131 aLabel->setText( label );
1135 \brief Check if data entered by the user is valid.
1137 This method can be re-implemented in the successor class if it
1138 requires to check user input consistency.
1139 Default implementation returns \c true.
1141 This method is called if dialog flag QtxDialog::Accept is set.
1142 If this method returns \c true, then dialog will be accepted and closed.
1144 \return \c true if user input is valid
1147 bool QtxDialog::acceptData() const
1153 \brief Check if dialog box can be cancelled.
1155 This method can be re-implemented in the successor class if it
1156 requires to check possibility to cancel dialog box safely.
1157 Default implementation returns \c true.
1159 This method is called if dialog flag QtxDialog::Reject is set.
1160 If this method returns \c true, then dialog will be rejected and closed.
1162 \return \c true if dialog box can be cancelled
1165 bool QtxDialog::rejectData() const
1171 \brief Create new user button.
1173 This method is invoked from method insertButton().
1175 \param parent parent widget
1176 \return new user button
1178 QAbstractButton* QtxDialog::createButton( QWidget* parent )
1180 QPushButton* pb = new QPushButton( parent );
1181 pb->setAutoDefault( false );
1186 \brief Get button by the specified ID.
1187 \param f control button ID (QtxDialog::ButtonFlags)
1188 \return button or 0 if \a id is invalid
1190 QAbstractButton* QtxDialog::button( const int f ) const
1192 QAbstractButton* retval = 0;
1193 if ( myButton.contains( f ) )
1194 retval = myButton[f];
1199 \brief Get buttons by the specified IDs.
1200 \param f control button(s) ID(s) (QtxDialog::ButtonFlags)
1203 QtxDialog::ButtonMap QtxDialog::buttons( const int f ) const
1208 if ( myButton.contains( f ) )
1209 retmap.insert( f, myButton[f] );
1213 for ( ButtonMap::ConstIterator it = myButton.begin(); it != myButton.end(); ++it )
1214 if ( f == -1 || ( it.key() >= 0 && f & it.key() ) )
1215 retmap.insert( it.key(), it.value() );
1221 \brief Get specified button's identifier.
1225 int QtxDialog::buttonId( const QAbstractButton* b ) const
1228 for ( ButtonMap::ConstIterator it = myButton.begin(); it != myButton.end() && id == -1; ++it )
1229 if ( it.value() == b )
1235 \brief Get position of specified button.
1237 \return button position (QtxDialog::ButtonPosition)
1239 int QtxDialog::buttonPosition( QAbstractButton* b ) const
1241 return buttonPosition( buttonId( b ) );
1245 \brief Align this dialog according to the parent widget and alignment
1246 policy before the dialog box is shown.
1248 Re-implemented from Qt.
1252 void QtxDialog::showEvent( QShowEvent* e )
1254 if ( !testDialogFlags( AlignOnce ) || !myInited )
1255 Qtx::alignWidget( this, parentWidget(), myAlignment );
1256 QDialog::showEvent( e );
1260 \brief Process all existing events when dialog box is hidden.
1262 Re-implemented from Qt.
1266 void QtxDialog::hideEvent( QHideEvent* e )
1268 QApplication::instance()->processEvents();
1269 QDialog::hideEvent( e );
1273 \brief Update dialog box layout when the size grip is added.
1275 Re-implemented from Qt.
1277 \param e child event
1279 void QtxDialog::childEvent( QChildEvent* e )
1281 QDialog::childEvent( e );
1282 if ( layout() && e->added() && e->child()->inherits( "QSizeGrip" ) )
1284 layout()->setMargin( 12 );
1285 connect( e->child(), SIGNAL( destroyed() ), this, SLOT( onSizeGripDestroyed() ) );
1290 \brief Process key pressing event.
1292 Re-implemented from Qt.
1294 Call reject() if "Escape" key is pressed.
1295 Call accept() if "Ctrl+Enter" key-sequence is pressed.
1296 Process "F1" key and emit signal dlgHelp().
1297 Transfer "Ctrl+(Shift+)Tab" key-sequence press event
1298 to the child Tab widget (if there is any).
1300 \param e key press event
1302 void QtxDialog::keyPressEvent( QKeyEvent* e )
1304 QDialog::keyPressEvent( e );
1306 if ( e->isAccepted() )
1309 if ( !e->modifiers() && e->key() == Qt::Key_Escape )
1312 if ( e->modifiers() == Qt::ControlModifier && e->key() == Qt::Key_Return )
1314 if ( testButtonFlags( OK ) || testButtonFlags( Yes ) )
1316 else if ( testButtonFlags( Apply ) && isButtonEnabled( Apply ) )
1321 if ( e->key() == Qt::Key_F1 && testButtonFlags( Help ) && isButtonEnabled( Help ) )
1327 if ( e->key() == Qt::Key_Tab && e->modifiers() & Qt::ControlModifier )
1329 QObject* tab = qFindChild<QTabWidget*>( this );
1331 QApplication::sendEvent( tab, e );
1336 \brief Called when user closes dialog box.
1338 Call reject() method.
1340 \param e close event (not used)
1342 void QtxDialog::closeEvent( QCloseEvent* /*e*/ )
1348 \brief Accept the dialog box.
1350 This method is used when any accept button is pressed (usually
1353 If dialog flag QtxDialog::Accept is set, this function invokes
1354 acceptData() method, which should in this case return \c true to
1355 allow further processing.
1357 If acceptData() returns \c false, this function just returns.
1359 If acceptData() returns \c true, the Accepted result is set
1360 and signal according to the pressed control button is emitted.
1361 Then the default implementation of accept() method is called
1362 (which hides the dialog box and, depending on the dialog box flags,
1363 can close and destroy it).
1367 void QtxDialog::accept()
1371 if ( testButtonFlags( OK ) )
1372 mySender = button( OK );
1373 else if ( testButtonFlags( Yes ) )
1374 mySender = button( Yes );
1376 mySender = button( Close );
1379 if ( !mySender || !mySender->isWidgetType() ||
1380 !((QWidget*)mySender)->isEnabled() )
1383 if ( testDialogFlags( Accept ) && !acceptData() )
1392 \brief Reject the dialog box.
1394 This method is used when any reject button is pressed (usually
1395 "Close", "Cancel", "No", etc).
1397 If dialog flag QtxDialog::Reject is set, this function invokes
1398 rejectData() method, which should in this case return \c true to
1399 allow further processing.
1401 If rejectData() returns \c false, this function just returns.
1403 If rejectData() returns \c true, the Rejected result is set
1404 and signal according to the pressed control button is emitted.
1405 Then the default implementation of reject() method is called
1406 (which hides the dialog box and, depending on the dialog box flags,
1407 can close and destroy it).
1411 void QtxDialog::reject()
1413 if ( testDialogFlags( Reject ) && !rejectData() )
1418 if ( testButtonFlags( Cancel ) )
1419 mySender = button( Cancel );
1420 else if ( testButtonFlags( No ) )
1421 mySender = button( No );
1423 mySender = button( Close );
1426 if ( !mySender || !mySender->isWidgetType() ||
1427 !((QWidget*)mySender)->isEnabled() )
1436 \brief Emit signal correspondingly to the control button.
1438 void QtxDialog::emitSignal()
1440 QApplication::instance()->processEvents();
1441 QApplication::syncX();
1443 int id = buttonId( (QAbstractButton*)mySender );
1467 \brief This slot is called when user presses on of the buttons
1470 Call accept() method.
1472 void QtxDialog::onAccept()
1474 const QObject* obj = sender();
1480 \brief This slot is called when user presses on of the buttons
1481 "Cancel", "No", "Close".
1483 Call reject() method.
1486 void QtxDialog::onReject()
1488 const QObject* obj = sender();
1494 \brief Process user button click event.
1496 This method is called when user presses one of custom user buttons.
1497 Emits signal dlgButton(int) with identificator of the clicked user
1498 button passed as parameter.
1500 void QtxDialog::onButton()
1502 int id = buttonId( (QAbstractButton*)sender() );
1504 emit dlgButton( id );
1508 \brief Watch for the user button destroying.
1509 \param obj button being destroyed
1511 void QtxDialog::onDestroyed( QObject* obj )
1513 QAbstractButton* b = (QAbstractButton*)obj;
1514 int id = buttonId( b );
1518 myButton.remove( id );
1519 myPosition.remove( id );
1520 for ( AreaMap::Iterator it = myArea.begin(); it != myArea.end(); ++it )
1521 it.value()->removeButton( b );
1525 \brief Update dialog box layout when the size grip is destroyed.
1527 void QtxDialog::onSizeGripDestroyed()
1530 layout()->setMargin( 5 );
1534 \brief Adjust buttons (set equal size for all buttons).
1536 void QtxDialog::adjustButtons()
1539 for ( AreaMap::Iterator aIt = myArea.begin(); aIt != myArea.end(); ++aIt )
1541 const QList<QAbstractButton*>& lst = aIt.value()->buttons();
1542 for ( QList<QAbstractButton*>::const_iterator bIt = lst.begin(); bIt != lst.end(); ++bIt )
1543 if ( (*bIt)->isVisibleTo( this ) )
1544 minWidth = qMax( minWidth, (*bIt)->sizeHint().width() );
1547 for ( AreaMap::Iterator aItr = myArea.begin(); aItr != myArea.end(); ++aItr )
1549 const QList<QAbstractButton*>& lst = aItr.value()->buttons();
1550 for ( QList<QAbstractButton*>::const_iterator bItr = lst.begin(); bItr != lst.end(); ++bItr )
1551 if ( (*bItr)->isVisibleTo( this ) )
1552 (*bItr)->setMinimumWidth( minWidth );
1557 \fn void QtxDialog::dlgButton( int id )
1558 \brief Emitted when the user button is clicked.
1559 \param id user button identificator
1562 \fn void QtxDialog::dlgParamChanged()
1563 \brief This signal can be used in successor classes to signalize about
1564 some dialog parameter changing.
1567 \fn void QtxDialog::dlgHelp()
1568 \brief Emitted when the "Help" button is clicked.
1571 \fn void QtxDialog::dlgApply()
1572 \brief Emitted when the "Apply" button is clicked.
1575 \fn void QtxDialog::dlgOk()
1576 \brief Emitted when the "OK" button is clicked.
1579 \fn void QtxDialog::dlgNo()
1580 \brief Emitted when the "No" button is clicked.
1583 \fn void QtxDialog::dlgYes()
1584 \brief Emitted when the "Yes" button is clicked.
1587 \fn void QtxDialog::dlgClose()
1588 \brief Emitted when the "Close" button is clicked.
1591 \fn void QtxDialog::dlgCancel()
1592 \brief Emitted when the "Cancel" button is clicked.