]> icculus.org git repositories - duncan/yast2-qt4.git/blob - src/pkg/YQPkgPatternList.cc
package selector semi working!
[duncan/yast2-qt4.git] / src / pkg / YQPkgPatternList.cc
1 /*---------------------------------------------------------------------\
2 |                                                                      |
3 |                      __   __    ____ _____ ____                      |
4 |                      \ \ / /_ _/ ___|_   _|___ \                     |
5 |                       \ V / _` \___ \ | |   __) |                    |
6 |                        | | (_| |___) || |  / __/                     |
7 |                        |_|\__,_|____/ |_| |_____|                    |
8 |                                                                      |
9 |                               core system                            |
10 |                                                        (C) SuSE GmbH |
11 \----------------------------------------------------------------------/
12
13   File:       YQPkgPatternList.cc
14
15   Author:     Stefan Hundhammer <sh@suse.de>
16
17   Textdomain "packages-qt"
18
19 /-*/
20
21 #define QT3_SUPPORT 1
22
23 #define y2log_component "qt-pkg"
24 #include <ycp/y2log.h>
25 #include <QRegExp>
26 #include <zypp/ZYppFactory.h>
27 #include <zypp/Resolver.h>
28 #include <QPainter>
29 #include <QHeaderView>
30 #include <zypp/ui/PatternContents.h>
31
32 #include "YQi18n.h"
33 #include "utf8.h"
34 #include "YQPkgPatternList.h"
35 #include "YQIconPool.h"
36 #include "YQApplication.h"
37 #include "YQUI.h"
38
39
40 #define CATEGORY_BACKGROUND     QColor( 0xFF, 0xC0, 0x50 )
41
42
43 YQPkgPatternList::YQPkgPatternList( QWidget * parent, bool autoFill, bool autoFilter )
44     : YQPkgObjList( parent )
45 {
46     y2debug( "Creating pattern list" );
47
48     int numCol = 0;
49     QStringList headers;
50     headers << "";      _statusCol      = numCol++;
51
52     // Translators: "Pattern" refers to so-called "installation patterns",
53     // i.e., specific task-oriented groups of packages, like "everything that
54     // is needed to run a web server". The idea of patterns is that they also
55     // include the configuration workflow needed for that task, such of
56     // configuring the web server. For the scope of the package selector, this
57     // is only of little relevance, though.
58
59     headers << _( "Pattern" );  _summaryCol     = numCol++;
60
61     setHeaderLabels(headers);
62     // Can use the same colum for "broken" and "satisfied":
63     // Both states are mutually exclusive
64
65     _satisfiedIconCol   = _summaryCol;
66     _brokenIconCol      = _summaryCol;
67
68 //     header()->setStretchEnabled( _statusCol , false );
69 //     header()->setStretchEnabled( _summaryCol, true  );
70
71     setAllColumnsShowFocus( true );
72     //setTreeStepSize( 0 );
73
74     if ( autoFilter )
75     {
76         connect( this, SIGNAL( currentItemChanged( QTreeWidgetItem * ) ),
77                  this, SLOT  ( filter()                            ) );
78     }
79
80     if ( autoFill )
81     {
82         fillList();
83         selectSomething();
84     }
85     y2debug( "Creating pattern list done" );
86 }
87
88
89 YQPkgPatternList::~YQPkgPatternList()
90 {
91     // NOP
92 }
93
94
95 void
96 YQPkgPatternList::fillList()
97 {
98     clear();
99     y2debug( "Filling pattern list" );
100
101
102     for ( ZyppPoolIterator it = zyppPatternsBegin();
103           it != zyppPatternsEnd();
104           ++it )
105     {
106         ZyppPattern zyppPattern = tryCastToZyppPattern( (*it)->theObj() );
107
108         if ( zyppPattern )
109         {
110             if ( zyppPattern->userVisible() )
111             {
112                 addPatternItem( *it, zyppPattern );
113             }
114             else
115                 y2debug( "Pattern %s is not user-visible", zyppPattern->name().c_str() );
116         }
117         else
118         {
119             y2error( "Found non-Pattern selectable" );
120         }
121     }
122
123     y2debug( "Pattern list filled" );
124 }
125
126
127 YQPkgPatternCategoryItem *
128 YQPkgPatternList::category( const QString & categoryName )
129 {
130     if ( categoryName.isEmpty() )
131         return 0;
132
133     YQPkgPatternCategoryItem * cat = _categories[ categoryName ];
134
135     if ( ! cat )
136     {
137         y2debug( "New pattern category \"%s\"", (const char *) categoryName );
138
139         cat = new YQPkgPatternCategoryItem( this, categoryName );
140         Q_CHECK_PTR( cat );
141         _categories.insert( categoryName, cat );
142     }
143
144
145     return cat;
146 }
147
148
149 void
150 YQPkgPatternList::filterIfVisible()
151 {
152     if ( isVisible() )
153         filter();
154 }
155
156
157 void
158 YQPkgPatternList::filter()
159 {
160     emit filterStart();
161
162     if ( selection() )  // The seleted QListViewItem
163     {
164         ZyppPattern zyppPattern = selection()->zyppPattern();
165
166         if ( zyppPattern )
167         {
168             zypp::ui::PatternContents patternContents( zyppPattern );
169             set<string> wanted = patternContents.install_packages();
170
171             for ( ZyppPoolIterator it = zyppPkgBegin();
172                   it != zyppPkgEnd();
173                   ++it )
174             {
175                 string name = (*it)->theObj()->name();
176
177                 if ( contains( wanted, name ) )
178                 {
179                     ZyppPkg zyppPkg = tryCastToZyppPkg( (*it)->theObj() );
180
181                     if ( zyppPkg )
182                     {
183                         emit filterMatch( *it, zyppPkg );
184                     }
185                 }
186             }
187         }
188     }
189
190     emit filterFinished();
191 }
192
193
194 void
195 YQPkgPatternList::addPatternItem( ZyppSel       selectable,
196                                   ZyppPattern   zyppPattern )
197 {
198     if ( ! selectable )
199     {
200         y2error( "NULL ZyppSelectable!" );
201         return;
202     }
203
204     YQPkgPatternCategoryItem * cat = category( fromUTF8( zyppPattern->category() ) );
205     YQPkgPatternListItem * item = 0;
206
207     if ( cat )
208         item = new YQPkgPatternListItem( this, cat, selectable, zyppPattern );
209     else
210         item = new YQPkgPatternListItem( this, selectable, zyppPattern );
211
212     addTopLevelItem(item);
213     applyExcludeRules( item );
214 }
215
216
217 YQPkgPatternListItem *
218 YQPkgPatternList::selection() const
219 {
220 #if FIXME
221     QTreeWidgetItem * item = currentItem();
222
223     if ( ! item )
224         return 0;
225
226     return dynamic_cast<YQPkgPatternListItem *> (item);
227 #else
228     return 0;
229 #endif
230 }
231
232
233 void
234 YQPkgPatternList::pkgObjClicked( int                    button,
235                                  QTreeWidgetItem *      listViewItem,
236                                  int                    col,
237                                  const QPoint &         pos )
238 {
239 #if FIXME
240     YQPkgPatternCategoryItem * categoryItem
241         = dynamic_cast<YQPkgPatternCategoryItem *> (listViewItem);
242
243     if ( categoryItem )
244     {
245         if ( button == Qt::LeftButton )
246         {
247             if ( col == statusCol() )
248             {
249                 categoryItem->setOpen( ! categoryItem->isExpanded() );
250             }
251         }
252     }
253     else
254     {
255         YQPkgObjList::pkgObjClicked( button, listViewItem, col, pos );
256     }
257 #endif
258 }
259
260
261 void
262 YQPkgPatternList::selectSomething()
263 {
264 #if FIXME
265     QTreeWidgetItemIterator it( this );
266
267     while ( *it )
268     {
269         QY2ListViewItem * item = dynamic_cast<QY2ListViewItem *> (*it);
270         YQPkgPatternCategoryItem * categoryItem =
271             dynamic_cast<YQPkgPatternCategoryItem *> (*it);
272
273         if ( item && item->isSelectable() && ! categoryItem )
274         {
275             setSelected( item, true ); // emits signal, too
276             return;
277         }
278
279         ++it;
280     }
281 #endif
282 }
283
284 void YQPkgPatternList::drawRow ( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const
285 {
286     painter->setFont( YQUI::yqApp()->headingFont() );
287     QTreeWidget::drawRow ( painter, option, index );
288 }
289
290 YQPkgPatternListItem::YQPkgPatternListItem( YQPkgPatternList *  patternList,
291                                             ZyppSel             selectable,
292                                             ZyppPattern         zyppPattern )
293     : YQPkgObjListItem( patternList, selectable, zyppPattern )
294     , _patternList( patternList )
295     , _zyppPattern( zyppPattern )
296 {
297     init();
298 }
299
300
301 YQPkgPatternListItem::YQPkgPatternListItem( YQPkgPatternList *          patternList,
302                                             YQPkgPatternCategoryItem *  parentCategory,
303                                             ZyppSel                     selectable,
304                                             ZyppPattern                 zyppPattern )
305     : YQPkgObjListItem( patternList, parentCategory, selectable, zyppPattern )
306     , _patternList( patternList )
307     , _zyppPattern( zyppPattern )
308 {
309     init();
310     parentCategory->addPattern( _zyppPattern );
311 }
312
313
314 void
315 YQPkgPatternListItem::init()
316 {
317     if ( ! _zyppPattern )
318         _zyppPattern = tryCastToZyppPattern( selectable()->theObj() );
319
320     setStatusIcon();
321 }
322
323
324
325 YQPkgPatternListItem::~YQPkgPatternListItem()
326 {
327     // NOP
328 }
329
330
331 void
332 YQPkgPatternListItem::applyChanges()
333 {
334     solveResolvableCollections();
335 }
336
337
338
339 /**
340  * Comparison function used for sorting the list.
341  * Returns:
342  * -1 if this <  other
343  *  0 if this == other
344  * +1 if this >  other
345  **/
346 int
347 YQPkgPatternListItem::compare( QTreeWidgetItem *        otherListViewItem,
348                                int              col,
349                                bool             ascending ) const
350 {
351     YQPkgPatternListItem * otherPatternListitem  = dynamic_cast<YQPkgPatternListItem     *>(otherListViewItem);
352
353     if ( _zyppPattern && otherPatternListitem && otherPatternListitem->zyppPattern() )
354         return _zyppPattern->order().compare( otherPatternListitem->zyppPattern()->order() );
355
356     YQPkgPatternCategoryItem * otherCategoryItem = dynamic_cast<YQPkgPatternCategoryItem *>(otherListViewItem);
357
358     if ( otherCategoryItem )    // Patterns without category should always be sorted
359         return -1;              // before any category
360
361     return false; //FIXME QTreeWidgetItem::compare( otherListViewItem, col, ascending );
362 }
363
364
365
366
367
368
369 YQPkgPatternCategoryItem::YQPkgPatternCategoryItem( YQPkgPatternList *  patternList,
370                                                     const QString &     category        )
371     : QY2ListViewItem( patternList )
372     , _patternList( patternList )
373 {
374     setText( _patternList->summaryCol(), category );
375     setBackgroundColor( CATEGORY_BACKGROUND );
376     setOpen( true );
377     setTreeIcon();
378 }
379
380
381 YQPkgPatternCategoryItem::~YQPkgPatternCategoryItem()
382 {
383     // NOP
384 }
385
386 void
387 YQPkgPatternCategoryItem::addPattern( ZyppPattern pattern )
388 {
389     if ( ! _firstPattern )
390     {
391         _firstPattern = pattern;
392     }
393     else
394     {
395         if ( _firstPattern->order().compare( pattern->order() ) < 0 )
396             _firstPattern = pattern;
397     }
398 }
399
400
401 void
402 YQPkgPatternCategoryItem::setOpen( bool open )
403 {
404     //FIXME QTreeWidgetItem::setOpen( open );
405     setTreeIcon();
406 }
407
408
409 void
410 YQPkgPatternCategoryItem::setTreeIcon()
411 {
412 #if FIXME
413     setPixmap( _patternList->statusCol(),
414                isOpen() ?
415                YQIconPool::treeMinus() :
416                YQIconPool::treePlus()   );
417 #endif
418 }
419
420
421
422 /**
423  * Comparison function used for sorting the list.
424  * Returns:
425  * -1 if this <  other
426  *  0 if this == other
427  * +1 if this >  other
428  **/
429 int
430 YQPkgPatternCategoryItem::compare( QTreeWidgetItem *    otherListViewItem,
431                                    int                  col,
432                                    bool                 ascending ) const
433 {
434     YQPkgPatternCategoryItem * otherCategoryItem = dynamic_cast<YQPkgPatternCategoryItem *>(otherListViewItem);
435
436     if ( _firstPattern && otherCategoryItem && otherCategoryItem->firstPattern() )
437         return _firstPattern->order().compare( otherCategoryItem->firstPattern()->order() );
438
439
440     YQPkgPatternListItem * otherPatternListitem  = dynamic_cast<YQPkgPatternListItem *>(otherListViewItem);
441
442     if ( otherPatternListitem ) // Patterns without category should always be sorted
443         return 1;               // before any category
444
445     return false; // FIXME QTreeWidgetItem::compare( otherListViewItem, col, ascending );
446 }
447
448
449
450 #include "YQPkgPatternList.moc"