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