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