libyui-qt  2.47.1.1
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  << std::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() << std::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  << std::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  << std::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 << std::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  << std::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" << std::endl;
235  yuiDebug() << "Removing dialog " << std::hex << (void *) dialog << std::dec
236  << " from mainWinDock"
237  << std::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" << std::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 }
325 
326 
327 #include "YQMainWinDock.moc"
void showCurrentDialog()
Show the current dialog.
bool isSecondary() const
Returns true if the wizard should follow the first wizard with steps.
Definition: YQWizard.cc:208
YQMainWinDock()
Constructor.
virtual ~YQMainWinDock()
Destructor.
void remove(YQDialog *dialog=0)
Remove a dialog from the MainWinDock (if it belongs to the MainWinDock).
void setSideBarWidth(int width)
For secondary wizards.
YQWizard * findWizard() const
Find the first wizard in that dialog, if there is any.
Definition: YQDialog.cc:426
void activateCurrentDialog(bool active)
Activate or deactivate the next-lower dialog in the dock when a new dialog is opened or when a dialog...
virtual void resizeEvent(QResizeEvent *event)
Resize event.
void add(YQDialog *dialog)
Add a dialog (the widgetRep() of a YQDialog) to the MainWinDock (on top of its widget stack...
Container window for YQDialogs of type YMainWindowDialog:
Definition: YQMainWinDock.h:51
void resizeVisibleChild()
Resize the visible child to the current size of the dock.
virtual void setEnabled(bool enabled)
Set enabled/disabled state.
Definition: YQDialog.cc:254
bool couldDock()
Return &#39;true&#39; if the next main dialog could be docked, i.e., if there is either no open dialog at all...
static YQMainWinDock * mainWinDock()
Static method to access the singleton for this class.
virtual void paintEvent(QPaintEvent *event)
Paint event.
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:494
Definition: YQUI.h:61
virtual void show()
Show the widget (make it visible).
virtual void closeEvent(QCloseEvent *event)
Window manager close event (Alt-F4): Send a YCancelEvent and let the application handle that event...
static YQUI * ui()
Access the global Qt-UI.
Definition: YQUI.h:80
YQDialog * topmostDialog() const
Return the current topmost dialog (the widgetRep() of a YQDialog) or 0 if there is none...