libyui-ncurses-pkg  2.46.1
 All Classes Functions
NCPackageSelector.cc
1 /****************************************************************************
2 |
3 | Copyright (c) [2002-2011] Novell, Inc.
4 | All Rights Reserved.
5 |
6 | This program is free software; you can redistribute it and/or
7 | modify it under the terms of version 2 of the GNU General Public License as
8 | published by the Free Software Foundation.
9 |
10 | This program is distributed in the hope that it will be useful,
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | GNU General Public License for more details.
14 |
15 | You should have received a copy of the GNU General Public License
16 | along with this program; if not, contact Novell, Inc.
17 |
18 | To contact Novell about this file by physical or electronic mail,
19 | you may find current contact information at www.novell.com
20 |
21 |***************************************************************************/
22 
23 
24 /*---------------------------------------------------------------------\
25 | |
26 | __ __ ____ _____ ____ |
27 | \ \ / /_ _/ ___|_ _|___ \ |
28 | \ V / _` \___ \ | | __) | |
29 | | | (_| |___) || | / __/ |
30 | |_|\__,_|____/ |_| |_____| |
31 | |
32 | core system |
33 | (C) SuSE GmbH |
34 \----------------------------------------------------------------------/
35 
36  File: NCPackageSelector.cc
37 
38  Author: Gabriele Strattner <gs@suse.de>
39 
40 /-*/
41 #include "NCurses.h"
42 #include "NCWidgetFactory.h"
43 #include "NCPushButton.h"
44 #include "NCMenuButton.h"
45 #include "NCTable.h"
46 #include "NCSpacing.h"
47 #include "NCRichText.h"
48 #include "NCLabel.h"
49 #include "NCPkgFilterRPMGroups.h"
50 #include "NCPopupInfo.h"
51 #include "NCSelectionBox.h"
52 #include "NCMenuButton.h"
53 #include "NCPkgFilterPattern.h"
54 #include "NCPkgFilterLocale.h"
55 #include "NCPkgFilterRepo.h"
56 #include "NCPkgFilterClassification.h"
57 #include "NCPkgPopupDeps.h"
58 #include "NCPkgPopupDiskspace.h"
59 #include "NCPkgMenuDeps.h"
60 #include "NCPkgMenuView.h"
61 #include "NCPkgMenuExtras.h"
62 #include "NCPkgMenuConfig.h"
63 #include "NCPkgMenuHelp.h"
64 #include "NCPkgMenuAction.h"
65 #include "NCPkgPopupDescr.h"
66 #include "NCPackageSelector.h"
67 #include "NCLayoutBox.h"
68 #include "YSelectionBox.h"
69 #include "YAlignment.h"
70 #include "YNCursesUI.h"
71 #include "YApplication.h"
72 #include "NCi18n.h"
73 
74 //#include <fstream>
75 //#include <iomanip>
76 #include <list>
77 #include <string>
78 #include <set>
79 
80 #include "NCZypp.h" // tryCastToZyppPkg(), tryCastToZyppPatch()
81 #include <zypp/ui/Selectable.h>
82 #include <zypp/base/Sysconfig.h>
83 
84 #include "YWidgetID.h"
85 #include "YPackageSelector.h"
86 
87 #define PATH_TO_YAST_SYSCONFIG "/etc/sysconfig/yast2"
88 
89 #define OPTION_REEVALUATE "PKGMGR_REEVALUATE_RECOMMENDED"
90 #define OPTION_VERIFY "PKGMGR_VERIFY_SYSTEM"
91 #define OPTION_AUTO_CHECK "PKGMGR_AUTO_CHECK"
92 #define OPTION_EXIT "PKGMGR_ACTION_AT_EXIT"
93 
94 typedef zypp::Patch::Contents ZyppPatchContents;
95 typedef zypp::Patch::Contents::Selectable_iterator ZyppPatchContentsIterator;
96 
97 #include "YEvent.h"
98 
99 using std::endl;
100 
101 /*
102  Textdomain "ncurses-pkg"
103 */
104 
105 ///////////////////////////////////////////////////////////////////
106 //
107 // Constructor
108 //
109 NCPackageSelector::NCPackageSelector( long modeFlags )
110  : filterPopup( 0 )
111  , depsPopup( 0 )
112  , patternPopup( 0 )
113  , languagePopup( 0 )
114  , repoPopup( 0 )
115  , diskspacePopup( 0 )
116  , searchPopup( 0 )
117  , autoCheck( true )
118  , verifySystem( false )
119  , installRecommended( false )
120  , pkgList ( 0 )
121  , depsMenu( 0 )
122  , viewMenu( 0 )
123  , configMenu( 0 )
124  , extrasMenu( 0 )
125  , helpMenu( 0 )
126  , filterMain( 0 )
127  , actionMenu( 0 )
128  , filterMenu( 0 )
129  , updatelistItem( 0 )
130  , packageLabel( 0 )
131  , diskspaceLabel( 0 )
132  , infoText( 0 )
133  , replacePoint( 0 )
134  , versionsList( 0 )
135  , patchPkgs( 0 )
136  , patchPkgsVersions( 0 )
137  , okButton( 0 )
138  , cancelButton( 0 )
139  , visibleInfo( 0 )
140 
141 {
142  setFlags( modeFlags );
143  readSysconfig();
144  saveState ();
145  diskspacePopup = new NCPkgDiskspace( testMode );
146 
147  setInstallAlreadyRecommended( isInstallAlreadyRecommended() );
148  setAutoCheck( isAutoCheck() );
149  setVerifySystem( isVerifySystem() );
150 }
151 
152 
153 ///////////////////////////////////////////////////////////////////
154 //
155 // Destructor
156 //
158 {
159  // Don't call delete for the popups in destructor but call
160  // YDialog::deleteTopmostDialog() instead at the end of
161  // NCPackageSelectorPlugin::runPkgSelection
162 }
163 
164 void NCPackageSelector::setFlags( long modeFlags )
165 {
166  youMode = ( modeFlags & YPkg_OnlineUpdateMode ) ? true : false ;
167 
168  updateMode = ( modeFlags & YPkg_UpdateMode ) ? true : false ;
169 
170  repoMgrEnabled = (modeFlags & YPkg_RepoMgr) ? true : false;
171 
172  testMode = (modeFlags & YPkg_TestMode ) ? true : false ;
173 
174  repoMode = ( modeFlags & YPkg_RepoMode ) ? true : false;
175 
176  summaryMode = ( modeFlags & YPkg_SummaryMode ) ? true : false;
177 }
178 
179 void NCPackageSelector::readSysconfig()
180 {
181  sysconfig = zypp::base::sysconfig::read( PATH_TO_YAST_SYSCONFIG );
182  std::map <std::string,std::string>::const_iterator it = sysconfig.find( OPTION_EXIT );
183 
184  if (it != sysconfig.end())
185  {
186  actionAtExit = it->second;
187  yuiMilestone() << "Read sysconfig's action at pkg mgr exit value: " << actionAtExit << endl;
188  }
189  else
190  {
191  actionAtExit = "";
192  yuiMilestone() << "Could not read " << OPTION_EXIT << "variable from sysconfig, disabling the menu" << endl;
193  }
194 }
195 
196 void NCPackageSelector::writeSysconfig( )
197 {
198 
199  if( !actionAtExit.empty() )
200  {
201  try
202  {
203  zypp::base::sysconfig::writeStringVal( PATH_TO_YAST_SYSCONFIG,
204  OPTION_EXIT,
205  actionAtExit,
206  "Set behaviour when package installation has finished.");
207  }
208  catch( const std::exception &e )
209  {
210  yuiError() << "Writing " << OPTION_EXIT << " failed" << endl;
211  }
212  }
213 
214  try
215  {
216  zypp::base::sysconfig::writeStringVal( PATH_TO_YAST_SYSCONFIG,
217  OPTION_AUTO_CHECK,
218  (autoCheck?"yes":"no"),
219  "Automatic dependency checking" );
220  }
221  catch( const std::exception &e )
222  {
223  yuiError() << "Writing " << OPTION_AUTO_CHECK << " failed" << endl;
224  }
225 
226  try
227  {
228  zypp::base::sysconfig::writeStringVal( PATH_TO_YAST_SYSCONFIG,
229  OPTION_VERIFY,
230  (verifySystem?"yes":"no"),
231  "System verification mode" );
232  }
233  catch( const std::exception &e )
234  {
235  yuiError() << "Writing " << OPTION_VERIFY << " failed" << endl;
236  }
237 
238  try
239  {
240  zypp::base::sysconfig::writeStringVal( PATH_TO_YAST_SYSCONFIG,
241  OPTION_REEVALUATE,
242  (installRecommended?"yes":"no"),
243  "Install recommended packages for already installed packages" );
244  }
245  catch( const std::exception &e )
246  {
247  yuiError() << "Writing " << OPTION_REEVALUATE << " failed" << endl;
248  }
249 }
250 
251 bool NCPackageSelector::checkNow( bool *ok )
252 {
253  bool ret = false;
254 
255  depsPopup = new NCPkgPopupDeps( wpos( 3, 4 ), this );
256  ret = depsPopup->showDependencies( NCPkgPopupDeps::S_Solve, ok );
257  YDialog::deleteTopmostDialog();
258  return ret;
259 }
260 
261 bool NCPackageSelector::systemVerification( bool *ok )
262 {
263  bool ret = false;
264 
265  depsPopup = new NCPkgPopupDeps( wpos( 3, 4 ), this );
266  ret = depsPopup->showDependencies( NCPkgPopupDeps::S_Verify, ok );
267  YDialog::deleteTopmostDialog();
268  return ret;
269 }
270 
271 //
272 // 'Clean dependencies on remove' option' is NOT saved and cannot be set in /etc/sysconfig/yast2.
273 // The package selector starts with setting from /etc/zypp/zypp.conf (default is false).
274 //
275 bool NCPackageSelector::isCleanDepsOnRemove()
276 {
277  return zypp::getZYpp()->resolver()->cleandepsOnRemove();
278 }
279 
280 void NCPackageSelector::setCleanDepsOnRemove( bool on )
281 {
282  zypp::getZYpp()->resolver()->setCleandepsOnRemove( on );
283  zypp::getZYpp()->resolver()->resolvePool();
285 }
286 
287 //
288 // 'Install recommended for already installed packages' option can be set and is saved
289 // in /etc/sysconfig/yast2
290 //
291 bool NCPackageSelector::isInstallAlreadyRecommended()
292 {
293  std::map <std::string,std::string>::const_iterator it = sysconfig.find( OPTION_REEVALUATE );
294 
295  if ( it != sysconfig.end() )
296  {
297  yuiMilestone() << OPTION_REEVALUATE<< ": " << it->second << endl;
298  if ( it->second == "yes" )
299  installRecommended = true;
300  else if ( it->second == "no")
301  installRecommended = false;
302  else
303  installRecommended = !(zypp::getZYpp()->resolver()->ignoreAlreadyRecommended()); // reverse value
304  }
305  else
306  {
307  installRecommended = !(zypp::getZYpp()->resolver()->ignoreAlreadyRecommended()); // reverse value
308  }
309  yuiMilestone() << "installRecommended: " << (installRecommended?"yes":"no") << endl;
310 
311  return installRecommended;
312 }
313 
314 void NCPackageSelector::setInstallAlreadyRecommended( bool on )
315 {
316  installRecommended = on;
317  zypp::getZYpp()->resolver()->setIgnoreAlreadyRecommended( !on ); // reverse value here !
318  // solve after changing the solver settings
319  zypp::getZYpp()->resolver()->resolvePool();
321 }
322 
323 
324 bool NCPackageSelector::isAutoCheck()
325 {
326  // automatic dependency check is on by default (check on every click)
327 
328  std::map <std::string,std::string>::const_iterator it = sysconfig.find( OPTION_AUTO_CHECK);
329 
330  if ( it != sysconfig.end() )
331  {
332  yuiMilestone() << OPTION_AUTO_CHECK << ": " << it->second << endl;
333  if ( it->second == "no" )
334  autoCheck = false;
335  }
336  yuiMilestone() << "autoCheck " << (autoCheck?"yes":"no") << endl;
337 
338  return autoCheck;
339 }
340 
341 bool NCPackageSelector::isVerifySystem( )
342 {
343  std::map <std::string,std::string>::const_iterator it = sysconfig.find( OPTION_VERIFY );
344 
345  if ( it != sysconfig.end() )
346  {
347  yuiMilestone() << OPTION_VERIFY << ": " << it->second << endl;
348  if ( it->second == "yes" )
349  verifySystem = true;
350  else if ( it->second == "no")
351  verifySystem = false;
352  else
353  verifySystem = zypp::getZYpp()->resolver()->systemVerification();
354  }
355  else
356  {
357  verifySystem = zypp::getZYpp()->resolver()->systemVerification();
358  }
359  yuiMilestone() << "verifySystem: " << (verifySystem?"yes":"no") << endl;
360 
361  return verifySystem;
362 }
363 
364 void NCPackageSelector::setVerifySystem( bool on )
365 {
366  verifySystem = on;
367  zypp::getZYpp()->resolver()->setSystemVerification( on );
368  // solve after changing the solver settings
369  zypp::getZYpp()->resolver()->resolvePool();
371 }
372 
373 //
374 // 'Allow vendor change' option is NOT saved and cannot be set in /etc/sysconfig/yast2.
375 // The package selector starts with setting from /etc/zypp/zypp.conf (default is false).
376 //
377 bool NCPackageSelector::isAllowVendorChange()
378 {
379  zypp::Resolver_Ptr resolver = zypp::getZYpp()->resolver();
380  bool change = resolver->allowVendorChange();
381  yuiMilestone() << "Vendor change allowed: " << (change?"true":"false") << endl;
382  return change;
383 }
384 
385 void NCPackageSelector::setAllowVendorChange( bool on )
386 {
387  zypp::getZYpp()->resolver()->setAllowVendorChange( on );
388  zypp::getZYpp()->resolver()->resolvePool();
390 }
391 
392 //////////////////////////////////////////////////////////////////
393 //
394 // detection whether the user has made any changes
395 //
396 
398 {
399  ZyppPool p = zyppPool ();
400 
401  p.saveState<zypp::Package> ();
402  p.saveState<zypp::SrcPackage> ();
403 
404  p.saveState<zypp::Patch> ();
405 
406  p.saveState<zypp::Pattern> ();
407  //p.saveState<zypp::Language> ();
408 }
409 
410 void NCPackageSelector::restoreState ()
411 {
412  ZyppPool p = zyppPool ();
413 
414  p.restoreState<zypp::Package> ();
415  p.restoreState<zypp::SrcPackage> ();
416 
417  p.restoreState<zypp::Patch> ();
418 
419  p.restoreState<zypp::Pattern> ();
420  //p.restoreState<zypp::Language> ();
421 }
422 
423 bool NCPackageSelector::diffState ()
424 {
425  ZyppPool p = zyppPool ();
426 
427  bool diff = false;
428 
429  std::ostream & log = yuiMilestone();
430  log << "diffState" << endl;
431  diff = diff || p.diffState<zypp::Package> ();
432  log << diff << endl;
433  diff = diff || p.diffState<zypp::SrcPackage> ();
434  log << diff << endl;
435 
436  diff = diff || p.diffState<zypp::Patch> ();
437  log << diff << endl;
438 
439  diff = diff || p.diffState<zypp::Pattern> ();
440  log << diff << endl;
441  //diff = diff || p.diffState<zypp::Language> ();
442  log << diff << endl;
443  return diff;
444 }
445 
446 ///////////////////////////////////////////////////////////////////
447 //
448 // handleEvent
449 //
450 // Handle event, calls corresponding handler-function
451 //
452 bool NCPackageSelector::handleEvent ( const NCursesEvent& event )
453 {
454  bool retVal = false;
455 
456  if ( event == NCursesEvent::handled )
457  return false;
458 
459  yuiMilestone() << "widget event: " << event << endl;
460  // Call the appropriate handler
461  if ( event == NCursesEvent::button )
462  {
463  if ( event.widget == okButton )
464  {
465  retVal = OkButtonHandler( event );
466  }
467  else if ( event.widget == cancelButton )
468  {
469  retVal = CancelHandler( event );
470  }
471  else if ( event.widget == filterPopup )
472  {
473  retVal = filterPopup->handleEvent();
474  }
475  else if ( event.widget == filterMain )
476  {
477  retVal = filterMain->handleEvent();
478  }
479  else if ( event.widget == searchField )
480  {
481  if ( event.reason == YEvent::Activated )
482  {
483  retVal = searchPopup->showSearchResultPackages();
484  }
485  else // no action, reason was YEvent::SelectionChanged
486  {
487  retVal = true;
488  }
489  }
490  }
491  else if ( event == NCursesEvent::menu )
492  {
493  if ( event.widget == actionMenu )
494  // change package/patch status
495  retVal = actionMenu->handleEvent( event );
496  else if ( event.widget == viewMenu )
497  // show package/patch information
498  retVal = viewMenu->handleEvent( event );
499  else if ( event.widget == depsMenu )
500  retVal = depsMenu->handleEvent( event );
501  else if ( event.widget == extrasMenu )
502  retVal = extrasMenu->handleEvent( event );
503  else if ( event.widget == configMenu )
504  retVal = configMenu->handleEvent( event );
505  else if ( event.widget == helpMenu )
506  retVal = helpMenu->handleEvent( event );
507  else if ( event.widget == filterMenu )
508  retVal = filterMenu->handleEvent( event );
509  else if ( event.selection->label().substr(0,4) == "pkg:" )
510  // handle hyper links
511  retVal = LinkHandler( event.selection->label() );
512 
513  }
514 
515  return retVal;
516 }
517 
518 ///////////////////////////////////////////////////////////////////
519 //
520 // fillPatchSearchList
521 //
522 // Fills the patch list with search results
523 //
524 bool NCPackageSelector::fillPatchSearchList( const std::string & expr, bool checkName, bool checkSum )
525 {
526  NCPkgTable * packageList = PackageList();
527 
528  if ( !packageList )
529  {
530  return false;
531  }
532 
533  // clear the patch list
534  packageList->itemsCleared ();
535 
536  zypp::PoolQuery q;
537  q.addString( expr );
538  q.addKind( zypp::ResKind::patch );
539  q.addAttribute( zypp::sat::SolvAttr::keywords );
540  if ( checkName )
541  {
542  q.addAttribute( zypp::sat::SolvAttr::name );
543  }
544  if ( checkSum )
545  {
546  q.addAttribute( zypp::sat::SolvAttr::summary );
547  }
548 
549  for( zypp::PoolQuery::Selectable_iterator it = q.selectableBegin();
550  it != q.selectableEnd(); it++)
551  {
552  yuiMilestone() << (*it)->name() << endl;
553  ZyppPatch patchPtr = tryCastToZyppPatch( (*it)->theObj() );
554  packageList->createPatchEntry ( patchPtr, *it);
555  }
556 
557  // show the patch list with search result
558  packageList->drawList();
559 
560  // set filter label to 'Search'
561  if ( packageLabel )
562  {
563  packageLabel->setLabel( NCPkgStrings::SearchResults() );
564  }
565 
566  return true;
567 }
568 
569 
570 ///////////////////////////////////////////////////////////////////
571 //
572 // fillPatchList
573 //
574 // Fills the package table with the list of YOU patches
575 //
576 bool NCPackageSelector::fillPatchList( NCPkgMenuFilter::PatchFilter filter )
577 {
578  NCPkgTable * packageList = PackageList();
579 
580  if ( !packageList )
581  {
582  yuiError() << "No valid NCPkgTable widget" << endl;
583  return false;
584  }
585 
586  // clear list of patches
587  packageList->itemsCleared ();
588 
589  // get the patch list and sort it
590  std::list<ZyppSel> patchList( zyppPatchesBegin (), zyppPatchesEnd () );
591  patchList.sort( sortByName );
592  std::list<ZyppSel>::iterator listIt = patchList.begin();
593 
594  while ( listIt != patchList.end() )
595  {
596  ZyppPatch patchPtr = tryCastToZyppPatch( ( *listIt)->theObj() );
597 
598  if ( patchPtr )
599  {
600  checkPatch( patchPtr, *listIt, filter );
601  }
602  ++listIt;
603  }
604 
605  if ( filter == NCPkgMenuFilter::F_All
606  && packageList->getNumLines() == 0 )
607  {
608  packageList->createInfoEntry( NCPkgStrings::NoPatches() );
609  }
610 
611  // show the patches
612  packageList->drawList();
613 
614  // show the selected filter label
615  if ( packageLabel )
616  {
617  switch ( filter )
618  {
619  case NCPkgMenuFilter::F_Needed:
620  {
621  // show common label "Needed Patches"
622  packageLabel->setLabel( NCPkgStrings::YOUPatches() );
623  break;
624  }
625  case NCPkgMenuFilter::F_Unneeded:
626  {
627  packageLabel->setLabel( NCPkgStrings::InstPatches() );
628  break;
629  }
630  default:
631  {
632  packageLabel->setLabel( NCPkgStrings::Patches() );
633  }
634  }
635  }
636 
637  return true;
638 }
639 
640 
641 ///////////////////////////////////////////////////////////////////
642 //
643 // fillUpdateList
644 //
645 //
647 {
648  NCPkgTable * packageList = PackageList();
649 
650  if ( !packageList )
651  {
652  yuiError() << "Widget is not a valid NCPkgTable widget" << endl;
653  return false;
654  }
655 
656  // clear the package table
657  packageList->itemsCleared ();
658 
659  std::list<zypp::PoolItem> problemList = zypp::getZYpp()->resolver()->problematicUpdateItems();
660 
661  for ( std::list<zypp::PoolItem>::const_iterator it = problemList.begin();
662  it != problemList.end();
663  ++it )
664  {
665  ZyppPkg pkg = tryCastToZyppPkg( (*it).resolvable() );
666 
667  if ( pkg )
668  {
669  ZyppSel slb = selMapper.findZyppSel( pkg );
670 
671  if ( slb )
672  {
673  yuiMilestone() << "Problematic package: " << pkg->name().c_str() << " " <<
674  pkg->edition().asString().c_str() << endl;
675  packageList->createListEntry( pkg, slb );
676  }
677  }
678 
679  }
680 
681  // show the list
682  packageList->drawList();
683 
684  // show the selected filter label
685  if ( packageLabel )
686  {
687  packageLabel->setLabel( NCPkgStrings::UpdateProblem() );
688  }
689 
690  return true;
691 }
692 
693 ///////////////////////////////////////////////////////////////////
694 //
695 // fillPatchPackages
696 //
697 //
698 bool NCPackageSelector::fillPatchPackages ( NCPkgTable * pkgTable, ZyppObj objPtr )
699 {
700  if ( !pkgTable || !objPtr )
701  return false;
702 
703  pkgTable->itemsCleared ();
704 
705  std::set<ZyppSel> patchSelectables;
706  ZyppPatch patchPtr = tryCastToZyppPatch( objPtr );
707 
708  if ( !patchPtr )
709  return false;
710 
711  ZyppPatchContents patchContents( patchPtr->contents() );
712 
713  yuiMilestone() << "Filtering for patch: " << patchPtr->name().c_str() << " number of atoms: "
714  << patchContents.size() << endl ;
715 
716  for ( ZyppPatchContentsIterator it = patchContents.selectableBegin();
717  it != patchContents.selectableEnd();
718  ++it )
719  {
720  ZyppPkg pkg = tryCastToZyppPkg( (*it)->theObj() );
721 
722  if ( pkg )
723  {
724  yuiMilestone() << "Patch package found: " << (*it)->name().c_str() << endl;
725  ZyppSel sel = selMapper.findZyppSel( pkg );
726 
727  if ( sel )
728  {
729  if ( inContainer( patchSelectables, sel ) )
730  {
731  yuiMilestone() << "Suppressing duplicate selectable: " << (*it)->name().c_str() << "-" <<
732  pkg->edition().asString().c_str() << " " <<
733  pkg->arch().asString().c_str() << endl;
734  }
735  else
736  {
737  patchSelectables.insert( sel );
738  yuiDebug() << (*it)->name().c_str() << ": Version: " << pkg->edition().asString() << endl;
739 
740  pkgTable->createListEntry( pkg, sel );
741  }
742  }
743  }
744  else // No ZyppPkg - some other kind of object
745  {
746  yuiDebug() << "Found unknown atom of kind %s: %s" <<
747  (*it)->kind().asString().c_str() <<
748  (*it)->name().c_str() << endl;
749 
750  }
751  }
752 
753  // show the list
754  pkgTable->drawList();
755 
756  return true;
757 }
758 
759 // patches
760 
761 ///////////////////////////////////////////////////////////////////
762 //
763 // checkPatch
764 //
765 //
766 bool NCPackageSelector::checkPatch( ZyppPatch patchPtr,
767  ZyppSel selectable,
768  NCPkgMenuFilter::PatchFilter filter )
769 
770 {
771  NCPkgTable * packageList = PackageList();
772  bool displayPatch = false;
773 
774  if ( !packageList )
775  {
776  yuiError() << "Widget is not a valid NCPkgTable widget" << endl;
777  return false;
778  }
779  if ( !patchPtr || !selectable || !selectable->hasCandidateObj() )
780  {
781  yuiError() << "Patch data not valid" << endl;
782  return false;
783  }
784  yuiDebug() << "Filter: " << filter << endl;
785 
786  if ( filter == NCPkgMenuFilter::F_All )
787  {
788  displayPatch = true;
789  }
790  // only show patches relevant for the system, means any of the patch packages is installed
791  else if ( selectable->candidateObj().isRelevant() )
792  {
793  switch ( filter )
794  {
795  case NCPkgMenuFilter::F_Unneeded: // unneeded means satisfied (installed)
796  {
797  if ( selectable->candidateObj().isSatisfied() &&
798  !selectable->candidateObj().status().isToBeInstalled() )
799  {
800  displayPatch = true;
801  }
802  break;
803  }
804  case NCPkgMenuFilter::F_Needed: // needed means not satisfied...
805  {
806  if ( !selectable->candidateObj().isSatisfied() ||
807  // or already satified because the patch is preselected
808  selectable->candidateObj().status().isToBeInstalled() )
809  displayPatch = true;
810  break;
811  }
812  case NCPkgMenuFilter::F_Security:
813  {
814  if ( patchPtr->category() == "security" )
815  displayPatch = true;
816  break;
817  }
818  case NCPkgMenuFilter::F_Recommended:
819  {
820  if ( patchPtr->category() == "recommended" )
821  displayPatch = true;
822  break;
823  }
824  case NCPkgMenuFilter::F_Optional:
825  {
826  if ( patchPtr->category() == "optional" )
827  displayPatch = true;
828  break;
829  }
830  default:
831  yuiWarning() << "Unknown patch filter" << endl;
832  }
833  }
834  if ( displayPatch )
835  packageList->createPatchEntry( patchPtr, selectable );
836 
837  return displayPatch;
838 }
839 
840 ///////////////////////////////////////////////////////////////////
841 //
842 // deleteReplacePoint
843 //
844 // Gets ( and returns ) the current size of the widget at the replace
845 // point and deletes it.
846 //
847 wrect NCPackageSelector::deleteReplacePoint()
848 {
849  // delete current child of the ReplacePoint
850  YWidget * replaceChild = replacePoint->firstChild();
851  wrect oldSize;
852 
853  if ( replaceChild )
854  {
855  oldSize = dynamic_cast<NCWidget *>(replaceChild)->wGetSize();
856 
857  delete replaceChild;
858  // reset all info widgets
859  infoText = 0; // NCPkgPackageDetails ( NCRichText )
860  versionsList = 0; // NCPkgTable - type: T_Availables
861  patchPkgs = 0; // NCPkgTable - type: T_PatchPkgs
862  patchPkgsVersions = 0; // NCPkgTable - type: T_Availables
863  }
864 
865  return oldSize;
866 }
867 
868 ///////////////////////////////////////////////////////////////////
869 //
870 // showInformation
871 //
872 // Creates an NCPkgPackageDetails (a RichtText widget) which is
873 // used to show the required information (called from NCPkgMenuView)
874 //
875 //
877 {
878  wrect oldSize = deleteReplacePoint();
879 
880  // show the rich text widget
881  infoText = new NCPkgPackageDetails( replacePoint, " ", this);
882 
883  if ( infoText )
884  {
885  infoText->setSize( oldSize.Sze.W, oldSize.Sze.H );
886  infoText->Redraw();
887  }
888 }
889 
890 ///////////////////////////////////////////////////////////////////
891 //
892 // showVersionsList
893 //
894 // Creates an NCPkgTable (type T_Availables) which is used to show
895 // the list of package versions (called from NCPkgMenuView)
896 //
897 //
899 {
900  wrect oldSize = deleteReplacePoint();
901  NCPkgTable * packageList = PackageList();
902 
903  // show a package table with all available package versions
904  YTableHeader * tableHeader = new YTableHeader();
905  versionsList = new NCPkgTable( replacePoint, tableHeader );
906  // YDialog::currentDialog()->setInitialSize(); -> doesn't work
907  // call versionsList->setSize() and versionsList->Redraw() instead
908 
909  if ( versionsList && packageList )
910  {
911  // set the connection to the NCPackageSelector !!!!
912  versionsList->setPackager( this );
913  // fill default header, set correct header in NCPkgTable::fillAvailableList()
914  versionsList->fillHeader();
915  versionsList->setSize( oldSize.Sze.W, oldSize.Sze.H );
916 
917  versionsList->fillAvailableList( packageList->getSelPointer( packageList->getCurrentItem() ) );
918  versionsList->Redraw();
919 
920  packageList->setKeyboardFocus();
921  }
922 }
923 
924 
925 ///////////////////////////////////////////////////////////////////
926 //
927 // showPatchPackages
928 //
929 // Creates an NCPkgTable (type T_PatchPkgs) which is used to show
930 // the list of all packages belonging to a patch (called from NCPkgMenuView)
931 //
932 //
934 {
935  wrect oldSize = deleteReplacePoint();
936  NCPkgTable * packageList = PackageList();
937 
938  // show a package table with packages belonging to a patch
939  YTableHeader * tableHeader = new YTableHeader();
940  patchPkgs = new NCPkgTable( replacePoint, tableHeader );
941 
942  if ( patchPkgs && packageList )
943  {
944  // set the connection to the NCPackageSelector !!!!
945  patchPkgs->setPackager( this );
946  // set status strategy - don't set extra strategy, use 'normal' package strategy
947  NCPkgStatusStrategy * strategy = new PackageStatStrategy();
948  patchPkgs->setTableType( NCPkgTable::T_PatchPkgs, strategy );
949  patchPkgs->fillHeader( );
950  patchPkgs->setSize( oldSize.Sze.W, oldSize.Sze.H );
951 
952  fillPatchPackages( patchPkgs, packageList->getDataPointer( packageList->getCurrentItem() ) );
953  patchPkgs->Redraw();
954 
955  packageList->setKeyboardFocus();
956  }
957 }
958 
959 ///////////////////////////////////////////////////////////////////
960 //
961 // showPatchPkgsVersions
962 //
963 // Creates an NCPkgTable (type T_Availables) which is used to show
964 // a list of all versions of all packages belonging to a patch
965 // (called from NCPkgMenuView)
966 //
967 //
969 {
970  // only available if patch packages are currently shown
971  if ( patchPkgs )
972  {
973  // get selected line and show availables for this package
974  ZyppSel sel = patchPkgs->getSelPointer( patchPkgs->getCurrentItem() );
975 
976  // show the availables
977  NCPkgPopupTable * availablePopup =
978  new NCPkgPopupTable( wpos( 3, 8), this,
979  // headline of package versions popup
980  _("Package Versions"),
981  // text above of list of all package versions
982  _("List of all available package versions:"),
983  "", // no additional text line
984  false ); // no 'Cancel' button
985  NCursesEvent input = availablePopup->showAvailablesPopup( sel );
986 
987  YDialog::deleteTopmostDialog();
988 
989  patchPkgs->setKeyboardFocus();
990  }
991 }
992 
993 void NCPackageSelector::clearInfoArea()
994 {
995  if ( infoText )
996  infoText->setText("");
997  if ( versionsList )
998  versionsList->itemsCleared();
999 
1000  packageLabel->setText(".....................................");
1001 }
1002 
1003 void NCPackageSelector::replaceFilter( FilterMode mode)
1004 {
1005  patternLabel->setLabel( " " );
1006  YWidget * replaceChild = replPoint->firstChild();
1007  wrect oldSize;
1008 
1009  if ( replaceChild )
1010  {
1011  oldSize = dynamic_cast<NCWidget *>(replaceChild)->wGetSize();
1012 
1013  delete replaceChild;
1014 
1015  filterPopup = 0;
1016  patternPopup = 0;
1017  languagePopup = 0;
1018  repoPopup = 0;
1019  searchPopup = 0;
1020  }
1021 
1022  //replace the description area already here, so the next selected
1023  //filter can update it right away (#377857)
1024  replaceFilterDescr( mode == Search );
1025 
1026  switch (mode)
1027  {
1028  case Patterns:
1029  {
1030  YTableHeader *hhh = new YTableHeader ();
1031  patternPopup = new NCPkgFilterPattern( replPoint, hhh, this );
1032  patternPopup->setSize( oldSize.Sze.W, oldSize.Sze.H );
1033  patternPopup->Redraw();
1034  patternPopup->showPatternPackages();
1035  patternPopup->setKeyboardFocus();
1036  break;
1037  }
1038  case Languages:
1039  {
1040  YTableHeader *hhh = new YTableHeader ();
1041  languagePopup = new NCPkgLocaleTable( replPoint, hhh, this );
1042  languagePopup->setSize( oldSize.Sze.W, oldSize.Sze.H );
1043  languagePopup->Redraw();
1044  languagePopup->showLocalePackages();
1045  languagePopup->setKeyboardFocus();
1046  break;
1047  }
1048  case Repositories:
1049  {
1050  YTableHeader *hhh = new YTableHeader ();
1051  repoPopup = new NCPkgRepoTable( replPoint, hhh, this );
1052  repoPopup->setSize( oldSize.Sze.W, oldSize.Sze.H );
1053  repoPopup->Redraw();
1054  repoPopup->showRepoPackages();
1055  repoPopup->setKeyboardFocus();
1056  break;
1057  }
1058  case RPMGroups:
1059  {
1060  filterPopup = new NCPkgFilterRPMGroups ( replPoint, " ", this);
1061  filterPopup->setSize( oldSize.Sze.W, oldSize.Sze.H );
1062  filterPopup->Redraw();
1063 
1064  YStringTreeItem * defaultGroup = filterPopup->getDefaultRpmGroup();
1065 
1066  if ( defaultGroup )
1067  {
1068  yuiMilestone() << "default RPM group: " << defaultGroup->value().translation() << endl;
1069  filterPopup->showRPMGroupPackages ( defaultGroup->value().translation(), defaultGroup );
1070  }
1071  else
1072  {
1073  yuiError() << "No default RPM group available" << endl;
1074  }
1075  filterPopup->setKeyboardFocus();
1076  break;
1077  }
1078  case Search:
1079  {
1080  searchPopup = new NCPkgFilterSearch( replPoint, YD_VERT, this );
1081  searchPopup->createLayout( replPoint );
1082  searchPopup->setSize( oldSize.Sze.W, oldSize.Sze.H );
1083  searchPopup->Redraw();
1084 
1085  searchField = searchPopup->getSearchField();
1086  if ( searchField )
1087  {
1088  searchField->setKeyboardFocus();
1089  searchField->setNotify(true);
1090  }
1091  break;
1092  }
1093  case Summary:
1094  {
1095  inst_summary = new NCPkgFilterInstSummary( replPoint, _( "&Packages with Status" ), this );
1096  inst_summary->setSize( oldSize.Sze.W, oldSize.Sze.H );
1097  inst_summary->Redraw();
1098  inst_summary->setKeyboardFocus();
1099  pkgList->fillSummaryList(NCPkgTable::L_Changes);
1100  break;
1101  }
1102  case PkgClassification:
1103  {
1104  pkgClass = new NCPkgFilterClassification( replPoint, this );
1105  pkgClass->setSize( oldSize.Sze.W, oldSize.Sze.H );
1106  pkgClass->Redraw();
1107  pkgClass->setKeyboardFocus();
1108  break;
1109  }
1110 
1111  default:
1112  yuiError() << "zatim nic" << endl;
1113  }
1114 
1115  if (mode == Search)
1116  {
1117  pkgList->itemsCleared();
1118  clearInfoArea();
1119  }
1120  else
1121  {
1122  pkgList->setCurrentItem(0);
1123  pkgList->showInformation ();
1124  }
1125 
1126 }
1127 
1128 void NCPackageSelector::replaceFilterDescr( bool b )
1129 {
1130  YWidget * replaceChild = replPoint2->firstChild();
1131  wrect oldSize;
1132 
1133  if ( replaceChild )
1134  {
1135  oldSize = dynamic_cast<NCWidget *>(replaceChild)->wGetSize();
1136 
1137  delete replaceChild;
1138  filter_desc = 0;
1139  searchSet = 0;
1140  }
1141 
1142  if (b)
1143  {
1144  searchSet = new NCPkgSearchSettings( replPoint2, NCPkgStrings::SearchIn() );
1145  searchSet->setSize( oldSize.Sze.W, oldSize.Sze.H );
1146  searchSet->Redraw();
1147  }
1148  else
1149  {
1150  filter_desc = new NCRichText( replPoint2, "");
1151  filter_desc->setSize( oldSize.Sze.W, oldSize.Sze.H );
1152  filter_desc->Redraw();
1153  }
1154 
1155 }
1156 
1157 ///////////////////////////////////////////////////////////////////
1158 //
1159 // LinkHandler
1160 //
1161 // Handles hyperlinks in package description.
1162 //
1163 bool NCPackageSelector::LinkHandler ( std::string link )
1164 {
1165  bool found = false;
1166  // e.g. link is pkg://hp-officeJet
1167  std::string pkgName = link.substr(6);
1168 
1169  ZyppPoolIterator
1170  b = zyppPkgBegin(),
1171  e = zyppPkgEnd(),
1172  i;
1173  for (i = b; i != e; ++i)
1174  {
1175  ZyppPkg pkgPtr = tryCastToZyppPkg ((*i)->theObj());
1176  if ( pkgPtr && pkgPtr->name() == pkgName )
1177  {
1178  yuiMilestone() << "Package " << pkgName << " found" << endl;
1179  // open popup with package info
1180  NCPkgPopupDescr * popupDescr = new NCPkgPopupDescr( wpos(1,1), this );
1181  popupDescr->showInfoPopup( pkgPtr, *i );
1182 
1183  YDialog::deleteTopmostDialog();
1184 
1185  found = true;
1186  }
1187  }
1188 
1189  if ( !found )
1190  {
1191  yuiError() << "Package " << pkgName << " NOT found" << endl;
1192  // open error popup
1193  }
1194 
1195  return found;
1196 }
1197 
1198 
1199 ///////////////////////////////////////////////////////////////////
1200 //
1201 // CancelHandler
1202 //
1203 // Cancel button handler.
1204 //
1205 bool NCPackageSelector::CancelHandler( const NCursesEvent& event )
1206 {
1207  bool changes = diffState ();
1208 
1209  if (changes) {
1210  // show a popup and ask the user
1211  NCPopupInfo * cancelMsg = new NCPopupInfo( wpos( (NCurses::lines()-8)/2, (NCurses::cols()-45)/2 ),
1212  NCPkgStrings::NotifyLabel(),
1213  NCPkgStrings::CancelText(),
1216  );
1217  cancelMsg->setPreferredSize( 45, 8 );
1218  cancelMsg->focusCancelButton();
1219  NCursesEvent input = cancelMsg->showInfoPopup( );
1220 
1221  YDialog::deleteTopmostDialog();
1222 
1223  if ( input == NCursesEvent::cancel ) {
1224  // don't leave the package installation dialog
1225  return true;
1226  }
1227  }
1228 
1229  restoreState ();
1230 
1231  yuiMilestone() << "Cancel button pressed - leaving package selection" << endl;
1232  const_cast<NCursesEvent &>(event).result = "cancel";
1233 
1234  // return false, which means stop the event loop (see runPkgSelection)
1235  return false;
1236 }
1237 
1238 ///////////////////////////////////////////////////////////////////
1239 //
1240 // OkButtonHandler
1241 //
1242 // OK button handler.
1243 //
1244 bool NCPackageSelector::OkButtonHandler( const NCursesEvent& event )
1245 {
1246  bool closeDialog = true;
1247  bool confirmedAllLicenses = false;
1248 
1249  // check/show dependencies also if youMode == true
1250  do
1251  {
1252  // show the dependency popup
1253  if ( showPackageDependencies( true ) )
1254  {
1255  // don't leave the package installation if the user has clicked on Cancel
1256  // in dependency popup because maybe he wants to change his choices
1257  closeDialog = false;
1258  }
1259 
1260  confirmedAllLicenses = showPendingLicenseAgreements();
1261 
1262  } while ( !confirmedAllLicenses && closeDialog );
1263 
1264  if ( !youMode ) // don't show automatic changes if YOU mode
1265  {
1266  // show the automatic changes list
1267  NCPkgPopupTable * autoChangePopup =
1268  new NCPkgPopupTable( wpos( 3, 8), this,
1269  // headline - packages with automatic status change
1270  _("Automatic Changes"),
1271  // text part1 of popup with automatic changes (it's a label; text continous)
1272  _( "In addition to your manual selections, the following" ),
1273  // text part2 of popup with automatic changes
1274  _( "packages have been changed to resolve dependencies:" )
1275  );
1276  NCursesEvent input = autoChangePopup->showInfoPopup();
1277 
1278  YDialog::deleteTopmostDialog();
1279 
1280  if ( input == NCursesEvent::cancel )
1281  {
1282  // user clicked on Cancel
1283  closeDialog = false;
1284  }
1285  }
1286 
1287  if ( diskspacePopup )
1288  {
1289  std::string message = "";
1290  message = diskspacePopup->checkDiskSpace();
1291  if ( message != "" )
1292  {
1293  // open the popup e.g. with the text "/usr needs 50 MB more disk space"
1294  NCPopupInfo * spaceMsg = new NCPopupInfo( wpos( (NCurses::lines()-10)/2, (NCurses::cols()-50)/2 ),
1295  NCPkgStrings::ErrorLabel(),
1296  NCPkgStrings::DiskSpaceError() + "<br>" + message +
1297  _( "You can choose to install anyway, but you risk getting a corrupted system." ),
1298  _( "&Continue anyway" ),
1300 
1301  spaceMsg->setPreferredSize( 50, 10 );
1302  spaceMsg->focusOkButton();
1303  NCursesEvent input = spaceMsg->showInfoPopup( );
1304 
1305  YDialog::deleteTopmostDialog();
1306 
1307  if ( input == NCursesEvent::cancel )
1308  {
1309  // disk space error warning returned `cancel
1310  closeDialog = false;
1311  }
1312  }
1313  }
1314 
1315  if ( closeDialog )
1316  {
1317  // clear the saved states
1318  // could free some memory?
1319  // clearSaveState ();
1320 
1321  writeSysconfig();
1322  const_cast<NCursesEvent &>(event).result = "accept";
1323  yuiMilestone() << "OK button pressed - leaving package selection, starting installation" << endl;
1324 
1325  // return false, leave the package selection
1326  return false;
1327  }
1328  else
1329  {
1330  NCPkgTable * packageList = PackageList();
1331  if ( packageList )
1332  {
1333  packageList->updateTable();
1334  packageList->setKeyboardFocus();
1335  }
1336  // don't leave the dialog
1337  return true;
1338  }
1339 }
1340 
1342 {
1343  bool allConfirmed = true;
1344 
1345  if ( youMode )
1346  allConfirmed = showPendingLicenseAgreements( zyppPatchesBegin(), zyppPatchesEnd() );
1347 
1348  allConfirmed = showPendingLicenseAgreements( zyppPkgBegin(), zyppPkgEnd() ) && allConfirmed;
1349 
1350  return allConfirmed;
1351 }
1352 
1353 bool NCPackageSelector::showPendingLicenseAgreements( ZyppPoolIterator begin, ZyppPoolIterator end )
1354 {
1355  yuiMilestone() << "Showing all pending license agreements" << endl;
1356 
1357  bool allConfirmed = true;
1358 
1359  for ( ZyppPoolIterator it = begin; it != end; ++it )
1360  {
1361  ZyppSel sel = (*it);
1362 
1363  switch ( sel->status() )
1364  {
1365  case S_Install:
1366  case S_AutoInstall:
1367  case S_Update:
1368  case S_AutoUpdate:
1369 
1370  if ( sel->candidateObj() )
1371  {
1372  std::string licenseText = sel->candidateObj()->licenseToConfirm();
1373 
1374  if ( ! licenseText.empty() )
1375  {
1376  yuiMilestone() << "Package/Patch " << sel->name().c_str() <<
1377  "has a license" << endl;
1378 
1379  if( ! sel->hasLicenceConfirmed() )
1380  {
1381  allConfirmed = showLicenseAgreement( sel, licenseText ) && allConfirmed;
1382  }
1383  else
1384  {
1385  yuiMilestone() << "License for " << sel->name().c_str() <<
1386  " is already confirmed" << endl;
1387  }
1388  }
1389  }
1390  break;
1391 
1392  default:
1393  break;
1394  }
1395  }
1396 
1397  return allConfirmed;
1398 }
1399 
1400 bool NCPackageSelector::showLicenseAgreement( ZyppSel & slbPtr , std::string licenseText )
1401 {
1402  if ( !slbPtr )
1403  return false;
1404 
1405  bool license_confirmed = true;
1406  bool ok = true;
1407  std::string pkgName = slbPtr->name();
1408 
1409  license_confirmed = showLicensePopup( pkgName, licenseText );
1410 
1411  if ( !license_confirmed )
1412  {
1413  // make sure the package won't be installed
1414  switch ( slbPtr->status() )
1415  {
1416  case S_Install:
1417  case S_AutoInstall:
1418  slbPtr->setStatus( S_Taboo );
1419  break;
1420 
1421  case S_Update:
1422  case S_AutoUpdate:
1423  slbPtr->setStatus( S_Protected );
1424  break;
1425 
1426  default:
1427  break;
1428  }
1429 
1430  ok = false;
1431  } else {
1432  yuiMilestone() << "User confirmed license agreement for " << pkgName << endl;
1433  slbPtr->setLicenceConfirmed (true);
1434  ok = true;
1435  }
1436 
1437  return ok;
1438 }
1439 
1440 ///////////////////////////////////////////////////////////////////
1441 //
1442 // showDependencies
1443 //
1444 // Checks and shows the dependencies
1445 //
1447 {
1448  bool ok = false;
1449  bool cancel = false;
1450 
1451  if ( doit || autoCheck )
1452  {
1453  yuiMilestone() << "Checking dependencies" << endl;
1454  cancel = checkNow( & ok );
1455  }
1456 
1457  return cancel;
1458 }
1459 
1460 ///////////////////////////////////////////////////////////////////
1461 //
1462 // showDependencies
1463 //
1464 // Checks and shows the dependencies
1465 //
1467 {
1468  showPackageDependencies (true);
1469 }
1470 
1471 ///////////////////////////////////////////////////////////////////
1472 //
1473 // createLicenseText
1474 //
1475 bool NCPackageSelector::showLicensePopup( std::string pkgName, std::string license )
1476 {
1477  std::string html_text = "";
1478  const std::string htmlIdent(DOCTYPETAG);
1479  bool confirmed = false;
1480 
1481  if ( license.find( htmlIdent ) != std::string::npos )
1482  {
1483  html_text = license; // HTML text
1484  }
1485  else
1486  {
1487  html_text = "<pre>" + license + "</pre>"; // add <pre> to preserve newlines and spaces
1488  }
1489 
1490  NCPopupInfo * info = new NCPopupInfo ( wpos( NCurses::lines()/10, NCurses::cols()/10),
1491  // headline of a popup showing the package license
1492  _( "End User License Agreement" ),
1493  "<i>" + pkgName + "</i><br><br>"
1494  + html_text,
1497 
1498  info->setPreferredSize( (NCurses::cols() * 80)/100, (NCurses::lines()*80)/100);
1499  info->focusOkButton();
1500  confirmed = info->showInfoPopup( ) != NCursesEvent::cancel;
1501 
1502  YDialog::deleteTopmostDialog();
1503 
1504  return confirmed;
1505 }
1506 
1507 ///////////////////////////////////////////////////////////////////
1508 //
1509 // updatePackageList
1510 //
1512 {
1513  NCPkgTable * packageList = PackageList();
1514 
1515  if ( packageList )
1516  {
1517  packageList->updateTable();
1518  }
1519 }
1520 
1521 ///////////////////////////////////////////////////////////////////
1522 //
1523 // showDiskSpace()
1524 //
1526 {
1527 
1528 
1529  // check whether required diskspace enters the warning range
1530  if ( diskspacePopup )
1531  {
1532  diskspacePopup->checkDiskSpaceRange( );
1533  // show pkg_diff, i.e. total difference of disk space (can be negative in installed system
1534  // if packages are deleted)
1535  if ( diskspaceLabel )
1536  {
1537  diskspaceLabel->setText( diskspacePopup->calculateDiff().asString() );
1538  }
1539  }
1540 }
1541 
1542 
1543 ///////////////////////////////////////////////////////////////////
1544 //
1545 // showDownloadSize()
1546 //
1547 // total download size of YOU patches
1548 //
1550 {
1551  std::set<ZyppSel> selectablesToInstall;
1552 
1553  for ( ZyppPoolIterator patches_it = zyppPatchesBegin();
1554  patches_it != zyppPatchesEnd();
1555  ++patches_it )
1556  {
1557  ZyppPatch patch = tryCastToZyppPatch( (*patches_it)->theObj() );
1558 
1559  if ( patch )
1560  {
1561  ZyppPatchContents patchContents( patch->contents() );
1562 
1563  for ( ZyppPatchContentsIterator contents_it = patchContents.selectableBegin();
1564  contents_it != patchContents.selectableEnd();
1565  ++contents_it )
1566  {
1567  ZyppPkg pkg = tryCastToZyppPkg( (*contents_it)->theObj() );
1568  ZyppSel sel;
1569 
1570  if ( pkg )
1571  sel = selMapper.findZyppSel( pkg );
1572 
1573 
1574  if ( sel )
1575  {
1576  switch ( sel->status() )
1577  {
1578  case S_Install:
1579  case S_AutoInstall:
1580  case S_Update:
1581  case S_AutoUpdate:
1582  // Insert the patch contents selectables into a set,
1583  // don't immediately sum up their sizes: The same
1584  // package could be in more than one patch, but of
1585  // course it will be downloaded only once.
1586 
1587  selectablesToInstall.insert( sel );
1588  break;
1589 
1590  case S_Del:
1591  case S_AutoDel:
1592  case S_NoInst:
1593  case S_KeepInstalled:
1594  case S_Taboo:
1595  case S_Protected:
1596  break;
1597 
1598  // intentionally omitting 'default' branch so the compiler can
1599  // catch unhandled enum states
1600  }
1601 
1602  }
1603  }
1604  }
1605  }
1606 
1607  FSize totalSize = 0;
1608 
1609  for ( std::set<ZyppSel>::iterator it = selectablesToInstall.begin();
1610  it != selectablesToInstall.end();
1611  ++it )
1612  {
1613  if ( (*it)->candidateObj() )
1614  totalSize += (*it)->candidateObj()->installSize();
1615  }
1616 
1617  // show the download size
1618  if ( diskspaceLabel )
1619  {
1620  diskspaceLabel->setText( totalSize.asString() );
1621  }
1622 }
1623 
1624 
1625 ///////////////////////////////////////////////////////////////////
1626 //
1627 // PackageList()
1628 //
1629 NCPkgTable * NCPackageSelector::PackageList()
1630 {
1631  return pkgList;
1632 }
1633 
1634 //
1635 // Create layout for Online Update
1636 //
1637 void NCPackageSelector::createYouLayout( YWidget * selector )
1638 {
1639  // the vertical split is the (only) child of the dialog
1640  YLayoutBox * split = YUI::widgetFactory()->createVBox( selector );
1641 
1642  YLayoutBox * hSplit = YUI::widgetFactory()->createHBox( split );
1643 
1644  YAlignment * left1 = YUI::widgetFactory()->createLeft( hSplit );
1645  filterMenu = new NCPkgMenuFilter( left1, NCPkgStrings::Filter(), this );
1646 
1647  YAlignment * left2 = YUI::widgetFactory()->createLeft( hSplit );
1648  actionMenu = new NCPkgMenuAction( left2, NCPkgStrings::Actions(), this );
1649 
1650  YAlignment * left3 = YUI::widgetFactory()->createLeft( hSplit );
1651  viewMenu = new NCPkgMenuView( left3, NCPkgStrings::View(), this);
1652 
1653  YAlignment * left4 = YUI::widgetFactory()->createLeft( hSplit );
1654  depsMenu = new NCPkgMenuDeps( left4, NCPkgStrings::Deps(), this);
1655 
1656  // add the package table
1657  YTableHeader * tableHeader = new YTableHeader();
1658 
1659  pkgList = new NCPkgTable( split, tableHeader );
1660  YUI_CHECK_NEW( pkgList );
1661 
1662  // set table type 'T_Patches'
1663  NCPkgStatusStrategy * strategy;
1664  strategy = new PatchStatStrategy();
1665  pkgList->setTableType( NCPkgTable::T_Patches, strategy );
1666  pkgList->fillHeader();
1667 
1668  // set the pointer to the packager object
1669  pkgList->setPackager( this );
1670 
1671  // set sort strategy
1672  std::vector<std::string> pkgHeader;
1673  pkgList->getHeader( pkgHeader );
1674  pkgList->setSortStrategy( new NCPkgTableSort( pkgHeader ) );
1675 
1676  // HBox for Filter and Disk Space (both in additional HBoxes )
1677  YLayoutBox * hSplit2 = YUI::widgetFactory()->createHBox( split );
1678 
1679  YLayoutBox * hSplit3 = YUI::widgetFactory()->createHBox( hSplit2 );
1680  // label text - keep it short
1681  new NCLabel( hSplit3, _( "Filter: " ) );
1682  packageLabel = YUI::widgetFactory()->createLabel ( hSplit3, "....................................." );
1683 
1684  new NCSpacing( hSplit2, YD_HORIZ, true, 0.5 );
1685 
1686  YLayoutBox * hSplit4 = YUI::widgetFactory()->createHBox( hSplit2 );
1687  // label text - keep it short (use abbreviation if necessary)
1688  new NCLabel( hSplit4, _( "Total Download Size: " ) );
1689  // create label with spaces to have enough space available for download size
1690  diskspaceLabel = YUI::widgetFactory()->createLabel ( hSplit4, " " );
1691 
1692  YLayoutBox * vSplit = YUI::widgetFactory()->createVBox( split );
1693  replacePoint = YUI::widgetFactory()->createReplacePoint( vSplit );
1694 
1695  infoText = new NCPkgPackageDetails( replacePoint, " ", this );
1696  YUI_CHECK_NEW( infoText );
1697 
1698  YLayoutBox * bottom_bar = YUI::widgetFactory()->createHBox( vSplit );
1699  YAlignment *ll = YUI::widgetFactory()->createLeft( bottom_bar );
1700 
1701  helpMenu = new NCPkgMenuHelp (ll, _( "&Help" ), this);
1702 
1703  YAlignment *r = YUI::widgetFactory()->createRight( bottom_bar );
1704  YLayoutBox * hSplit5 = YUI::widgetFactory()->createHBox( r );
1705 
1706  // add the Cancel button
1707  cancelButton = new NCPushButton( hSplit5, _( "&Cancel" ) );
1708  YUI_CHECK_NEW( cancelButton );
1709  cancelButton->setFunctionKey( 9 );
1710 
1711  // add the OK button
1712  okButton = new NCPushButton( hSplit5, _( "&Accept" ) );
1713  YUI_CHECK_NEW( okButton );
1714  okButton->setFunctionKey( 10 );
1715 
1716 }
1717 
1718 //
1719 // Create layout for Package Selector
1720 //
1721 void NCPackageSelector::createPkgLayout( YWidget * selector, NCPkgTable::NCPkgTableType type )
1722 {
1723  // the vertical split is the (only) child of the dialog
1724  YLayoutBox * vsplit = YUI::widgetFactory()->createVBox( selector );
1725  YLayoutBox * menu_bar = YUI::widgetFactory()->createHBox( vsplit );
1726  YLayoutBox * panels = YUI::widgetFactory()->createVBox( vsplit );
1727  YLayoutBox * bottom_bar = YUI::widgetFactory()->createHBox( vsplit );
1728 
1729  YAlignment * left1 = YUI::widgetFactory()->createLeft( menu_bar );
1730 
1731  YLayoutBox * menu_buttons = YUI::widgetFactory()->createHBox( left1);
1732  depsMenu = new NCPkgMenuDeps( menu_buttons, NCPkgStrings::Deps(), this);
1733  viewMenu = new NCPkgMenuView( menu_buttons, NCPkgStrings::View(), this);
1734 
1735  //Add only if requested by `opt(`repoMgr) flag - #381956
1736  if (isRepoMgrEnabled())
1737  configMenu = new NCPkgMenuConfig( menu_buttons, _( "C&onfiguration" ), this);
1738 
1739  extrasMenu = new NCPkgMenuExtras( menu_buttons, NCPkgStrings::Extras(), this);
1740 
1741  YLayoutBox * hbox_top = YUI::widgetFactory()->createHBox( panels );
1742  YLayoutBox * hbox_bottom = YUI::widgetFactory()->createHBox( panels );
1743 
1744  YLayoutBox * vbox_left = YUI::widgetFactory()->createVBox( hbox_top );
1745  vbox_left->setWeight(YD_HORIZ,1);
1746  YFrame * fr = YUI::widgetFactory()->createFrame (vbox_left, "");
1747  YLayoutBox * vv = YUI::widgetFactory()->createVBox( fr );
1748  YAlignment *l = YUI::widgetFactory()->createLeft( vv );
1749  filterMain = new NCPkgFilterMain (l, NCPkgStrings::Filter(), this );
1750 
1751  replPoint = YUI::widgetFactory()->createReplacePoint( vv );
1752  //Search view is now default (#404694)
1753  searchPopup = new NCPkgFilterSearch( replPoint, YD_VERT, this );
1754  searchPopup->createLayout( replPoint );
1755 
1756  searchField = searchPopup->getSearchField();
1757  if ( searchField )
1758  {
1759  searchField->setKeyboardFocus();
1760  searchField->setNotify( true );
1761  }
1762 
1763  YAlignment *l1 = YUI::widgetFactory()->createLeft( vbox_left );
1764  patternLabel = new NCLabel( l1, " " );
1765 
1766  // add the package table
1767  YTableHeader * tableHeader = new YTableHeader();
1768 
1769  YLayoutBox * v = YUI::widgetFactory()->createVBox( hbox_top );
1770  v->setWeight(YD_HORIZ,2);
1771  pkgList = new NCPkgTable( v, tableHeader );
1772  YUI_CHECK_NEW( pkgList );
1773 
1774  NCPkgStatusStrategy * strategy;
1775  // set table type and status strategy (either 'normal' package list or update list)
1776  switch ( type )
1777  {
1778  case NCPkgTable::T_Packages:
1779  strategy = new PackageStatStrategy();
1780  pkgList->setTableType( NCPkgTable::T_Packages, strategy );
1781  case NCPkgTable::T_Update:
1782  strategy = new UpdateStatStrategy();
1783  pkgList->setTableType( NCPkgTable::T_Update, strategy );
1784  default:
1785  strategy = new PackageStatStrategy();
1786  pkgList->setTableType( NCPkgTable::T_Packages, strategy );
1787  }
1788  // set the pointer to the packager object
1789  pkgList->setPackager( this );
1790  pkgList->fillHeader();
1791 
1792  // set sort strategy
1793  std::vector<std::string> pkgHeader;
1794  pkgList->getHeader( pkgHeader );
1795  pkgList->setSortStrategy( new NCPkgTableSort( pkgHeader ) );
1796 
1797  // label text + actions menu
1798  YLayoutBox * hSplit2 = YUI::widgetFactory()->createHBox( v );
1799  new NCLabel( hSplit2, NCPkgStrings::PackageName() );
1800  packageLabel = YUI::widgetFactory()->createLabel ( hSplit2, "......................" );
1801  new NCSpacing( hSplit2, YD_HORIZ, true, 0.5 );
1802  actionMenu = new NCPkgMenuAction ( hSplit2, NCPkgStrings::Actions(), this );
1803 
1804  //Search parameters resp. filter description
1805  replPoint2 = YUI::widgetFactory()->createReplacePoint( hbox_bottom );
1806  replPoint2->setWeight(YD_HORIZ, 1);
1807  searchSet = new NCPkgSearchSettings( replPoint2, NCPkgStrings::SearchIn() );
1808 
1809  //Package description resp. package version table
1810  YLayoutBox * vSplit = YUI::widgetFactory()->createVBox( hbox_bottom );
1811  vSplit->setWeight(YD_HORIZ, 2);
1812  replacePoint = YUI::widgetFactory()->createReplacePoint( vSplit );
1813  infoText = new NCPkgPackageDetails( replacePoint, " ", this );
1814  YUI_CHECK_NEW( infoText );
1815 
1816  //Bottom button bar
1817  YAlignment *ll = YUI::widgetFactory()->createLeft( bottom_bar );
1818  helpMenu = new NCPkgMenuHelp (ll, _( "&Help" ), this);
1819  YUI_CHECK_NEW( helpMenu );
1820 
1821  //right-alignment for OK-Cancel
1822  YAlignment *right = YUI::widgetFactory()->createRight( bottom_bar );
1823  YLayoutBox * hSplit = YUI::widgetFactory()->createHBox( right );
1824 
1825  // add the Cancel button
1826  cancelButton = new NCPushButton( hSplit, _( "&Cancel" ) );
1827  YUI_CHECK_NEW( cancelButton );
1828  cancelButton->setFunctionKey( 9 );
1829 
1830  // add the OK button
1831  okButton = new NCPushButton( hSplit, _( "&Accept" ) );
1832  YUI_CHECK_NEW( okButton );
1833  okButton->setFunctionKey( 10 );
1834 
1835 }
1836 
1837 //
1838 // Fill package list with packages of default RPM group/update list or installable patches
1839 //
1841 {
1842  if ( !pkgList )
1843  return false;
1844 
1845  yuiMilestone() << "Filling package list: " << (NCWidget *) pkgList << endl;
1846 
1847  switch ( pkgList->getTableType() )
1848  {
1849  case NCPkgTable::T_Patches: {
1850  fillPatchList( NCPkgMenuFilter::F_Needed ); // default: needed patches
1851 
1852  // set the visible info to long description
1853  pkgList->setVisibleInfo(NCPkgTable::I_PatchDescr);
1854  // show the patch description of the current item
1855  pkgList->showInformation ();
1856  pkgList->setKeyboardFocus();
1857  break;
1858  }
1859  case NCPkgTable::T_Update: {
1860  if ( ! zypp::getZYpp()->resolver()->problematicUpdateItems().empty() )
1861  {
1862  fillUpdateList();
1863  // set the visible info to technical information
1864  pkgList->setVisibleInfo(NCPkgTable::I_Technical);
1865  // show the package information of the current item
1866  pkgList->showInformation ();
1867  break;
1868  }
1869  }
1870  case NCPkgTable::T_Packages: {
1871  //Search view is the default (#404694)
1872  pkgList->setVisibleInfo(NCPkgTable::I_Technical);
1873  searchField->setKeyboardFocus();
1874  break;
1875  }
1876  default:
1877  break;
1878  }
1879 
1880  // if started with `repoMode or `summaryMode replace filter accordingly
1881  if ( repoMode )
1882  {
1883  replaceFilter ( NCPackageSelector::Repositories );
1884  if ( filterMain)
1885  filterMain->setReposSelected();
1886  }
1887  else if ( summaryMode )
1888  {
1889  replaceFilter ( NCPackageSelector::Summary );
1890  if ( filterMain )
1891  filterMain->setSummarySelected();
1892  }
1893 
1894  return true;
1895 
1896 }
bool showInformation()
Show the corresponding information (e.g.
Definition: NCPkgTable.cc:762
bool createPatchEntry(ZyppPatch pkgPtr, ZyppSel slbPtr)
Creates a line in the YOU patch table.
Definition: NCPkgTable.cc:723
void showDiskSpace()
Calls the package mananager (updateDu()) and shows the required disk space.
static const std::string YOUPatches()
The label Filter: YOU Patches.
void showSelectionDependencies()
Checks and shows the selectiondependencies.
bool checkPatch(ZyppPatch patch, ZyppSel selectable, NCPkgMenuFilter::PatchFilter filter)
Check if 'patch' matches the selected filter.
static const std::string UpdateProblem()
The label for Filter: Update problem.
bool fillPatchList(NCPkgMenuFilter::PatchFilter filter)
Fills the package table with YOU patches matching the filter.
bool showPendingLicenseAgreements()
Check for license.
void createPkgLayout(YWidget *parent, NCPkgTable::NCPkgTableType type)
Create layout for the PackageSelector.
The package table class.
Definition: NCPkgTable.h:175
ZyppObj getDataPointer(int index)
Gets the data pointer of a certain package.
Definition: NCPkgTable.cc:874
void showDownloadSize()
Shows the total download size.
bool handleEvent(const NCursesEvent &event)
Handle the given event.
void updatePackageList()
Updates the status in list of packages.
virtual ~NCPackageSelector()
Destructor.
void showPatchPackages()
Creates an NCPkgTable widget and shows all packages belonging to a patch.
void fillHeader()
Fills the header of the table.
Definition: NCPkgTable.cc:448
bool fillPatchPackages(NCPkgTable *pkgTable, ZyppObj youPatch)
Fills the list of packages belonging to the youPatch.
bool CancelHandler(const NCursesEvent &event)
Handler function for "Cancel button pressed".
bool showLicensePopup(std::string pkgName, std::string license)
Shows 'End User License Agreement' popup with license text.
void showPatternPackages()
Shows the popup with the add ons (package categories).
bool createListEntry(ZyppPkg pkgPtr, ZyppSel slbPtr)
Creates a line in the package table.
Definition: NCPkgTable.cc:550
static const std::string AcceptLabel()
The label of the Accept button.
static const std::string SearchResults()
The label for Filter: Search results.
bool createInfoEntry(std::string text)
Creates a line in the table shwing an info text.
Definition: NCPkgTable.cc:704
void saveState()
Check for changes.
bool fillPatchSearchList(const std::string &expr, bool checkName, bool checkSum)
Fills the package table with packages matching the search expression.
ZyppSel getSelPointer(int index)
Gets the selectable pointer of a certain package.
Definition: NCPkgTable.cc:884
bool updateTable()
Set the status information if status has changed.
Definition: NCPkgTable.cc:369
bool setTableType(NCPkgTableType type, NCPkgStatusStrategy *strategy)
Sets the type of the table and the status strategy (which means call particular methods to set/get th...
Definition: NCPkgTable.h:352
unsigned int getNumLines()
Returns the number of lines in the table (the table size)
Definition: NCPkgTable.h:383
static const std::string NoPatches()
Info line in empty patch list.
static const std::string YesLabel()
The label of the Yes button.
bool fillDefaultList()
Fills the default package table.
virtual void itemsCleared()
Clears the package list.
Definition: NCPkgTable.cc:184
static const std::string NoLabel()
The label of the No button.
bool LinkHandler(std::string link)
Handles hyperlinks in package description.
void drawList()
Draws the package list (has to be called after the loop with addLine() calls)
Definition: NCPkgTable.h:263
void createYouLayout(YWidget *parent)
Create layout for the Online Update.
bool OkButtonHandler(const NCursesEvent &event)
Handler function for "OK button pressed".
void setPackager(NCPackageSelector *pkg)
Sets the member variable PackageSelector *packager.
Definition: NCPkgTable.h:300
void showPatchPkgVersions()
Creates an NCPkgTable widget and shows all versions of all packages belonging to a patch...
static const std::string DiskSpaceError()
The headline of the disk space popup.
void showInformation()
Creates an NCRichText widget for package (patch) information.
bool showLicenseAgreement(ZyppSel &slbPtr, std::string licenseText)
Show popup with license.
bool showPackageDependencies(bool doit)
Checks and shows the dependencies.
static const std::string CancelLabel()
The label of the Cancel button.
void showVersionsList()
Creates an NCPkgTable widget and shows all verions a the selected package.
bool fillUpdateList()
Fills the package table with packages with update problems.
ZyppSel findZyppSel(ZyppPkg pkg)
Find the corresponding ZyppSel to a ZyppPkg.