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