b1061fa9a75344de028ab6156ee50a4d593eb368
[duncan/yast2-qt4.git] / src / YQMainWinDock.cc
1 /*---------------------------------------------------------------------\
2 |                                                                      |
3 |                      __   __    ____ _____ ____                      |
4 |                      \ \ / /_ _/ ___|_   _|___ \                     |
5 |                       \ V / _` \___ \ | |   __) |                    |
6 |                        | | (_| |___) || |  / __/                     |
7 |                        |_|\__,_|____/ |_| |_____|                    |
8 |                                                                      |
9 |                               core system                            |
10 |                                                        (C) SuSE GmbH |
11 \----------------------------------------------------------------------/
12
13   File:       YQMainWinDock.cc
14
15   Author:     Stefan Hundhammer <sh@suse.de>
16
17 /-*/
18
19
20 #define y2log_component "qt-ui"
21 #include <ycp/y2log.h>
22 #include <QTimer>
23 #include <QResizeEvent>
24 #include <YDialog.h>
25 #include <YQUI.h>
26 #include <YEvent.h>
27 #include "YQMainWinDock.h"
28
29
30
31 YQMainWinDock *
32 YQMainWinDock::mainWinDock()
33 {
34     static YQMainWinDock * mainWinDock = 0;
35     
36     if ( ! mainWinDock )
37         mainWinDock = new YQMainWinDock();
38
39     return mainWinDock;
40 }
41
42
43 YQMainWinDock::YQMainWinDock()
44     : QWidget( 0, // parent, name
45                YQUI::ui()->noBorder() ?
46                Qt::Widget :
47                Qt::Window ) 
48 {
49     setWindowTitle( "YaST2" );
50
51     setFocusPolicy( Qt::StrongFocus );
52
53     resize( YQUI::ui()->defaultSize( YD_HORIZ ),
54             YQUI::ui()->defaultSize( YD_VERT  ) );
55
56     y2debug( "MainWinDock initial size: %d x %d",
57              size().width(), size().height() );
58 }
59
60
61 YQMainWinDock::~YQMainWinDock()
62 {
63     // NOP
64 }
65
66
67 void
68 YQMainWinDock::childEvent( QChildEvent * event )
69 {
70     if ( event )
71     {
72         QWidget * widget = dynamic_cast<QWidget *> ( event->child() );
73
74         if ( widget && ( event->type() == QEvent::ChildAdded ) )
75         {
76             add( widget );
77         }
78     }
79     
80     QWidget::childEvent( event );
81 }
82
83
84 void
85 YQMainWinDock::resizeEvent( QResizeEvent * event )
86 {
87     if ( event )
88     {
89         resize( event->size() );
90         resizeVisibleChild();
91     }
92 }
93
94
95 void
96 YQMainWinDock::resizeVisibleChild()
97 {
98     if ( ! _widgetStack.empty() )
99     {
100         QWidget * dialog = _widgetStack.back();
101
102         if ( dialog->size() != size() )
103         {
104             // y2debug( "Resizing child dialog %p to %d x %d", dialog, size().width(), size().height() );
105             dialog->resize( size() );
106         }
107     }
108 }
109
110
111 void
112 YQMainWinDock::show()
113 {
114     QWidget::show();
115     
116     if ( ! _widgetStack.empty() )
117     {
118         QWidget * dialog = _widgetStack.back();
119         dialog->raise();  
120         
121         if ( dialog->isHidden() )
122             dialog->show();
123     }
124 }
125
126
127 void
128 YQMainWinDock::add( QWidget * dialog )
129 {
130     YUI_CHECK_PTR( dialog );
131
132     if ( dialog->isHidden() )
133         dialog->show();
134
135     y2debug( "Adding dialog %p to mainWinDock", dialog );
136     _widgetStack.push_back( dialog );
137     resizeVisibleChild();
138     
139     if ( isHidden() )
140         show();
141 }
142
143
144 void
145 YQMainWinDock::showCurrentDialog()
146 {
147     if ( ! _widgetStack.empty() )
148     {
149         QWidget * dialog = _widgetStack.back();
150         y2debug( "Showing dialog %p", dialog );
151         dialog->raise();
152         update();
153     }
154 }
155
156
157 void
158 YQMainWinDock::remove( QWidget * dialog )
159 {
160     if ( _widgetStack.empty() )
161         return;
162
163     if ( ! dialog )
164         dialog = _widgetStack.back();
165
166     if ( dialog == _widgetStack.back() )
167     {
168         // The most common case:
169         // The topmost dialog is to be removed
170
171         _widgetStack.pop_back();
172
173         y2debug( "Removing dialog %p from mainWinDock", dialog );
174     }
175     else // The less common (but more generic) case: Remove any dialog
176     {
177         YQMainWinDock::YQWidgetStack::iterator pos = findInStack( dialog );
178
179         if ( pos == _widgetStack.end() )
180             return;
181
182         y2warning( "Found dialog somewhere in the middle of the widget stack" );
183         y2debug( "Removing dialog %p from mainWinDock", dialog );
184         
185         _widgetStack.erase( pos );
186     }
187
188     if ( _widgetStack.empty() )         // No more main dialog?
189         hide();                         // -> hide dock
190     else
191     {
192         dialog = _widgetStack.back();   // Get the next dialog from the stack
193         dialog->raise();                // and raise it
194         resizeVisibleChild();
195     }
196 }
197
198
199 YQMainWinDock::YQWidgetStack::iterator
200 YQMainWinDock::findInStack( QWidget * dialog )
201 {
202     for ( YQMainWinDock::YQWidgetStack::iterator it = _widgetStack.begin();
203           it != _widgetStack.end();
204           ++it )
205     {
206         if ( *it == dialog )
207             return it;
208     }
209
210     return _widgetStack.end();
211 }
212
213
214 QWidget *
215 YQMainWinDock::topmostDialog() const
216 {
217     if ( _widgetStack.empty() )
218         return 0;
219     else
220         return _widgetStack.back();
221 }
222
223
224 bool
225 YQMainWinDock::couldDock()
226 {
227     //FIXME
228     return false;
229
230     YDialog * topDialog = YDialog::topmostDialog( false ); // don't throw
231
232     if ( ! topDialog )  // No dialog at all?
233         return true;    // Can dock the next one without problems
234
235     // The next dialog can be docked if there is no popup dialog currently open.
236     // This is equivalent to the topmost dialog on the YDialog stack being the
237     // same dialog as the topmost dialog of this MainWinDock.
238
239     return topDialog->widgetRep() == this->topmostDialog();
240 }
241
242
243 void
244 YQMainWinDock::closeEvent( QCloseEvent * event )
245 {
246     // The window manager "close window" button (and WM menu, e.g. Alt-F4) will be
247     // handled just like the user had clicked on the `id`( `cancel ) button in
248     // that dialog. It's up to the YCP application to handle this (if desired).
249
250     y2milestone( "Caught window manager close event - returning with YCancelEvent" );
251     event->ignore();
252     YQUI::ui()->sendEvent( new YCancelEvent() );
253 }
254
255
256 void
257 YQMainWinDock::paintEvent( QPaintEvent * event )
258 {
259     // NOP
260 }
261
262
263 #include "YQMainWinDock.moc"