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