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