]> icculus.org git repositories - duncan/yast2-qt4.git/blob - src/pkg/YQPatternSelector.cc
don't create QObjects in ycp thread - make timeouts work
[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( this );
109
110     QSplitter * outer_splitter = new QSplitter( Qt::Horizontal, this );
111     Q_CHECK_PTR( outer_splitter );
112
113     vbox->addWidget( outer_splitter );
114
115     QWidget * left_pane  = layoutLeftPane ( outer_splitter );
116     QWidget * right_pane = layoutRightPane( outer_splitter );
117
118     int left_pane_width = (int) ( 0.3 * YQUI::ui()->defaultSize( YD_HORIZ ) );
119     left_pane->resize( QSize( left_pane_width, left_pane->height() ) );
120
121     outer_splitter->setStretchFactor(outer_splitter->indexOf(left_pane), 0);
122     outer_splitter->setStretchFactor(outer_splitter->indexOf(right_pane), 1);
123
124     if ( ! _wizard )
125         layoutButtons( this );
126 }
127
128
129
130 QWidget *
131 YQPatternSelector::layoutLeftPane( QWidget * parent )
132 {
133     QWidget *vbox = new QWidget(parent);
134     QVBoxLayout * layout = new QVBoxLayout( vbox );
135     Q_CHECK_PTR( vbox );
136     layout->setMargin( MARGIN );
137     vbox->setLayout(layout);
138
139     if ( ! zyppPool().empty<zypp::Pattern>() )
140     {
141         //
142         // Patterns list
143         //
144
145         _patternList = new YQPkgPatternList( vbox,
146                                              false,     // no autoFill - need to connect to details view first
147                                              false );   // no autoFilter - filterMatch() is not connected
148         Q_CHECK_PTR( _patternList );
149   layout->addWidget(_patternList);
150          _patternList->header()->hide();
151     }
152
153     if ( ! _patternList )
154     {
155         //
156         // Fallback: selections list
157         //
158
159         /**
160          * Create a selections list even if there are no selections, otherwise
161          * the layout will look very weird. An empty selections list still
162          * looks better than a lot of grey empty space.
163          **/
164
165         y2warning( "No patterns in ZyppPool - using selections instead" );
166         _selList = new YQPkgSelList( vbox,
167                                      false,     // no autoFill - need to connect to details view first
168                                      false );   // no autoFilter - filterMatch() is not connected
169         Q_CHECK_PTR( _selList );
170   layout->addWidget(_selList);
171         _selList->header()->hide();
172     }
173
174     if ( _wizard )      // No button box - add "Details..." button here
175     {
176         //
177         // "Details" button
178         //
179
180         layout->addSpacing( SPACING );
181
182         QHBoxLayout * hbox = new QHBoxLayout();
183         Q_CHECK_PTR( hbox );
184   layout->addLayout(hbox);
185
186         QPushButton * details_button = new QPushButton( _( "&Details..." ), vbox );
187         Q_CHECK_PTR( details_button );
188   hbox->addWidget(details_button);
189
190         connect( details_button, SIGNAL( clicked() ),
191                  this,           SLOT  ( detailedPackageSelection() ) );
192
193         hbox->addStretch();
194     }
195
196     return vbox;
197 }
198
199
200
201 QWidget *
202 YQPatternSelector::layoutRightPane( QWidget * parent )
203 {
204     QSplitter * splitter = new QSplitter( Qt::Vertical, parent );
205     Q_CHECK_PTR( splitter );
206     //splitter->setMargin( MARGIN );
207
208
209     //
210     // Selection / Pattern description
211     //
212     QWidget *upper_vbox = new QWidget(splitter);
213     QVBoxLayout * layout = new QVBoxLayout(upper_vbox);
214     
215     Q_CHECK_PTR( upper_vbox );
216
217     _descriptionView = new YQPkgSelDescriptionView( upper_vbox );
218     Q_CHECK_PTR( _descriptionView );
219     layout->addWidget(_descriptionView);
220
221     layout->addSpacing( MARGIN );
222
223
224     //
225     // Disk usage
226     //
227
228     QWidget *lower_vbox = new QWidget(splitter);
229     layout = new QVBoxLayout(upper_vbox);
230
231     Q_CHECK_PTR( lower_vbox );
232     layout->addSpacing( MARGIN );
233
234     _diskUsageList = new YQPkgDiskUsageList( lower_vbox );
235     Q_CHECK_PTR( _diskUsageList );
236     layout->addWidget(_diskUsageList);
237
238     splitter->setStretchFactor( 0, 0 );
239     splitter->setStretchFactor( 0, 1 );
240
241     return splitter;
242 }
243
244
245
246 void
247 YQPatternSelector::layoutButtons( QWidget * parent )
248 {
249     QWidget *button_box = new QWidget(parent);
250     QHBoxLayout *layout = new QHBoxLayout(button_box);
251
252     Q_CHECK_PTR( button_box );
253     layout->setMargin ( MARGIN  );
254     layout->setSpacing( SPACING );
255
256    button_box->setLayout(layout);
257
258     QPushButton * details_button = new QPushButton( _( "&Details..." ), button_box );
259     layout->addWidget(details_button);
260     Q_CHECK_PTR( details_button );
261     details_button->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ) ); // hor/vert
262
263     connect( details_button,    SIGNAL( clicked() ),
264              this,              SLOT  ( detailedPackageSelection() ) );
265
266
267     layout->addStretch();
268
269     QPushButton * cancel_button = new QPushButton( _( "&Cancel" ), button_box );
270     Q_CHECK_PTR( cancel_button );
271     layout->addWidget(cancel_button);
272     cancel_button->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ) ); // hor/vert
273
274     connect( cancel_button, SIGNAL( clicked() ),
275              this,          SLOT  ( reject()   ) );
276
277
278     QPushButton * accept_button = new QPushButton( _( "&Accept" ), button_box );
279     Q_CHECK_PTR( accept_button );
280     layout->addWidget(accept_button);
281     accept_button->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ) ); // hor/vert
282
283     connect( accept_button, SIGNAL( clicked() ),
284              this,          SLOT  ( accept()   ) );
285
286     button_box->setFixedHeight( button_box->sizeHint().height() );
287 }
288
289
290
291 void
292 YQPatternSelector::makeConnections()
293 {
294     if ( _patternList )
295     {
296 #if ALWAYS_SOLVE_IMMEDIATELY
297         connect( _patternList,          SIGNAL( statusChanged()         ),
298                  this,                  SLOT  ( resolveDependencies()   ) );
299
300         if ( _pkgConflictDialog )
301         {
302             connect( _pkgConflictDialog, SIGNAL( updatePackages()       ),
303                      _patternList,       SLOT  ( updateItemStates()     ) );
304         }
305 #endif
306
307         if ( _descriptionView )
308         {
309             connect( _patternList,      SIGNAL( currentItemChanged( ZyppSel ) ),
310                      _descriptionView,  SLOT  ( showDetails     ( ZyppSel ) ) );
311         }
312
313         if ( _diskUsageList )
314         {
315             connect( _patternList,      SIGNAL( updatePackages()  ),
316                      _diskUsageList,    SLOT  ( updateDiskUsage() ) );
317         }
318
319     }
320
321     if ( _selList )
322     {
323 #if ALWAYS_SOLVE_IMMEDIATELY
324         connect( _selList,              SIGNAL( statusChanged()         ),
325                  this,                  SLOT  ( resolveDependencies()   ) );
326
327         if ( _pkgConflictDialog )
328         {
329             connect( _pkgConflictDialog, SIGNAL( updatePackages()       ),
330                      _selList,           SLOT  ( updateItemStates()     ) );
331         }
332
333 #endif
334
335         if ( _descriptionView )
336         {
337             connect( _selList,          SIGNAL( currentItemChanged( ZyppSel ) ),
338                      _descriptionView,  SLOT  ( showDetails     ( ZyppSel ) ) );
339         }
340
341         if ( _diskUsageList )
342         {
343             connect( _selList,          SIGNAL( updatePackages()  ),
344                      _diskUsageList,    SLOT  ( updateDiskUsage() ) );
345         }
346     }
347
348     y2milestone( "Connection set up" );
349
350
351     if ( _wizard )
352     {
353         connect( _wizard,       SIGNAL( nextClicked()   ),
354                  this,          SLOT  ( accept()        ) );
355
356         connect( _wizard,       SIGNAL( backClicked()   ),
357                  this,          SLOT  ( reject()        ) );
358
359         connect( _wizard,       SIGNAL( abortClicked()  ),
360                  this,          SLOT  ( reject()        ) );
361     }
362 }
363
364
365 void
366 YQPatternSelector::detailedPackageSelection()
367 {
368     y2milestone( "\"Details..\" button clicked" );
369     YQUI::ui()->sendEvent( new YMenuEvent( YCPSymbol( "details" ) ) );
370 }
371
372
373 void
374 YQPatternSelector::debugTrace()
375 {
376     y2warning( "debugTrace" );
377 }
378
379
380
381 #include "YQPatternSelector.moc"