libyui-qt  2.53.0
YQMainWinDock.cc
1 /*
2  Copyright (C) 2000-2012 Novell, Inc
3  This library is free software; you can redistribute it and/or modify
4  it under the terms of the GNU Lesser General Public License as
5  published by the Free Software Foundation; either version 2.1 of the
6  License, or (at your option) version 3.0 of the License. This library
7  is distributed in the hope that it will be useful, but WITHOUT ANY
8  WARRANTY; without even the implied warranty of MERCHANTABILITY or
9  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
10  License for more details. You should have received a copy of the GNU
11  Lesser General Public License along with this library; if not, write
12  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
13  Floor, Boston, MA 02110-1301 USA
14 */
15 
16 
17 /*-/
18 
19  File: YQMainWinDock.cc
20 
21  Author: Stefan Hundhammer <sh@suse.de>
22 
23 /-*/
24 
25 
26 #define YUILogComponent "qt-ui"
27 #include <yui/YUILog.h>
28 #include <QResizeEvent>
29 #include "YQDialog.h"
30 #include <YQUI.h>
31 #include <yui/YEvent.h>
32 #include "YQWizard.h"
33 #include "YQMainWinDock.h"
34 
35 #define VERBOSE_RESIZE 1
36 
37 
40 {
41  static YQMainWinDock * mainWinDock = 0;
42 
43  if ( ! mainWinDock )
44  mainWinDock = new YQMainWinDock();
45 
46  return mainWinDock;
47 }
48 
49 
51  : QWidget( 0, // parent, name
52  YQUI::ui()->noBorder() ?
53  Qt::FramelessWindowHint :
54  Qt::Window ),
55  _sideBarWidth( 0 )
56 {
57  setFocusPolicy( Qt::StrongFocus );
58 
59  resize( YQUI::ui()->defaultSize( YD_HORIZ ),
60  YQUI::ui()->defaultSize( YD_VERT ) );
61 
62  yuiDebug() << "MainWinDock initial size: "
63  << size().width() << " x " << size().height()
64  << endl;
65 }
66 
67 
69 {
70  // NOP
71 }
72 
73 
74 void
75 YQMainWinDock::resizeEvent( QResizeEvent * event )
76 {
77  if ( event )
78  {
79  resize( event->size() );
81  }
82 }
83 
84 
85 void
87 {
88  for ( YQWidgetStack::reverse_iterator it = _widgetStack.rbegin(); it != _widgetStack.rend(); it++ )
89  {
90  YQDialog * dialog = *it;
91 
92  QRect rect = QRect( QPoint( 0, 0 ), size() );
93 
94  YQWizard * wizard = dialog->findWizard();
95 
96  if ( wizard )
97  yuiDebug() << dialog << " with " << wizard << " isSecondary: " << std::boolalpha << wizard->isSecondary() << endl;
98 
99  if ( wizard && wizard->isSecondary() )
100  {
101  if ( QApplication::isLeftToRight() )
102  rect.setLeft( 0 );
103  else
104  rect.setWidth( rect.width() );
105  }
106 
107  if ( dialog->rect() != rect )
108  {
109 #if VERBOSE_RESIZE
110  yuiDebug() << "Resizing child dialog " << std::hex << ( (void *) dialog ) << std::dec
111  << " to " << rect.width() << " x " << rect.height()
112  << endl;
113 #endif
114  dialog->setGeometry( rect );
115  }
116  }
117 }
118 
119 
120 void
122 {
123  QWidget::show();
124 
125  if ( ! _widgetStack.empty() )
126  {
127  QWidget * dialog = _widgetStack.back();
128  dialog->raise();
129  dialog->show();
130  }
131 }
132 
133 
134 void
136 {
137  YUI_CHECK_PTR( dialog );
138 
139  // Deactivate the next-lower dialog
140  // (the one that currently still is the topmost on the _widgetStack)
141  activateCurrentDialog( false );
142 
143  dialog->raise();
144  dialog->show();
145 
146  yuiDebug() << "Adding dialog " << std::hex << (void *) dialog << std::dec
147  << " to mainWinDock"
148  << endl;
149 
150  _widgetStack.push_back( dialog );
152 
153  show();
154 }
155 
156 
157 void
159 {
160  if ( _widgetStack.empty() )
161  return;
162 
163  // In the normal case, the (still or again) topmost dialog needs to be
164  // activated or deactivated directly. Since this is done on the QWidget
165  // level, its widgetRep() is needed -- which may or may not be the same as
166  // the YQDialog.
167 
168  YQDialog * dialog = _widgetStack.back();
169  QWidget * widget = (QWidget *) dialog->widgetRep();
170 
171 
172  // But then, there is also the exceptional case that this dialog contains a
173  // wizard with a steps panel. In that case, the steps panel should remain
174  // untouched; only the right side (the work area) of that wizard is to be
175  // activated or deactivated.
176 
177  // probably no longer needed, now the windows (even with steps) fully overlap ??
178  /*YQWizard * wizard = dialog->findWizard();
179 
180  if ( wizard && wizard->wizardMode() == YWizardMode_Steps )
181  {
182  QWidget * wizardWorkArea = wizard->workArea();
183 
184  if ( wizardWorkArea )
185  widget = wizardWorkArea;
186  // else -> stick with dialog->widgetRep()
187  }*/
188 
189  if ( widget )
190  widget->setEnabled( active );
191 }
192 
193 
194 void
196 {
197  if ( ! _widgetStack.empty() )
198  {
199  QWidget * dialog = _widgetStack.back();
200  yuiDebug() << "Showing dialog " << std::hex << (void *) dialog << std::dec << endl;
201  dialog->raise();
202  update();
203  }
204 }
205 
206 
207 void
209 {
210  if ( _widgetStack.empty() )
211  return;
212 
213  if ( ! dialog )
214  dialog = _widgetStack.back();
215 
216  if ( dialog == _widgetStack.back() )
217  {
218  // The most common case:
219  // The topmost dialog is to be removed
220 
221  _widgetStack.pop_back();
222 
223  yuiDebug() << "Removing dialog " << std::hex << (void *) dialog << std::dec
224  <<" from mainWinDock"
225  << endl;
226  }
227  else // The less common (but more generic) case: Remove any dialog
228  {
229  YQMainWinDock::YQWidgetStack::iterator pos = findInStack( dialog );
230 
231  if ( pos == _widgetStack.end() )
232  return;
233 
234  yuiWarning() << "Found dialog somewhere in the middle of the widget stack" << endl;
235  yuiDebug() << "Removing dialog " << std::hex << (void *) dialog << std::dec
236  << " from mainWinDock"
237  << endl;
238 
239  _widgetStack.erase( pos );
240  }
241 
242  if ( _widgetStack.empty() ) // No more main dialog?
243  hide(); // -> hide dock
244  else
245  {
246  dialog = _widgetStack.back(); // Get the next dialog from the stack
247  dialog->raise(); // and raise it
248  activateCurrentDialog( true );
249  dialog->show();
251  }
252 }
253 
254 
255 YQMainWinDock::YQWidgetStack::iterator
256 YQMainWinDock::findInStack( YQDialog * dialog )
257 {
258  for ( YQMainWinDock::YQWidgetStack::iterator it = _widgetStack.begin();
259  it != _widgetStack.end();
260  ++it )
261  {
262  if ( *it == dialog )
263  return it;
264  }
265 
266  return _widgetStack.end();
267 }
268 
269 
270 YQDialog *
272 {
273  if ( _widgetStack.empty() )
274  return 0;
275  else
276  return _widgetStack.back();
277 }
278 
279 
280 bool
282 {
283  YDialog * topDialog = YDialog::topmostDialog( false ); // don't throw
284 
285  if ( ! topDialog ) // No dialog at all?
286  return true; // Can dock the next one without problems
287 
288  // The next dialog can be docked if there is no popup dialog currently open.
289  // This is equivalent to the topmost dialog on the YDialog stack being the
290  // same dialog as the topmost dialog of this MainWinDock.
291 
292  return topDialog->widgetRep() == this->topmostDialog();
293 }
294 
295 
296 void
297 YQMainWinDock::closeEvent( QCloseEvent * event )
298 {
299  // The window manager "close window" button (and WM menu, e.g. Alt-F4) will be
300  // handled just like the user had clicked on the `id`( `cancel ) button in
301  // that dialog. It's up to the YCP application to handle this (if desired).
302 
303  yuiMilestone() << "Caught window manager close event - returning with YCancelEvent" << endl;
304  event->ignore();
305  YQUI::ui()->sendEvent( new YCancelEvent() );
306 }
307 
308 
309 void
310 YQMainWinDock::paintEvent( QPaintEvent * event )
311 {
312  // NOP
313 }
314 
315 
316 void
318 {
319  if ( _sideBarWidth == width )
320  return;
321 
322  _sideBarWidth = width;
324 }
YQWizard * findWizard() const
Find the first wizard in that dialog, if there is any.
Definition: YQDialog.cc:425
virtual void setEnabled(bool enabled)
Set enabled/disabled state.
Definition: YQDialog.cc:253
Container window for YQDialogs of type YMainWindowDialog:
Definition: YQMainWinDock.h:52
virtual void show()
Show the widget (make it visible).
void activateCurrentDialog(bool active)
Activate or deactivate the next-lower dialog in the dock when a new dialog is opened or when a dialog...
void setSideBarWidth(int width)
For secondary wizards.
YQDialog * topmostDialog() const
Return the current topmost dialog (the widgetRep() of a YQDialog) or 0 if there is none.
static YQMainWinDock * mainWinDock()
Static method to access the singleton for this class.
virtual ~YQMainWinDock()
Destructor.
void remove(YQDialog *dialog=0)
Remove a dialog from the MainWinDock (if it belongs to the MainWinDock).
virtual void resizeEvent(QResizeEvent *event)
Resize event.
void resizeVisibleChild()
Resize the visible child to the current size of the dock.
virtual void paintEvent(QPaintEvent *event)
Paint event.
virtual void closeEvent(QCloseEvent *event)
Window manager close event (Alt-F4): Send a YCancelEvent and let the application handle that event.
void add(YQDialog *dialog)
Add a dialog (the widgetRep() of a YQDialog) to the MainWinDock (on top of its widget stack.
bool couldDock()
Return 'true' if the next main dialog could be docked, i.e., if there is either no open dialog at all...
YQMainWinDock()
Constructor.
void showCurrentDialog()
Show the current dialog.
Definition: YQUI.h:63
static YQUI * ui()
Access the global Qt-UI.
Definition: YQUI.h:83
void sendEvent(YEvent *event)
Widget event handlers (slots) call this when an event occured that should be the answer to a UserInpu...
Definition: YQUI.cc:480
bool isSecondary() const
Returns true if the wizard should follow the first wizard with steps.
Definition: YQWizard.cc:208