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