libyui-qt  2.43.5
/usr/src/RPM/BUILD/libyui-qt-2.43.5/src/YQMainWinDock.cc
00001 /*
00002   Copyright (C) 2000-2012 Novell, Inc
00003   This library is free software; you can redistribute it and/or modify
00004   it under the terms of the GNU Lesser General Public License as
00005   published by the Free Software Foundation; either version 2.1 of the
00006   License, or (at your option) version 3.0 of the License. This library
00007   is distributed in the hope that it will be useful, but WITHOUT ANY
00008   WARRANTY; without even the implied warranty of MERCHANTABILITY or
00009   FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
00010   License for more details. You should have received a copy of the GNU
00011   Lesser General Public License along with this library; if not, write
00012   to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
00013   Floor, Boston, MA 02110-1301 USA
00014 */
00015 
00016 
00017 /*-/
00018 
00019   File:       YQMainWinDock.cc
00020 
00021   Author:     Stefan Hundhammer <sh@suse.de>
00022 
00023 /-*/
00024 
00025 
00026 #define YUILogComponent "qt-ui"
00027 #include <yui/YUILog.h>
00028 #include <QResizeEvent>
00029 #include "YQDialog.h"
00030 #include <YQUI.h>
00031 #include <yui/YEvent.h>
00032 #include "YQWizard.h"
00033 #include "YQMainWinDock.h"
00034 
00035 #define VERBOSE_RESIZE 1
00036 
00037 
00038 YQMainWinDock *
00039 YQMainWinDock::mainWinDock()
00040 {
00041     static YQMainWinDock * mainWinDock = 0;
00042 
00043     if ( ! mainWinDock )
00044         mainWinDock = new YQMainWinDock();
00045 
00046     return mainWinDock;
00047 }
00048 
00049 
00050 YQMainWinDock::YQMainWinDock()
00051     : QWidget( 0, // parent, name
00052                YQUI::ui()->noBorder() ?
00053                Qt::FramelessWindowHint :
00054                Qt::Window ),
00055       _sideBarWidth( 0 )
00056 {
00057     setFocusPolicy( Qt::StrongFocus );
00058 
00059     resize( YQUI::ui()->defaultSize( YD_HORIZ ),
00060             YQUI::ui()->defaultSize( YD_VERT  ) );
00061 
00062     yuiDebug() << "MainWinDock initial size: "
00063                << size().width() << " x " << size().height()
00064                << std::endl;
00065 }
00066 
00067 
00068 YQMainWinDock::~YQMainWinDock()
00069 {
00070     // NOP
00071 }
00072 
00073 
00074 void
00075 YQMainWinDock::resizeEvent( QResizeEvent * event )
00076 {
00077     if ( event )
00078     {
00079         resize( event->size() );
00080         resizeVisibleChild();
00081     }
00082 }
00083 
00084 
00085 void
00086 YQMainWinDock::resizeVisibleChild()
00087 {
00088     for ( YQWidgetStack::reverse_iterator it = _widgetStack.rbegin(); it != _widgetStack.rend(); it++ )
00089     {
00090         YQDialog * dialog = *it;
00091 
00092         QRect rect = QRect( QPoint( 0, 0 ), size() );
00093 
00094         YQWizard * wizard = dialog->findWizard();
00095 
00096         if ( wizard )
00097             yuiDebug() << dialog << " with " << wizard << " isSecondary: " << std::boolalpha << wizard->isSecondary() << std::endl;
00098 
00099         if ( wizard && wizard->isSecondary() )
00100         {
00101             if ( QApplication::isLeftToRight() )
00102                 rect.setLeft( 0 );
00103             else
00104                 rect.setWidth( rect.width() );
00105         }
00106 
00107         if ( dialog->rect() != rect )
00108         {
00109 #if VERBOSE_RESIZE
00110             yuiDebug() << "Resizing child dialog " << std::hex << ( (void *) dialog ) << std::dec
00111                        << " to " << rect.width() << " x " << rect.height()
00112                        << std::endl;
00113 #endif
00114             dialog->setGeometry( rect );
00115         }
00116     }
00117 }
00118 
00119 
00120 void
00121 YQMainWinDock::show()
00122 {
00123     QWidget::show();
00124 
00125     if ( ! _widgetStack.empty() )
00126     {
00127         QWidget * dialog = _widgetStack.back();
00128         dialog->raise();
00129         dialog->show();
00130     }
00131 }
00132 
00133 
00134 void
00135 YQMainWinDock::add( YQDialog * dialog )
00136 {
00137     YUI_CHECK_PTR( dialog );
00138 
00139     // Deactivate the next-lower dialog
00140     // (the one that currently still is the topmost on the _widgetStack)
00141     activateCurrentDialog( false );
00142 
00143     dialog->raise();
00144     dialog->show();
00145 
00146     yuiDebug() << "Adding dialog " << std::hex << (void *) dialog << std::dec
00147                << "  to mainWinDock"
00148                << std::endl;
00149 
00150     _widgetStack.push_back( dialog );
00151     resizeVisibleChild();
00152 
00153     show();
00154 }
00155 
00156 
00157 void
00158 YQMainWinDock::activateCurrentDialog( bool active )
00159 {
00160     if ( _widgetStack.empty() )
00161         return;
00162 
00163     // In the normal case, the (still or again) topmost dialog needs to be
00164     // activated or deactivated directly. Since this is done on the QWidget
00165     // level, its widgetRep() is needed -- which may or may not be the same as
00166     // the YQDialog.
00167 
00168     YQDialog * dialog = _widgetStack.back();
00169     QWidget  * widget = (QWidget *) dialog->widgetRep();
00170 
00171 
00172     // But then, there is also the exceptional case that this dialog contains a
00173     // wizard with a steps panel. In that case, the steps panel should remain
00174     // untouched; only the right side (the work area) of that wizard is to be
00175     // activated or deactivated.
00176 
00177     // probably no longer needed, now the windows (even with steps) fully overlap ??
00178     /*YQWizard * wizard = dialog->findWizard();
00179 
00180     if ( wizard && wizard->wizardMode() == YWizardMode_Steps )
00181     {
00182         QWidget * wizardWorkArea = wizard->workArea();
00183 
00184         if ( wizardWorkArea )
00185             widget = wizardWorkArea;
00186         // else -> stick with dialog->widgetRep()
00187     }*/
00188 
00189     if ( widget )
00190         widget->setEnabled( active );
00191 }
00192 
00193 
00194 void
00195 YQMainWinDock::showCurrentDialog()
00196 {
00197     if ( ! _widgetStack.empty() )
00198     {
00199         QWidget * dialog = _widgetStack.back();
00200         yuiDebug() << "Showing dialog " << std::hex << (void *) dialog << std::dec << std::endl;
00201         dialog->raise();
00202         update();
00203     }
00204 }
00205 
00206 
00207 void
00208 YQMainWinDock::remove( YQDialog * dialog )
00209 {
00210     if ( _widgetStack.empty() )
00211         return;
00212 
00213     if ( ! dialog )
00214         dialog = _widgetStack.back();
00215 
00216     if ( dialog == _widgetStack.back() )
00217     {
00218         // The most common case:
00219         // The topmost dialog is to be removed
00220 
00221         _widgetStack.pop_back();
00222 
00223         yuiDebug() << "Removing dialog " << std::hex << (void *) dialog << std::dec
00224                    <<" from mainWinDock"
00225                    << std::endl;
00226     }
00227     else // The less common (but more generic) case: Remove any dialog
00228     {
00229         YQMainWinDock::YQWidgetStack::iterator pos = findInStack( dialog );
00230 
00231         if ( pos == _widgetStack.end() )
00232             return;
00233 
00234         yuiWarning() << "Found dialog somewhere in the middle of the widget stack" << std::endl;
00235         yuiDebug() << "Removing dialog " << std::hex << (void *) dialog << std::dec
00236                    << " from mainWinDock"
00237                    << std::endl;
00238 
00239         _widgetStack.erase( pos );
00240     }
00241 
00242     if ( _widgetStack.empty() )         // No more main dialog?
00243         hide();                         // -> hide dock
00244     else
00245     {
00246         dialog = _widgetStack.back();   // Get the next dialog from the stack
00247         dialog->raise();                // and raise it
00248         activateCurrentDialog( true );
00249         dialog->show();
00250         resizeVisibleChild();
00251     }
00252 }
00253 
00254 
00255 YQMainWinDock::YQWidgetStack::iterator
00256 YQMainWinDock::findInStack( YQDialog * dialog )
00257 {
00258     for ( YQMainWinDock::YQWidgetStack::iterator it = _widgetStack.begin();
00259           it != _widgetStack.end();
00260           ++it )
00261     {
00262         if ( *it == dialog )
00263             return it;
00264     }
00265 
00266     return _widgetStack.end();
00267 }
00268 
00269 
00270 YQDialog *
00271 YQMainWinDock::topmostDialog() const
00272 {
00273     if ( _widgetStack.empty() )
00274         return 0;
00275     else
00276         return _widgetStack.back();
00277 }
00278 
00279 
00280 bool
00281 YQMainWinDock::couldDock()
00282 {
00283     YDialog * topDialog = YDialog::topmostDialog( false ); // don't throw
00284 
00285     if ( ! topDialog )  // No dialog at all?
00286         return true;    // Can dock the next one without problems
00287 
00288     // The next dialog can be docked if there is no popup dialog currently open.
00289     // This is equivalent to the topmost dialog on the YDialog stack being the
00290     // same dialog as the topmost dialog of this MainWinDock.
00291 
00292     return topDialog->widgetRep() == this->topmostDialog();
00293 }
00294 
00295 
00296 void
00297 YQMainWinDock::closeEvent( QCloseEvent * event )
00298 {
00299     // The window manager "close window" button (and WM menu, e.g. Alt-F4) will be
00300     // handled just like the user had clicked on the `id`( `cancel ) button in
00301     // that dialog. It's up to the YCP application to handle this (if desired).
00302 
00303     yuiMilestone() << "Caught window manager close event - returning with YCancelEvent" << std::endl;
00304     event->ignore();
00305     YQUI::ui()->sendEvent( new YCancelEvent() );
00306 }
00307 
00308 
00309 void
00310 YQMainWinDock::paintEvent( QPaintEvent * event )
00311 {
00312     // NOP
00313 }
00314 
00315 
00316 void
00317 YQMainWinDock::setSideBarWidth( int width )
00318 {
00319     if ( _sideBarWidth == width )
00320         return;
00321 
00322     _sideBarWidth = width;
00323     resizeVisibleChild();
00324 }
00325 
00326 
00327 #include "YQMainWinDock.moc"
 All Classes Functions Variables