- Don't create layouts with parent. Qt 4.x automatically reparents
[duncan/yast2-qt4.git] / src / pkg / YQPatternSelector.cc
1 /*---------------------------------------------------------------------\
2 |                                                                      |
3 |                      __   __    ____ _____ ____                      |
4 |                      \ \ / /_ _/ ___|_   _|___ \                     |
5 |                       \ V / _` \___ \ | |   __) |                    |
6 |                        | | (_| |___) || |  / __/                     |
7 |                        |_|\__,_|____/ |_| |_____|                    |
8 |                                                                      |
9 |                               core system                            |
10 |                                                        (C) SuSE GmbH |
11 \----------------------------------------------------------------------/
12
13   File:       YQPatternSelector.cc
14   See also:   YQPatternSelectorHelp.cc
15
16   Author:     Stefan Hundhammer <sh@suse.de>
17
18   Textdomain "packages-qt"
19
20 /-*/
21
22 #include <QApplication>
23 #include <QHeaderView>
24 #include <QPushButton>
25 #include <QSplitter>
26
27 #define y2log_component "qt-pkg"
28 #include <ycp/y2log.h>
29
30 #include "QY2LayoutUtils.h"
31
32 #include "YQPatternSelector.h"
33 #include "YQPkgConflictDialog.h"
34 #include "YQPkgSelDescriptionView.h"
35 #include "YQPkgDiskUsageList.h"
36 #include "YQPkgPatternList.h"
37 #include "YQPkgSelList.h"
38 #include "YQWizard.h"
39 #include "YQDialog.h"
40
41 #include "utf8.h"
42 #include "YQUI.h"
43 #include "YEvent.h"
44 #include "YQi18n.h"
45
46 #define ALWAYS_SOLVE_IMMEDIATELY 1
47
48 using std::max;
49 using std::string;
50
51 #define SPACING                 6
52 #define MARGIN                  6
53
54
55 YQPatternSelector::YQPatternSelector( YWidget * parent, long modeFlags )
56     : YQPackageSelectorBase( parent, modeFlags )
57 {
58     _patternList                = 0;
59     _selList                    = 0;
60     _descriptionView            = 0;
61     _wizard                     = findWizard();
62
63     basicLayout();
64     makeConnections();
65
66     if ( _patternList )
67     {
68         _patternList->fillList();
69         _patternList->selectSomething();
70     }
71     else if ( _selList )
72     {
73         _selList->fillList();
74         _selList->selectSomething();
75     }
76
77     if ( zyppPool().empty<zypp::Pattern  >() &&
78          zyppPool().empty<zypp::Selection>()   )
79     {
80         y2warning( "Neither patterns nor selections in ZyppPool" );
81     }
82
83
84     if ( _diskUsageList )
85         _diskUsageList->updateDiskUsage();
86 }
87
88
89
90 YQWizard *
91 YQPatternSelector::findWizard() const
92 {
93     YQWizard * wizard = 0;
94
95     YQDialog * dialog = dynamic_cast<YQDialog *> ( YDialog::currentDialog() );
96
97     if ( dialog )
98         wizard = dialog->findWizard();
99
100     return wizard;
101 }
102
103
104
105 void
106 YQPatternSelector::basicLayout()
107 {
108     QVBoxLayout *vbox = new QVBoxLayout();
109     setLayout(vbox);
110
111     QSplitter * outer_splitter = new QSplitter( Qt::Horizontal, this );
112     Q_CHECK_PTR( outer_splitter );
113
114     vbox->addWidget( outer_splitter );
115
116     QWidget * left_pane  = layoutLeftPane ( outer_splitter );
117     QWidget * right_pane = layoutRightPane( outer_splitter );
118
119     int left_pane_width = (int) ( 0.3 * YQUI::ui()->defaultSize( YD_HORIZ ) );
120     left_pane->resize( QSize( left_pane_width, left_pane->height() ) );
121
122     outer_splitter->setStretchFactor(outer_splitter->indexOf(left_pane), 0);
123     outer_splitter->setStretchFactor(outer_splitter->indexOf(right_pane), 1);
124
125     if ( ! _wizard )
126         layoutButtons( this );
127 }
128
129
130
131 QWidget *
132 YQPatternSelector::layoutLeftPane( QWidget * parent )
133 {
134     QWidget *vbox = new QWidget(parent);
135     QVBoxLayout * layout = new QVBoxLayout( vbox );
136     Q_CHECK_PTR( vbox );
137     layout->setMargin( MARGIN );
138     vbox->setLayout(layout);
139
140     if ( ! zyppPool().empty<zypp::Pattern>() )
141     {
142         //
143         // Patterns list
144         //
145
146         _patternList = new YQPkgPatternList( vbox,
147                                              false,     // no autoFill - need to connect to details view first
148                                              false );   // no autoFilter - filterMatch() is not connected
149         Q_CHECK_PTR( _patternList );
150   layout->addWidget(_patternList);
151          _patternList->header()->hide();
152     }
153
154     if ( ! _patternList )
155     {
156         //
157         // Fallback: selections list
158         //
159
160         /**
161          * Create a selections list even if there are no selections, otherwise
162          * the layout will look very weird. An empty selections list still
163          * looks better than a lot of grey empty space.
164          **/
165
166         y2warning( "No patterns in ZyppPool - using selections instead" );
167         _selList = new YQPkgSelList( vbox,
168                                      false,     // no autoFill - need to connect to details view first
169                                      false );   // no autoFilter - filterMatch() is not connected
170         Q_CHECK_PTR( _selList );
171   layout->addWidget(_selList);
172         _selList->header()->hide();
173     }
174
175     if ( _wizard )      // No button box - add "Details..." button here
176     {
177         //
178         // "Details" button
179         //
180
181         layout->addSpacing( SPACING );
182
183         QHBoxLayout * hbox = new QHBoxLayout();
184         Q_CHECK_PTR( hbox );
185   layout->addLayout(hbox);
186
187         QPushButton * details_button = new QPushButton( _( "&Details..." ), vbox );
188         Q_CHECK_PTR( details_button );
189   hbox->addWidget(details_button);
190
191         connect( details_button, SIGNAL( clicked() ),
192                  this,           SLOT  ( detailedPackageSelection() ) );
193
194         hbox->addStretch();
195     }
196
197     return vbox;
198 }
199
200
201
202 QWidget *
203 YQPatternSelector::layoutRightPane( QWidget * parent )
204 {
205     QSplitter * splitter = new QSplitter( Qt::Vertical, parent );
206     Q_CHECK_PTR( splitter );
207     //splitter->setMargin( MARGIN );
208
209
210     //
211     // Selection / Pattern description
212     //
213     QWidget *upper_vbox = new QWidget(splitter);
214     QVBoxLayout * layout = new QVBoxLayout(upper_vbox);
215     
216     Q_CHECK_PTR( upper_vbox );
217
218     _descriptionView = new YQPkgSelDescriptionView( upper_vbox );
219     Q_CHECK_PTR( _descriptionView );
220     layout->addWidget(_descriptionView);
221
222     layout->addSpacing( MARGIN );
223
224
225     //
226     // Disk usage
227     //
228
229     QWidget *lower_vbox = new QWidget(splitter);
230     layout = new QVBoxLayout(upper_vbox);
231
232     Q_CHECK_PTR( lower_vbox );
233     layout->addSpacing( MARGIN );
234
235     _diskUsageList = new YQPkgDiskUsageList( lower_vbox );
236     Q_CHECK_PTR( _diskUsageList );
237     layout->addWidget(_diskUsageList);
238
239     splitter->setStretchFactor( 0, 0 );
240     splitter->setStretchFactor( 0, 1 );
241
242     return splitter;
243 }
244
245
246
247 void
248 YQPatternSelector::layoutButtons( QWidget * parent )
249 {
250     QWidget *button_box = new QWidget(parent);
251     QHBoxLayout *layout = new QHBoxLayout(button_box);
252
253     Q_CHECK_PTR( button_box );
254     layout->setMargin ( MARGIN  );
255     layout->setSpacing( SPACING );
256
257    button_box->setLayout(layout);
258
259     QPushButton * details_button = new QPushButton( _( "&Details..." ), button_box );
260     layout->addWidget(details_button);
261     Q_CHECK_PTR( details_button );
262     details_button->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ) ); // hor/vert
263
264     connect( details_button,    SIGNAL( clicked() ),
265              this,              SLOT  ( detailedPackageSelection() ) );
266
267
268     layout->addStretch();
269
270     QPushButton * cancel_button = new QPushButton( _( "&Cancel" ), button_box );
271     Q_CHECK_PTR( cancel_button );
272     layout->addWidget(cancel_button);
273     cancel_button->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ) ); // hor/vert
274
275     connect( cancel_button, SIGNAL( clicked() ),
276              this,          SLOT  ( reject()   ) );
277
278
279     QPushButton * accept_button = new QPushButton( _( "&Accept" ), button_box );
280     Q_CHECK_PTR( accept_button );
281     layout->addWidget(accept_button);
282     accept_button->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ) ); // hor/vert
283
284     connect( accept_button, SIGNAL( clicked() ),
285              this,          SLOT  ( accept()   ) );
286
287     button_box->setFixedHeight( button_box->sizeHint().height() );
288 }
289
290
291
292 void
293 YQPatternSelector::makeConnections()
294 {
295     if ( _patternList )
296     {
297 #if ALWAYS_SOLVE_IMMEDIATELY
298         connect( _patternList,          SIGNAL( statusChanged()         ),
299                  this,                  SLOT  ( resolveDependencies()   ) );
300
301         if ( _pkgConflictDialog )
302         {
303             connect( _pkgConflictDialog, SIGNAL( updatePackages()       ),
304                      _patternList,       SLOT  ( updateItemStates()     ) );
305         }
306 #endif
307
308         if ( _descriptionView )
309         {
310             connect( _patternList,      SIGNAL( currentItemChanged( ZyppSel ) ),
311                      _descriptionView,  SLOT  ( showDetails     ( ZyppSel ) ) );
312         }
313
314         if ( _diskUsageList )
315         {
316             connect( _patternList,      SIGNAL( updatePackages()  ),
317                      _diskUsageList,    SLOT  ( updateDiskUsage() ) );
318         }
319
320     }
321
322     if ( _selList )
323     {
324 #if ALWAYS_SOLVE_IMMEDIATELY
325         connect( _selList,              SIGNAL( statusChanged()         ),
326                  this,                  SLOT  ( resolveDependencies()   ) );
327
328         if ( _pkgConflictDialog )
329         {
330             connect( _pkgConflictDialog, SIGNAL( updatePackages()       ),
331                      _selList,           SLOT  ( updateItemStates()     ) );
332         }
333
334 #endif
335
336         if ( _descriptionView )
337         {
338             connect( _selList,          SIGNAL( currentItemChanged( ZyppSel ) ),
339                      _descriptionView,  SLOT  ( showDetails     ( ZyppSel ) ) );
340         }
341
342         if ( _diskUsageList )
343         {
344             connect( _selList,          SIGNAL( updatePackages()  ),
345                      _diskUsageList,    SLOT  ( updateDiskUsage() ) );
346         }
347     }
348
349     y2milestone( "Connection set up" );
350
351
352     if ( _wizard )
353     {
354         connect( _wizard,       SIGNAL( nextClicked()   ),
355                  this,          SLOT  ( accept()        ) );
356
357         connect( _wizard,       SIGNAL( backClicked()   ),
358                  this,          SLOT  ( reject()        ) );
359
360         connect( _wizard,       SIGNAL( abortClicked()  ),
361                  this,          SLOT  ( reject()        ) );
362     }
363 }
364
365
366 void
367 YQPatternSelector::detailedPackageSelection()
368 {
369     y2milestone( "\"Details..\" button clicked" );
370     YQUI::ui()->sendEvent( new YMenuEvent( YCPSymbol( "details" ) ) );
371 }
372
373
374 void
375 YQPatternSelector::debugTrace()
376 {
377     y2warning( "debugTrace" );
378 }
379
380
381
382 #include "YQPatternSelector.moc"