]> icculus.org git repositories - duncan/yast2-qt4.git/blob - src/pkg/YQPkgPatternList.cc
- ported listview and friends. Still does not build
[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
22 #define y2log_component "qt-pkg"
23 #include <ycp/y2log.h>
24 #include <qregexp.h>
25 #include <zypp/ZYppFactory.h>
26 #include <zypp/Resolver.h>
27 #include <qpainter.h>
28 #include <q3header.h>
29 #include <zypp/ui/PatternContents.h>
30
31 #include "YQi18n.h"
32 #include "utf8.h"
33 #include "YQPkgPatternList.h"
34 #include "YQIconPool.h"
35 #include "YQApplication.h"
36 #include "YQUI.h"
37
38
39 #define CATEGORY_BACKGROUND     QColor( 0xFF, 0xC0, 0x50 )
40
41
42 YQPkgPatternList::YQPkgPatternList( QWidget * parent, bool autoFill, bool autoFilter )
43     : YQPkgObjList( parent )
44 {
45     y2debug( "Creating pattern list" );
46
47     int numCol = 0;
48     addColumn( ""               );      _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     addColumn( _( "Pattern" )   );      _summaryCol     = numCol++;
58
59     // Can use the same colum for "broken" and "satisfied":
60     // Both states are mutually exclusive
61     
62     _satisfiedIconCol   = _summaryCol;
63     _brokenIconCol      = _summaryCol;
64     
65     header()->setStretchEnabled( _statusCol , false );
66     header()->setStretchEnabled( _summaryCol, true  );
67
68     setAllColumnsShowFocus( true );
69     setTreeStepSize( 0 );
70
71     if ( autoFilter )
72     {
73         connect( this, SIGNAL( selectionChanged( QTreeWidgetItem * ) ),
74                  this, SLOT  ( filter()                            ) );
75     }
76
77     if ( autoFill )
78     {
79         fillList();
80         selectSomething();
81     }
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\"", (const char *) 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     applyExcludeRules( item );
211 }
212
213
214 YQPkgPatternListItem *
215 YQPkgPatternList::selection() const
216 {
217     QTreeWidgetItem * item = selectedItem();
218
219     if ( ! item )
220         return 0;
221
222     return dynamic_cast<YQPkgPatternListItem *> (item);
223 }
224
225
226 void
227 YQPkgPatternList::pkgObjClicked( int                    button,
228                                  QTreeWidgetItem *      listViewItem,
229                                  int                    col,
230                                  const QPoint &         pos )
231 {
232     YQPkgPatternCategoryItem * categoryItem
233         = dynamic_cast<YQPkgPatternCategoryItem *> (listViewItem);
234
235     if ( categoryItem )
236     {
237         if ( button == Qt::LeftButton )
238         {
239             if ( col == statusCol() )
240             {
241                 categoryItem->setOpen( ! categoryItem->isOpen() );
242             }
243         }
244     }
245     else
246     {
247         YQPkgObjList::pkgObjClicked( button, listViewItem, col, pos );
248     }
249 }
250
251
252 void
253 YQPkgPatternList::selectSomething()
254 {
255     QTreeWidgetItemIterator it( this );
256
257     while ( *it )
258     {
259         QY2ListViewItem * item = dynamic_cast<QY2ListViewItem *> (*it);
260         YQPkgPatternCategoryItem * categoryItem =
261             dynamic_cast<YQPkgPatternCategoryItem *> (*it);
262
263         if ( item && item->isSelectable() && ! categoryItem )
264         {
265             setSelected( item, true ); // emits signal, too
266             return;
267         }
268
269         ++it;
270     }
271 }
272
273
274
275
276
277
278 YQPkgPatternListItem::YQPkgPatternListItem( YQPkgPatternList *  patternList,
279                                             ZyppSel             selectable,
280                                             ZyppPattern         zyppPattern )
281     : YQPkgObjListItem( patternList, selectable, zyppPattern )
282     , _patternList( patternList )
283     , _zyppPattern( zyppPattern )
284 {
285     init();
286 }
287
288
289 YQPkgPatternListItem::YQPkgPatternListItem( YQPkgPatternList *          patternList,
290                                             YQPkgPatternCategoryItem *  parentCategory,
291                                             ZyppSel                     selectable,
292                                             ZyppPattern                 zyppPattern )
293     : YQPkgObjListItem( patternList, parentCategory, selectable, zyppPattern )
294     , _patternList( patternList )
295     , _zyppPattern( zyppPattern )
296 {
297     init();
298     parentCategory->addPattern( _zyppPattern );
299 }
300
301
302 void
303 YQPkgPatternListItem::init()
304 {
305     if ( ! _zyppPattern )
306         _zyppPattern = tryCastToZyppPattern( selectable()->theObj() );
307
308     setStatusIcon();
309 }
310
311
312
313 YQPkgPatternListItem::~YQPkgPatternListItem()
314 {
315     // NOP
316 }
317
318
319 void
320 YQPkgPatternListItem::applyChanges()
321 {
322     solveResolvableCollections();
323 }
324
325
326
327 /**
328  * Comparison function used for sorting the list.
329  * Returns:
330  * -1 if this <  other
331  *  0 if this == other
332  * +1 if this >  other
333  **/
334 int
335 YQPkgPatternListItem::compare( QTreeWidgetItem *        otherListViewItem,
336                                int              col,
337                                bool             ascending ) const
338 {
339     YQPkgPatternListItem * otherPatternListitem  = dynamic_cast<YQPkgPatternListItem     *>(otherListViewItem);
340
341     if ( _zyppPattern && otherPatternListitem && otherPatternListitem->zyppPattern() )
342         return _zyppPattern->order().compare( otherPatternListitem->zyppPattern()->order() );
343
344     YQPkgPatternCategoryItem * otherCategoryItem = dynamic_cast<YQPkgPatternCategoryItem *>(otherListViewItem);
345
346     if ( otherCategoryItem )    // Patterns without category should always be sorted
347         return -1;              // before any category
348
349     return QTreeWidgetItem::compare( otherListViewItem, col, ascending );
350 }
351
352
353
354
355
356
357 YQPkgPatternCategoryItem::YQPkgPatternCategoryItem( YQPkgPatternList *  patternList,
358                                                     const QString &     category        )
359     : QY2ListViewItem( patternList )
360     , _patternList( patternList )
361 {
362     setText( _patternList->summaryCol(), category );
363     setBackgroundColor( CATEGORY_BACKGROUND );
364     setOpen( true );
365     setTreeIcon();
366 }
367
368
369 YQPkgPatternCategoryItem::~YQPkgPatternCategoryItem()
370 {
371     // NOP
372 }
373
374
375 void
376 YQPkgPatternCategoryItem::paintCell( QPainter *                 painter,
377                                      const QColorGroup &        colorGroup,
378                                      int                        column,
379                                      int                        width,
380                                      int                        alignment )
381 {
382     painter->setFont( YQUI::yqApp()->headingFont() );
383     QY2ListViewItem::paintCell( painter, colorGroup, column, width, alignment );
384 }
385
386
387
388 void
389 YQPkgPatternCategoryItem::addPattern( ZyppPattern pattern )
390 {
391     if ( ! _firstPattern )
392     {
393         _firstPattern = pattern;
394     }
395     else
396     {
397         if ( _firstPattern->order().compare( pattern->order() ) < 0 )
398             _firstPattern = pattern;
399     }
400 }
401
402
403 void
404 YQPkgPatternCategoryItem::setOpen( bool open )
405 {
406     QTreeWidgetItem::setOpen( open );
407     setTreeIcon();
408 }
409
410
411 void
412 YQPkgPatternCategoryItem::setTreeIcon()
413 {
414     setPixmap( _patternList->statusCol(),
415                isOpen() ?
416                YQIconPool::treeMinus() :
417                YQIconPool::treePlus()   );
418
419 }
420
421
422
423 /**
424  * Comparison function used for sorting the list.
425  * Returns:
426  * -1 if this <  other
427  *  0 if this == other
428  * +1 if this >  other
429  **/
430 int
431 YQPkgPatternCategoryItem::compare( QTreeWidgetItem *    otherListViewItem,
432                                    int                  col,
433                                    bool                 ascending ) const
434 {
435     YQPkgPatternCategoryItem * otherCategoryItem = dynamic_cast<YQPkgPatternCategoryItem *>(otherListViewItem);
436
437     if ( _firstPattern && otherCategoryItem && otherCategoryItem->firstPattern() )
438         return _firstPattern->order().compare( otherCategoryItem->firstPattern()->order() );
439
440
441     YQPkgPatternListItem * otherPatternListitem  = dynamic_cast<YQPkgPatternListItem *>(otherListViewItem);
442
443     if ( otherPatternListitem ) // Patterns without category should always be sorted
444         return 1;               // before any category
445
446     return QTreeWidgetItem::compare( otherListViewItem, col, ascending );
447 }
448
449
450
451 #include "YQPkgPatternList.moc"