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