]> icculus.org git repositories - duncan/yast2-qt4.git/blob - src/pkg/YQPkgList.cc
#ifdefed out everything not compiling so it can be ported
[duncan/yast2-qt4.git] / src / pkg / YQPkgList.cc
1 /*---------------------------------------------------------------------\
2 |                                                                      |
3 |                      __   __    ____ _____ ____                      |
4 |                      \ \ / /_ _/ ___|_   _|___ \                     |
5 |                       \ V / _` \___ \ | |   __) |                    |
6 |                        | | (_| |___) || |  / __/                     |
7 |                        |_|\__,_|____/ |_| |_____|                    |
8 |                                                                      |
9 |                               core system                            |
10 |                                                        (C) SuSE GmbH |
11 \----------------------------------------------------------------------/
12
13   File:       YQPkgList.cc
14
15   Author:     Stefan Hundhammer <sh@suse.de>
16
17   Textdomain "packages-qt"
18
19 /-*/
20
21 #define SOURCE_RPM_DISABLED 0
22
23 #define y2log_component "qt-pkg"
24 #include <ycp/y2log.h>
25 #include <qpixmap.h>
26 #include <q3action.h>
27 #include <q3popupmenu.h>
28 #include <qmessagebox.h>
29
30 #include "utf8.h"
31
32 #include "YQPkgList.h"
33 #include "YQUI.h"
34 #include "YQi18n.h"
35 #include "YQIconPool.h"
36
37
38 YQPkgList::YQPkgList( QWidget * parent )
39     : YQPkgObjList( parent )
40 {
41     _srpmStatusCol      = -42;
42
43     int numCol = 0;
44 #if FIXME
45     addColumn( "" );                    _statusCol      = numCol++;
46     // _statusCol = numCol;
47     addColumn( _( "Package"     ) );    _nameCol        = numCol++;
48
49     addColumn( _( "Summary"     ) );    _summaryCol     = numCol++;
50     addColumn( _( "Size"        ) );    _sizeCol        = numCol++;
51
52     if ( haveInstalledPkgs() )
53     {
54         addColumn( _( "Avail. Ver." ) ); _versionCol     = numCol++;
55         addColumn( _( "Inst. Ver."  ) ); _instVersionCol = numCol++;
56     }
57     else
58     {
59         addColumn( _( "Version" ) );    _versionCol     = numCol++;
60         _instVersionCol = -1;
61     }
62
63 #if SOURCE_RPM_DISABLED
64 #warning Selecting source RPMs disabled!
65 #else
66     addColumn( _( "Source" ) );         _srpmStatusCol  = numCol++;
67 #endif
68
69     saveColumnWidths();
70     setSorting( nameCol() );
71     setColumnAlignment( sizeCol(), Qt::AlignRight );
72     setAllColumnsShowFocus( true );
73
74     createActions();
75 #endif
76     createSourceRpmContextMenu();
77 }
78
79
80 YQPkgList::~YQPkgList()
81 {
82     // NOP
83 }
84
85
86 void YQPkgList::addPkgItem( ZyppSel selectable,
87                             ZyppPkg zyppPkg )
88 {
89     addPkgItem( selectable, zyppPkg, false );
90 }
91
92
93 void YQPkgList::addPkgItemDimmed( ZyppSel selectable,
94                                   ZyppPkg zyppPkg )
95 {
96     addPkgItem( selectable, zyppPkg, true );
97 }
98
99
100 void
101 YQPkgList::addPkgItem( ZyppSel  selectable,
102                        ZyppPkg  zyppPkg,
103                        bool     dimmed )
104 {
105     if ( ! selectable )
106     {
107         y2error( "NULL zypp::ui::Selectable!" );
108         return;
109     }
110
111     YQPkgListItem * item = new YQPkgListItem( this, selectable, zyppPkg );
112     Q_CHECK_PTR( item );
113
114     item->setDimmed( dimmed );
115     applyExcludeRules( item );
116 }
117
118
119 bool
120 YQPkgList::haveInstalledPkgs()
121 {
122     for ( ZyppPoolIterator it = zyppPkgBegin();
123           it != zyppPkgEnd();
124           ++it )
125     {
126         if ( (*it)->installedObj() )
127             return true;
128     }
129
130     return false;
131 }
132
133
134 void
135 YQPkgList::pkgObjClicked( int                   button,
136                           QTreeWidgetItem *     listViewItem,
137                           int                   col,
138                           const QPoint &        pos )
139 {
140     if ( col == srpmStatusCol() )
141     {
142         YQPkgListItem * item = dynamic_cast<YQPkgListItem *> (listViewItem);
143
144         if ( item )
145         {
146             if ( button == Qt::LeftButton )
147             {
148                 if ( editable() && item->editable() )
149                     item->toggleSourceRpmStatus();
150                 return;
151             }
152             else if ( button == Qt::RightButton )
153             {
154                 if ( editable() && item->editable() )
155                 {
156                     updateActions( item );
157
158                     if ( _sourceRpmContextMenu )
159                         _sourceRpmContextMenu->popup( pos );
160                 }
161
162                 return;
163             }
164         }
165     }
166
167     YQPkgObjList::pkgObjClicked( button, listViewItem, col, pos );
168 }
169
170
171 QSize
172 YQPkgList::sizeHint() const
173 {
174     return QSize( 600, 350 );
175 }
176
177
178 void
179 YQPkgList::createSourceRpmContextMenu()
180 {
181     _sourceRpmContextMenu = new Q3PopupMenu( this );
182
183     actionInstallSourceRpm->addTo( _sourceRpmContextMenu );
184     actionDontInstallSourceRpm->addTo( _sourceRpmContextMenu );
185
186     Q3PopupMenu * submenu = new Q3PopupMenu( _sourceRpmContextMenu );
187     Q_CHECK_PTR( submenu );
188     _sourceRpmContextMenu->insertItem( _( "&All in This List" ), submenu );
189
190     actionInstallListSourceRpms->addTo( submenu );
191     actionDontInstallListSourceRpms->addTo( submenu );
192 }
193
194
195 void
196 YQPkgList::setInstallCurrentSourceRpm( bool installSourceRpm,
197                                        bool selectNextItem )
198 {
199 #if FIXME
200     QTreeWidgetItem * listViewItem = selectedItem();
201
202     if ( ! listViewItem )
203         return;
204
205     YQPkgListItem * item = dynamic_cast<YQPkgListItem *> (listViewItem);
206
207     if ( item )
208     {
209         item->setInstallSourceRpm( installSourceRpm );
210
211         if ( selectNextItem && item->nextSibling() )
212         {
213             item->setSelected( false );                 // doesn't emit signals
214             setSelected( item->nextSibling(), true );   // emits signals
215         }
216     }
217 #endif
218 }
219
220
221 void
222 YQPkgList::setInstallListSourceRpms( bool installSourceRpm )
223 {
224     if ( ! _editable )
225         return;
226
227 #if FIXME
228     QTreeWidgetItem * listViewItem = firstChild();
229
230     while ( listViewItem )
231     {
232         YQPkgListItem * item = dynamic_cast<YQPkgListItem *> (listViewItem);
233
234         if ( item && item->editable() )
235         {
236             item->setInstallSourceRpm( installSourceRpm );
237         }
238
239         listViewItem = listViewItem->nextSibling();
240     }
241 #endif
242 }
243
244
245
246 void
247 YQPkgList::createNotInstalledContextMenu()
248 {
249     _notInstalledContextMenu = new Q3PopupMenu( this );
250     Q_CHECK_PTR( _notInstalledContextMenu );
251
252     actionSetCurrentInstall->addTo( _notInstalledContextMenu );
253     actionSetCurrentDontInstall->addTo( _notInstalledContextMenu );
254     actionSetCurrentTaboo->addTo( _notInstalledContextMenu );
255
256     addAllInListSubMenu( _notInstalledContextMenu );
257
258
259     _notInstalledContextMenu->insertSeparator();
260     _notInstalledContextMenu->insertItem( _( "Export This List to &Text File..." ),
261                                           this, SLOT( askExportList() ) );
262 }
263
264
265 void
266 YQPkgList::createInstalledContextMenu()
267 {
268     _installedContextMenu = new Q3PopupMenu( this );
269     Q_CHECK_PTR( _installedContextMenu );
270
271     actionSetCurrentKeepInstalled->addTo( _installedContextMenu );
272     actionSetCurrentDelete->addTo( _installedContextMenu );
273     actionSetCurrentUpdate->addTo( _installedContextMenu );
274     actionSetCurrentProtected->addTo( _installedContextMenu );
275
276     addAllInListSubMenu( _installedContextMenu );
277
278     _installedContextMenu->insertSeparator();
279     _installedContextMenu->insertItem( _( "Export This List to &Text File..." ),
280                                        this, SLOT( askExportList() ) );
281 }
282
283
284 Q3PopupMenu *
285 YQPkgList::addAllInListSubMenu( Q3PopupMenu * menu )
286 {
287     Q3PopupMenu * submenu = new Q3PopupMenu( menu );
288     Q_CHECK_PTR( submenu );
289
290     actionSetListInstall->addTo( submenu );
291     actionSetListDontInstall->addTo( submenu );
292     actionSetListKeepInstalled->addTo( submenu );
293     actionSetListDelete->addTo( submenu );
294     actionSetListUpdate->addTo( submenu );
295     actionSetListUpdateForce->addTo( submenu );
296     actionSetListTaboo->addTo( submenu );
297     actionSetListProtected->addTo( submenu );
298
299     menu->insertItem( _( "&All in This List" ), submenu );
300
301     return submenu;
302 }
303
304
305 void
306 YQPkgList::createActions()
307 {
308     actionInstallSourceRpm              = createAction( _( "&Install Source" ),
309                                                         statusIcon( S_Install, true ),
310                                                         statusIcon( S_Install, false ) );
311
312     actionDontInstallSourceRpm          = createAction( _( "Do &Not Install Source" ),
313                                                         statusIcon( S_NoInst, true ),
314                                                         statusIcon( S_NoInst, false ) );
315
316     actionInstallListSourceRpms         = createAction( _( "&Install All Available Sources" ),
317                                                         statusIcon( S_Install, true ),
318                                                         statusIcon( S_Install, false ),
319                                                         QString::null,          // key
320                                                         true );                 // enabled
321
322     actionDontInstallListSourceRpms     = createAction( _( "Do &Not Install Any Sources" ),
323                                                         statusIcon( S_NoInst, true ),
324                                                         statusIcon( S_NoInst, false ),
325                                                         QString::null,          // key
326                                                         true );                 // enabled
327
328     connect( actionInstallSourceRpm,            SIGNAL( activated() ), this, SLOT( setInstallCurrentSourceRpm()     ) );
329     connect( actionDontInstallSourceRpm,        SIGNAL( activated() ), this, SLOT( setDontInstallCurrentSourceRpm() ) );
330
331     connect( actionInstallListSourceRpms,       SIGNAL( activated() ), this, SLOT( setInstallListSourceRpms()       ) );
332     connect( actionDontInstallListSourceRpms,   SIGNAL( activated() ), this, SLOT( setDontInstallListSourceRpms()   ) );
333 }
334
335
336 void
337 YQPkgList::updateActions( YQPkgObjListItem * pkgObjListItem )
338 {
339     YQPkgObjList::updateActions( pkgObjListItem );
340
341     YQPkgListItem * item = dynamic_cast<YQPkgListItem *> (pkgObjListItem);
342
343     if ( item )
344     {
345         actionInstallSourceRpm->setEnabled( item->hasSourceRpm() );
346         actionDontInstallSourceRpm->setEnabled( item->hasSourceRpm() );
347     }
348     else
349     {
350         actionInstallSourceRpm->setEnabled( false );
351         actionDontInstallSourceRpm->setEnabled( false );
352     }
353 }
354
355
356 void
357 YQPkgList::askExportList() const
358 {
359     QString filename = YQUI::ui()->askForSaveFileName( "pkglist.txt",   // startsWith
360                                                            "*.txt",             // filter
361                                                            _( "Export Package List" ) );
362     if ( ! filename.isEmpty() )
363         exportList( filename, true );
364 }
365
366
367 void
368 YQPkgList::exportList( const QString filename, bool interactive ) const
369 {
370     // Open file
371
372     FILE * file = fopen( (const char *) filename, "w" );
373
374     if ( ! file )
375     {
376         y2error( "Can't open file %s", (const char *) filename );
377
378         if ( interactive )
379         {
380             // Post error popup.
381
382             QMessageBox::warning( 0,                                            // parent
383                                   _( "Error" ),                                 // caption
384                                   _( "Cannot open file %1" ).arg( filename ),
385                                   QMessageBox::Ok | QMessageBox::Default,       // button0
386                                   QMessageBox::NoButton,                        // button1
387                                   QMessageBox::NoButton );                      // button2
388         }
389         return;
390     }
391
392
393     //
394     // Write header
395     //
396
397     // Format the header line with QString::sprintf() because plain stdio
398     // fprintf() is not UTF-8 aware - it will count multi-byte characters
399     // wrong, so the formatting will be broken.
400
401     QString header;
402     header.sprintf( "# %-18s %-30s | %10s | %-16s | %-16s\n\n",
403                     (const char *) _( "Status"      ).utf8(),
404                     (const char *) _( "Package"     ).utf8(),
405                     (const char *) _( "Size"        ).utf8(),
406                     (const char *) _( "Avail. Ver." ).utf8(),
407                     (const char *) _( "Inst. Ver."  ).utf8()
408                     );
409     fputs( (const char *) header.utf8(), file );
410
411
412     //
413     // Write all items
414     //
415
416 #if FIXME
417     const QTreeWidgetItem * item = firstChild();
418
419     while ( item )
420     {
421         const YQPkgListItem * pkg = dynamic_cast<const YQPkgListItem *> (item);
422
423         if ( pkg )
424         {
425             QString candVersion = pkg->text( versionCol()     );
426             QString instVersion = pkg->text( instVersionCol() );
427
428             if ( candVersion.isEmpty() ) candVersion = "---";
429             if ( instVersion.isEmpty() ) instVersion = "---";
430
431             QString status = "[" + statusText( pkg->status() ) + "]";
432             fprintf( file, "%-20s %-30s | %10s | %-16s | %-16s\n",
433                      (const char *) status.utf8(),
434                      (const char *) pkg->text( nameCol()   ),
435                      (const char *) pkg->text( sizeCol()   ),
436                      (const char *) candVersion,
437                      (const char *) instVersion
438                      );
439         }
440
441         item = item->nextSibling();
442     }
443
444 #endif
445     // Clean up
446
447     if ( file )
448         fclose( file );
449 }
450
451
452 int
453 YQPkgList::globalSetPkgStatus( ZyppStatus newStatus, bool force, bool countOnly )
454 {
455     YQUI::ui()->busyCursor();
456     int changedCount = 0;
457
458     for ( ZyppPoolIterator it = zyppPkgBegin();
459           it != zyppPkgEnd();
460           ++it )
461     {
462         ZyppSel    selectable = *it;
463         ZyppStatus oldStatus  = selectable->status();
464
465         if ( newStatus != oldStatus )
466         {
467             bool doChange = false;
468
469             switch ( newStatus )
470             {
471                 case S_KeepInstalled:
472                 case S_Del:
473                 case S_AutoDel:
474                 case S_Protected:
475                     doChange = selectable->hasInstalledObj();
476                     break;
477
478                 case S_Update:
479                 case S_AutoUpdate:
480
481                     if ( force )
482                     {
483                         doChange = selectable->hasInstalledObj();
484                     }
485                     else // don't force - update only if useful (if candidate is newer)
486                     {
487                         const ZyppObj candidate = selectable->candidateObj();
488                         const ZyppObj installed = selectable->installedObj();
489
490                         if ( candidate && installed )
491                         {
492                             doChange = ( installed->edition() < candidate->edition() );
493                         }
494                     }
495                     break;
496
497                 case S_Install:
498                 case S_AutoInstall:
499                 case S_NoInst:
500                 case S_Taboo:
501                     doChange = ! selectable->hasInstalledObj();
502                     break;
503             }
504
505             if ( doChange )
506             {
507                 if ( ! countOnly )
508                     selectable->set_status( newStatus );
509
510                 changedCount++;
511                 // y2milestone( "Updating %s", selectable->name().c_str() );
512             }
513         }
514     }
515
516     if ( changedCount > 0 && ! countOnly )
517     {
518         emit updateItemStates();
519         emit updatePackages();
520         emit statusChanged();
521     }
522
523     YQUI::ui()->normalCursor();
524
525     return changedCount;
526 }
527
528
529
530
531
532
533 YQPkgListItem::YQPkgListItem( YQPkgList *               pkgList,
534                               ZyppSel   selectable,
535                               ZyppPkg   zyppPkg )
536     : YQPkgObjListItem( pkgList, selectable, zyppPkg )
537     , _pkgList( pkgList )
538     , _zyppPkg( zyppPkg )
539     , _dimmed( false )
540 {
541     if ( ! _zyppPkg )
542         _zyppPkg = tryCastToZyppPkg( selectable->theObj() );
543
544     setSourceRpmIcon();
545 }
546
547
548 YQPkgListItem::~YQPkgListItem()
549 {
550     // NOP
551 }
552
553
554 void
555 YQPkgListItem::updateData()
556 {
557     YQPkgObjListItem::updateData();
558     setSourceRpmIcon();
559 }
560
561
562 bool
563 YQPkgListItem::hasSourceRpm() const
564 {
565     if ( ! selectable() )
566         return false;
567
568 #ifdef FIXME
569     return selectable()->providesSources();
570 #else
571     return false;
572 #endif
573 }
574
575
576 bool
577 YQPkgListItem::installSourceRpm() const
578 {
579     if ( ! selectable() )
580         return false;
581
582 #ifdef FIXME
583     if ( ! selectable()->providesSources() )
584         return false;
585
586     return selectable()->source_install();
587 #else
588     return false;
589 #endif
590 }
591
592
593 void
594 YQPkgListItem::setSourceRpmIcon()
595 {
596     if ( srpmStatusCol() < 0 )
597         return;
598
599     QPixmap icon;
600
601     if ( hasSourceRpm() )
602     {
603
604         if ( editable() && _pkgObjList->editable() )
605         {
606             icon = installSourceRpm() ?
607                 YQIconPool::pkgInstall() :
608                 YQIconPool::pkgNoInst();
609         }
610         else
611         {
612             icon = installSourceRpm() ?
613                 YQIconPool::disabledPkgInstall() :
614                 YQIconPool::disabledPkgNoInst();
615         }
616     }
617 #if FIXME
618     setPixmap( srpmStatusCol(), icon );
619 #endif
620 }
621
622
623 void
624 YQPkgListItem::setInstallSourceRpm( bool installSourceRpm )
625 {
626     if ( hasSourceRpm() )
627     {
628 #ifdef FIXME
629         if ( selectable() )
630             selectable()->set_source_install( installSourceRpm );
631 #endif
632     }
633
634     setSourceRpmIcon();
635 }
636
637
638 void
639 YQPkgListItem::toggleSourceRpmStatus()
640 {
641     setInstallSourceRpm( ! installSourceRpm() );
642 }
643
644
645 QString
646 YQPkgListItem::toolTip( int col )
647 {
648     QString text;
649     QString name = _zyppObj->name().c_str();
650
651     if ( col == statusCol() )
652     {
653         text = YQPkgObjListItem::toolTip( col );
654     }
655     else if ( col == srpmStatusCol() )
656     {
657         text = name + "\n\n";
658
659         if ( hasSourceRpm() )
660         {
661             text += installSourceRpm() ?
662                 _( "Install Sources" ) :
663                 _( "Do Not Install Sources" );
664         }
665         else
666         {
667             text += _( "No Sources Available" );
668         }
669     }
670     else
671     {
672         text = name + "\n\n";
673
674         QString installed;
675         QString candidate;
676
677         if ( selectable()->hasInstalledObj() )
678         {
679             installed  = selectable()->installedObj()->edition().asString().c_str();
680             installed += "-";
681             installed +=  selectable()->installedObj()->arch().asString().c_str();
682             installed  = _( "Installed Version: %1" ).arg( installed );
683         }
684
685         if (  selectable()->hasCandidateObj() )
686         {
687             candidate  = selectable()->candidateObj()->edition().asString().c_str();
688             candidate += "-";
689             candidate +=  selectable()->candidateObj()->arch().asString().c_str();
690         }
691
692         if ( selectable()->hasInstalledObj() )
693         {
694             text += installed + "\n";
695
696             if ( selectable()->hasCandidateObj() )
697             {
698                 // Translators: This is the relation between two versions of one package
699                 // if both versions are the same, e.g., both "1.2.3-42", "1.2.3-42"
700                 QString relation = _( "same" );
701
702                 if ( _candidateIsNewer )        relation = _( "newer" );
703                 if ( _installedIsNewer )        relation = _( "older" );
704
705                 // Translators: %1 is the version, %2 is one of "newer", "older", "same"
706                 text += _( "Available Version: %1 (%2)" ).arg( candidate ).arg( relation );
707             }
708             else
709             {
710                 text += _( "Not available for installation" );
711             }
712         }
713         else // not installed
714         {
715             text += candidate;
716         }
717     }
718
719     return text;
720 }
721
722
723
724 /**
725  * Comparison function used for sorting the list.
726  * Returns:
727  * -1 if this <  other
728  *  0 if this == other
729  * +1 if this >  other
730  **/
731 int
732 YQPkgListItem::compare( QTreeWidgetItem *               otherListViewItem,
733                         int                     col,
734                         bool                    ascending ) const
735 {
736     if ( col == srpmStatusCol() )
737     {
738         YQPkgListItem * other = dynamic_cast<YQPkgListItem *> (otherListViewItem);
739
740         if ( other )
741         {
742             int thisPoints  = ( this->hasSourceRpm()  ? 1 : 0 ) + ( this->installSourceRpm()  ? 1 : 0 );
743             int otherPoints = ( other->hasSourceRpm() ? 1 : 0 ) + ( other->installSourceRpm() ? 1 : 0 );
744
745             // Intentionally inverting order: Pkgs with source RPMs are more interesting than without.
746             if ( thisPoints > otherPoints ) return -1;
747             if ( thisPoints < otherPoints ) return  1;
748             return 0;
749         }
750     }
751
752     // Fallback: Use parent class method
753     return YQPkgObjListItem::compare( otherListViewItem, col, ascending );
754 }
755
756
757 void
758 YQPkgListItem::paintCell( QPainter *            painter,
759                           const QColorGroup &   colorGroup,
760                           int                   column,
761                           int                   width,
762                           int                   alignment )
763 {
764 #if FIXME
765     if ( isDimmed() && ! YQUI::ui()->usingVisionImpairedPalette() )
766     {
767         QColorGroup cg = colorGroup;
768         cg.setColor( QColorGroup::Text, QColor( 0xA0, 0xA0, 0xA0 ) );
769
770         QTreeWidgetItem::paintCell( painter, cg, column, width, alignment );
771     }
772     else
773     {
774         if ( installedIsNewer() )
775         {
776             QColorGroup cg = colorGroup;
777
778             if ( ! YQUI::ui()->usingVisionImpairedPalette() )
779             {
780                 if ( column == instVersionCol() )
781                     cg.setColor( QColorGroup::Base, QColor( 0xFF, 0x30, 0x30 ) );       // Background
782                 else
783                     cg.setColor( QColorGroup::Text, QColor( 0xFF, 0, 0 ) );             // Foreground
784             }
785
786             QTreeWidgetItem::paintCell( painter, cg, column, width, alignment );
787         }
788         else if ( candidateIsNewer() )
789         {
790             QColorGroup cg = colorGroup;
791
792             if ( ! YQUI::ui()->usingVisionImpairedPalette() )
793             {
794                 cg.setColor( QColorGroup::Text, QColor( 0, 0, 0xC0 ) );                 // Foreground
795
796                 if ( column == versionCol() )
797                     cg.setColor( QColorGroup::Base, QColor( 0xF0, 0xF0, 0xF0 ) );       // Background
798             }
799
800             QTreeWidgetItem::paintCell( painter, cg, column, width, alignment );
801         }
802         else
803         {
804             QTreeWidgetItem::paintCell( painter, colorGroup, column, width, alignment );
805         }
806     }
807 #endif
808 }
809
810
811
812 #include "YQPkgList.moc"