libyui-ncurses-pkg  2.43.4.1
 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  // set the connection to the NCPackageSelector !!!!
918  versionsList->setPackager( this );
919  // fill default header, set correct header in NCPkgTable::fillAvailableList()
920  versionsList->fillHeader();
921  versionsList->setSize( oldSize.Sze.W, oldSize.Sze.H );
922 
923  versionsList->fillAvailableList( packageList->getSelPointer( packageList->getCurrentItem() ) );
924  versionsList->Redraw();
925 
926  packageList->setKeyboardFocus();
927  }
928 }
929 
930 
931 ///////////////////////////////////////////////////////////////////
932 //
933 // showPatchPackages
934 //
935 // Creates an NCPkgTable (type T_PatchPkgs) which is used to show
936 // the list of all packages belonging to a patch (called from NCPkgMenuView)
937 //
938 //
940 {
941  wrect oldSize = deleteReplacePoint();
942  NCPkgTable * packageList = PackageList();
943 
944  // show a package table with packages belonging to a patch
945  YTableHeader * tableHeader = new YTableHeader();
946  patchPkgs = new NCPkgTable( replacePoint, tableHeader );
947 
948  if ( patchPkgs && packageList )
949  {
950  // set the connection to the NCPackageSelector !!!!
951  patchPkgs->setPackager( this );
952  // set status strategy - don't set extra strategy, use 'normal' package strategy
953  NCPkgStatusStrategy * strategy = new PackageStatStrategy();
954  patchPkgs->setTableType( NCPkgTable::T_PatchPkgs, strategy );
955  patchPkgs->fillHeader( );
956  patchPkgs->setSize( oldSize.Sze.W, oldSize.Sze.H );
957 
958  fillPatchPackages( patchPkgs, packageList->getDataPointer( packageList->getCurrentItem() ) );
959  patchPkgs->Redraw();
960 
961  packageList->setKeyboardFocus();
962  }
963 }
964 
965 ///////////////////////////////////////////////////////////////////
966 //
967 // showPatchPkgsVersions
968 //
969 // Creates an NCPkgTable (type T_Availables) which is used to show
970 // a list of all versions of all packages belonging to a patch
971 // (called from NCPkgMenuView)
972 //
973 //
975 {
976  wrect oldSize = deleteReplacePoint();
977  NCPkgTable * packageList = PackageList();
978 
979  // show a package table with versions of the packages beloning to a patch
980  YTableHeader * tableHeader = new YTableHeader();
981  patchPkgsVersions = new NCPkgTable( replacePoint, tableHeader );
982 
983  if ( patchPkgsVersions && packageList )
984  {
985  // set the connection to the NCPackageSelector !!!!
986  patchPkgsVersions->setPackager( this );
987  // set status strategy and table type
988  NCPkgStatusStrategy * strategy = new AvailableStatStrategy();
989  patchPkgsVersions->setTableType( NCPkgTable::T_Availables, strategy );
990  patchPkgsVersions->fillHeader( );
991  patchPkgsVersions->setSize( oldSize.Sze.W, oldSize.Sze.H );
992 
993  fillPatchPackages( patchPkgsVersions, packageList->getDataPointer( packageList->getCurrentItem() ), true );
994  patchPkgsVersions->Redraw();
995 
996  packageList->setKeyboardFocus();
997  }
998 }
999 
1000 void NCPackageSelector::clearInfoArea()
1001 {
1002  if ( infoText )
1003  infoText->setText("");
1004  if ( versionsList )
1005  versionsList->itemsCleared();
1006 
1007  packageLabel->setText(".....................................");
1008 }
1009 
1010 void NCPackageSelector::replaceFilter( FilterMode mode)
1011 {
1012  patternLabel->setLabel( " " );
1013  YWidget * replaceChild = replPoint->firstChild();
1014  wrect oldSize;
1015 
1016  if ( replaceChild )
1017  {
1018  oldSize = dynamic_cast<NCWidget *>(replaceChild)->wGetSize();
1019 
1020  delete replaceChild;
1021 
1022  filterPopup = 0;
1023  patternPopup = 0;
1024  languagePopup = 0;
1025  repoPopup = 0;
1026  searchPopup = 0;
1027  }
1028 
1029  //replace the description area already here, so the next selected
1030  //filter can update it right away (#377857)
1031  replaceFilterDescr( mode == Search );
1032 
1033  switch (mode)
1034  {
1035  case Patterns:
1036  {
1037  YTableHeader *hhh = new YTableHeader ();
1038  patternPopup = new NCPkgFilterPattern( replPoint, hhh, this );
1039  patternPopup->setSize( oldSize.Sze.W, oldSize.Sze.H );
1040  patternPopup->Redraw();
1041  patternPopup->showPatternPackages();
1042  patternPopup->setKeyboardFocus();
1043  break;
1044  }
1045  case Languages:
1046  {
1047  YTableHeader *hhh = new YTableHeader ();
1048  languagePopup = new NCPkgLocaleTable( replPoint, hhh, this );
1049  languagePopup->setSize( oldSize.Sze.W, oldSize.Sze.H );
1050  languagePopup->Redraw();
1051  languagePopup->showLocalePackages();
1052  languagePopup->setKeyboardFocus();
1053  break;
1054  }
1055  case Repositories:
1056  {
1057  YTableHeader *hhh = new YTableHeader ();
1058  repoPopup = new NCPkgRepoTable( replPoint, hhh, this );
1059  repoPopup->setSize( oldSize.Sze.W, oldSize.Sze.H );
1060  repoPopup->Redraw();
1061  repoPopup->showRepoPackages();
1062  repoPopup->setKeyboardFocus();
1063  break;
1064  }
1065  case RPMGroups:
1066  {
1067  filterPopup = new NCPkgFilterRPMGroups ( replPoint, " ", this);
1068  filterPopup->setSize( oldSize.Sze.W, oldSize.Sze.H );
1069  filterPopup->Redraw();
1070 
1071  YStringTreeItem * defaultGroup = filterPopup->getDefaultRpmGroup();
1072 
1073  if ( defaultGroup )
1074  {
1075  yuiMilestone() << "default RPM group: " << defaultGroup->value().translation() << endl;
1076  filterPopup->showRPMGroupPackages ( defaultGroup->value().translation(), defaultGroup );
1077  }
1078  else
1079  {
1080  yuiError() << "No default RPM group available" << endl;
1081  }
1082  filterPopup->setKeyboardFocus();
1083  break;
1084  }
1085  case Search:
1086  {
1087  searchPopup = new NCPkgFilterSearch( replPoint, YD_VERT, this );
1088  searchPopup->createLayout( replPoint );
1089  searchPopup->setSize( oldSize.Sze.W, oldSize.Sze.H );
1090  searchPopup->Redraw();
1091 
1092  searchField = searchPopup->getSearchField();
1093  if ( searchField )
1094  {
1095  searchField->setKeyboardFocus();
1096  searchField->setNotify(true);
1097  }
1098  break;
1099  }
1100  case Summary:
1101  {
1102  inst_summary = new NCPkgFilterInstSummary( replPoint, _( "&Packages with Status" ), this );
1103  inst_summary->setSize( oldSize.Sze.W, oldSize.Sze.H );
1104  inst_summary->Redraw();
1105  inst_summary->setKeyboardFocus();
1106  pkgList->fillSummaryList(NCPkgTable::L_Changes);
1107  break;
1108  }
1109  case PkgClassification:
1110  {
1111  pkgClass = new NCPkgFilterClassification( replPoint, this );
1112  pkgClass->setSize( oldSize.Sze.W, oldSize.Sze.H );
1113  pkgClass->Redraw();
1114  pkgClass->setKeyboardFocus();
1115  break;
1116  }
1117 
1118  default:
1119  yuiError() << "zatim nic" << endl;
1120  }
1121 
1122  if (mode == Search)
1123  {
1124  pkgList->itemsCleared();
1125  clearInfoArea();
1126  }
1127  else
1128  {
1129  pkgList->setCurrentItem(0);
1130  pkgList->showInformation ();
1131  }
1132 
1133 }
1134 
1135 void NCPackageSelector::replaceFilterDescr( bool b )
1136 {
1137  YWidget * replaceChild = replPoint2->firstChild();
1138  wrect oldSize;
1139 
1140  if ( replaceChild )
1141  {
1142  oldSize = dynamic_cast<NCWidget *>(replaceChild)->wGetSize();
1143 
1144  delete replaceChild;
1145  filter_desc = 0;
1146  searchSet = 0;
1147  }
1148 
1149  if (b)
1150  {
1151  searchSet = new NCPkgSearchSettings( replPoint2, NCPkgStrings::SearchIn() );
1152  searchSet->setSize( oldSize.Sze.W, oldSize.Sze.H );
1153  searchSet->Redraw();
1154  }
1155  else
1156  {
1157  filter_desc = new NCRichText( replPoint2, "");
1158  filter_desc->setSize( oldSize.Sze.W, oldSize.Sze.H );
1159  filter_desc->Redraw();
1160  }
1161 
1162 }
1163 
1164 ///////////////////////////////////////////////////////////////////
1165 //
1166 // LinkHandler
1167 //
1168 // Handles hyperlinks in package description.
1169 //
1170 bool NCPackageSelector::LinkHandler ( std::string link )
1171 {
1172  bool found = false;
1173  // e.g. link is pkg://hp-officeJet
1174  std::string pkgName = link.substr(6);
1175 
1176  ZyppPoolIterator
1177  b = zyppPkgBegin(),
1178  e = zyppPkgEnd(),
1179  i;
1180  for (i = b; i != e; ++i)
1181  {
1182  ZyppPkg pkgPtr = tryCastToZyppPkg ((*i)->theObj());
1183  if ( pkgPtr && pkgPtr->name() == pkgName )
1184  {
1185  yuiMilestone() << "Package " << pkgName << " found" << endl;
1186  // open popup with package info
1187  NCPkgPopupDescr * popupDescr = new NCPkgPopupDescr( wpos(1,1), this );
1188  popupDescr->showInfoPopup( pkgPtr, *i );
1189 
1190  YDialog::deleteTopmostDialog();
1191 
1192  found = true;
1193  }
1194  }
1195 
1196  if ( !found )
1197  {
1198  yuiError() << "Package " << pkgName << " NOT found" << endl;
1199  // open error popup
1200  }
1201 
1202  return found;
1203 }
1204 
1205 
1206 ///////////////////////////////////////////////////////////////////
1207 //
1208 // CancelHandler
1209 //
1210 // Cancel button handler.
1211 //
1212 bool NCPackageSelector::CancelHandler( const NCursesEvent& event )
1213 {
1214  bool changes = diffState ();
1215 
1216  if (changes) {
1217  // show a popup and ask the user
1218  NCPopupInfo * cancelMsg = new NCPopupInfo( wpos( (NCurses::lines()-8)/2, (NCurses::cols()-45)/2 ),
1219  NCPkgStrings::NotifyLabel(),
1220  NCPkgStrings::CancelText(),
1223  );
1224  cancelMsg->setPreferredSize( 45, 8 );
1225  cancelMsg->focusCancelButton();
1226  NCursesEvent input = cancelMsg->showInfoPopup( );
1227 
1228  YDialog::deleteTopmostDialog();
1229 
1230  if ( input == NCursesEvent::cancel ) {
1231  // don't leave the package installation dialog
1232  return true;
1233  }
1234  }
1235 
1236  restoreState ();
1237 
1238  yuiMilestone() << "Cancel button pressed - leaving package selection" << endl;
1239  const_cast<NCursesEvent &>(event).result = "cancel";
1240 
1241  // return false, which means stop the event loop (see runPkgSelection)
1242  return false;
1243 }
1244 
1245 ///////////////////////////////////////////////////////////////////
1246 //
1247 // OkButtonHandler
1248 //
1249 // OK button handler.
1250 //
1251 bool NCPackageSelector::OkButtonHandler( const NCursesEvent& event )
1252 {
1253  bool closeDialog = true;
1254  bool confirmedAllLicenses = false;
1255 
1256  // check/show dependencies also if youMode == true
1257  do
1258  {
1259  // show the dependency popup
1260  if ( showPackageDependencies( true ) )
1261  {
1262  // don't leave the package installation if the user has clicked on Cancel
1263  // in dependency popup because maybe he wants to change his choices
1264  closeDialog = false;
1265  }
1266 
1267  confirmedAllLicenses = showPendingLicenseAgreements();
1268 
1269  } while ( !confirmedAllLicenses && closeDialog );
1270 
1271  if ( !youMode ) // don't show automatic changes if YOU mode
1272  {
1273  // show the automatic changes list
1274  NCPkgPopupTable * autoChangePopup = new NCPkgPopupTable( wpos( 3, 8), this );
1275  NCursesEvent input = autoChangePopup->showInfoPopup();
1276 
1277  YDialog::deleteTopmostDialog();
1278 
1279  if ( input == NCursesEvent::cancel )
1280  {
1281  // user clicked on Cancel
1282  closeDialog = false;
1283  }
1284  }
1285 
1286  if ( diskspacePopup )
1287  {
1288  std::string message = "";
1289  message = diskspacePopup->checkDiskSpace();
1290  if ( message != "" )
1291  {
1292  // open the popup e.g. with the text "/usr needs 50 MB more disk space"
1293  NCPopupInfo * spaceMsg = new NCPopupInfo( wpos( (NCurses::lines()-10)/2, (NCurses::cols()-50)/2 ),
1294  NCPkgStrings::ErrorLabel(),
1295  NCPkgStrings::DiskSpaceError() + "<br>" + message +
1296  _( "You can choose to install anyway, but you risk getting a corrupted system." ),
1297  _( "&Continue anyway" ),
1299 
1300  spaceMsg->setPreferredSize( 50, 10 );
1301  spaceMsg->focusOkButton();
1302  NCursesEvent input = spaceMsg->showInfoPopup( );
1303 
1304  YDialog::deleteTopmostDialog();
1305 
1306  if ( input == NCursesEvent::cancel )
1307  {
1308  // disk space error warning returned `cancel
1309  closeDialog = false;
1310  }
1311  }
1312  }
1313 
1314  if ( closeDialog )
1315  {
1316  // clear the saved states
1317  // could free some memory?
1318  // clearSaveState ();
1319 
1320  writeSysconfig();
1321  const_cast<NCursesEvent &>(event).result = "accept";
1322  yuiMilestone() << "OK button pressed - leaving package selection, starting installation" << endl;
1323 
1324  // return false, leave the package selection
1325  return false;
1326  }
1327  else
1328  {
1329  NCPkgTable * packageList = PackageList();
1330  if ( packageList )
1331  {
1332  packageList->updateTable();
1333  packageList->setKeyboardFocus();
1334  }
1335  // don't leave the dialog
1336  return true;
1337  }
1338 }
1339 
1341 {
1342  bool allConfirmed = true;
1343 
1344  if ( youMode )
1345  allConfirmed = showPendingLicenseAgreements( zyppPatchesBegin(), zyppPatchesEnd() );
1346 
1347  allConfirmed = showPendingLicenseAgreements( zyppPkgBegin(), zyppPkgEnd() ) && allConfirmed;
1348 
1349  return allConfirmed;
1350 }
1351 
1352 bool NCPackageSelector::showPendingLicenseAgreements( ZyppPoolIterator begin, ZyppPoolIterator end )
1353 {
1354  yuiMilestone() << "Showing all pending license agreements" << endl;
1355 
1356  bool allConfirmed = true;
1357 
1358  for ( ZyppPoolIterator it = begin; it != end; ++it )
1359  {
1360  ZyppSel sel = (*it);
1361 
1362  switch ( sel->status() )
1363  {
1364  case S_Install:
1365  case S_AutoInstall:
1366  case S_Update:
1367  case S_AutoUpdate:
1368 
1369  if ( sel->candidateObj() )
1370  {
1371  std::string licenseText = sel->candidateObj()->licenseToConfirm();
1372 
1373  if ( ! licenseText.empty() )
1374  {
1375  yuiMilestone() << "Package/Patch " << sel->name().c_str() <<
1376  "has a license" << endl;
1377 
1378  if( ! sel->hasLicenceConfirmed() )
1379  {
1380  allConfirmed = showLicenseAgreement( sel, licenseText ) && allConfirmed;
1381  }
1382  else
1383  {
1384  yuiMilestone() << "License for " << sel->name().c_str() <<
1385  " is already confirmed" << endl;
1386  }
1387  }
1388  }
1389  break;
1390 
1391  default:
1392  break;
1393  }
1394  }
1395 
1396  return allConfirmed;
1397 }
1398 
1399 bool NCPackageSelector::showLicenseAgreement( ZyppSel & slbPtr , std::string licenseText )
1400 {
1401  if ( !slbPtr )
1402  return false;
1403 
1404  bool license_confirmed = true;
1405  bool ok = true;
1406  std::string pkgName = slbPtr->name();
1407 
1408  license_confirmed = showLicensePopup( pkgName, licenseText );
1409 
1410  if ( !license_confirmed )
1411  {
1412  // make sure the package won't be installed
1413  switch ( slbPtr->status() )
1414  {
1415  case S_Install:
1416  case S_AutoInstall:
1417  slbPtr->setStatus( S_Taboo );
1418  break;
1419 
1420  case S_Update:
1421  case S_AutoUpdate:
1422  slbPtr->setStatus( S_Protected );
1423  break;
1424 
1425  default:
1426  break;
1427  }
1428 
1429  ok = false;
1430  } else {
1431  yuiMilestone() << "User confirmed license agreement for " << pkgName << endl;
1432  slbPtr->setLicenceConfirmed (true);
1433  ok = true;
1434  }
1435 
1436  return ok;
1437 }
1438 
1439 ///////////////////////////////////////////////////////////////////
1440 //
1441 // showDependencies
1442 //
1443 // Checks and shows the dependencies
1444 //
1446 {
1447  bool ok = false;
1448  bool cancel = false;
1449 
1450  if ( doit || autoCheck )
1451  {
1452  yuiMilestone() << "Checking dependencies" << endl;
1453  cancel = checkNow( & ok );
1454  }
1455 
1456  return cancel;
1457 }
1458 
1459 ///////////////////////////////////////////////////////////////////
1460 //
1461 // showDependencies
1462 //
1463 // Checks and shows the dependencies
1464 //
1466 {
1467  showPackageDependencies (true);
1468 }
1469 
1470 ///////////////////////////////////////////////////////////////////
1471 //
1472 // createLicenseText
1473 //
1474 bool NCPackageSelector::showLicensePopup( std::string pkgName, std::string license )
1475 {
1476  std::string html_text = "";
1477  const std::string htmlIdent(DOCTYPETAG);
1478  bool confirmed = false;
1479 
1480  if ( license.find( htmlIdent ) != std::string::npos )
1481  {
1482  html_text = license; // HTML text
1483  }
1484  else
1485  {
1486  html_text = "<pre>" + license + "</pre>"; // add <pre> to preserve newlines and spaces
1487  }
1488 
1489  NCPopupInfo * info = new NCPopupInfo ( wpos( NCurses::lines()/10, NCurses::cols()/10),
1490  // headline of a popup showing the package license
1491  _( "End User License Agreement" ),
1492  "<i>" + pkgName + "</i><br><br>"
1493  + html_text,
1496 
1497  info->setPreferredSize( (NCurses::cols() * 80)/100, (NCurses::lines()*80)/100);
1498  info->focusOkButton();
1499  confirmed = info->showInfoPopup( ) != NCursesEvent::cancel;
1500 
1501  YDialog::deleteTopmostDialog();
1502 
1503  return confirmed;
1504 }
1505 
1506 ///////////////////////////////////////////////////////////////////
1507 //
1508 // updatePackageList
1509 //
1511 {
1512  NCPkgTable * packageList = PackageList();
1513 
1514  if ( packageList )
1515  {
1516  packageList->updateTable();
1517  }
1518 }
1519 
1520 ///////////////////////////////////////////////////////////////////
1521 //
1522 // showDiskSpace()
1523 //
1525 {
1526 
1527 
1528  // check whether required diskspace enters the warning range
1529  if ( diskspacePopup )
1530  {
1531  diskspacePopup->checkDiskSpaceRange( );
1532  // show pkg_diff, i.e. total difference of disk space (can be negative in installed system
1533  // if packages are deleted)
1534  if ( diskspaceLabel )
1535  {
1536  diskspaceLabel->setText( diskspacePopup->calculateDiff().asString() );
1537  }
1538  }
1539 }
1540 
1541 
1542 ///////////////////////////////////////////////////////////////////
1543 //
1544 // showDownloadSize()
1545 //
1546 // total download size of YOU patches
1547 //
1549 {
1550  std::set<ZyppSel> selectablesToInstall;
1551 
1552  for ( ZyppPoolIterator patches_it = zyppPatchesBegin();
1553  patches_it != zyppPatchesEnd();
1554  ++patches_it )
1555  {
1556  ZyppPatch patch = tryCastToZyppPatch( (*patches_it)->theObj() );
1557 
1558  if ( patch )
1559  {
1560  ZyppPatchContents patchContents( patch->contents() );
1561 
1562  for ( ZyppPatchContentsIterator contents_it = patchContents.selectableBegin();
1563  contents_it != patchContents.selectableEnd();
1564  ++contents_it )
1565  {
1566  ZyppPkg pkg = tryCastToZyppPkg( (*contents_it)->theObj() );
1567  ZyppSel sel;
1568 
1569  if ( pkg )
1570  sel = selMapper.findZyppSel( pkg );
1571 
1572 
1573  if ( sel )
1574  {
1575  switch ( sel->status() )
1576  {
1577  case S_Install:
1578  case S_AutoInstall:
1579  case S_Update:
1580  case S_AutoUpdate:
1581  // Insert the patch contents selectables into a set,
1582  // don't immediately sum up their sizes: The same
1583  // package could be in more than one patch, but of
1584  // course it will be downloaded only once.
1585 
1586  selectablesToInstall.insert( sel );
1587  break;
1588 
1589  case S_Del:
1590  case S_AutoDel:
1591  case S_NoInst:
1592  case S_KeepInstalled:
1593  case S_Taboo:
1594  case S_Protected:
1595  break;
1596 
1597  // intentionally omitting 'default' branch so the compiler can
1598  // catch unhandled enum states
1599  }
1600 
1601  }
1602  }
1603  }
1604  }
1605 
1606  FSize totalSize = 0;
1607 
1608  for ( std::set<ZyppSel>::iterator it = selectablesToInstall.begin();
1609  it != selectablesToInstall.end();
1610  ++it )
1611  {
1612  if ( (*it)->candidateObj() )
1613  totalSize += (*it)->candidateObj()->installSize();
1614  }
1615 
1616  // show the download size
1617  if ( diskspaceLabel )
1618  {
1619  diskspaceLabel->setText( totalSize.asString() );
1620  }
1621 }
1622 
1623 
1624 ///////////////////////////////////////////////////////////////////
1625 //
1626 // PackageList()
1627 //
1628 NCPkgTable * NCPackageSelector::PackageList()
1629 {
1630  return pkgList;
1631 }
1632 
1633 //
1634 // Create layout for Online Update
1635 //
1636 void NCPackageSelector::createYouLayout( YWidget * selector )
1637 {
1638  // the vertical split is the (only) child of the dialog
1639  YLayoutBox * split = YUI::widgetFactory()->createVBox( selector );
1640 
1641  YLayoutBox * hSplit = YUI::widgetFactory()->createHBox( split );
1642 
1643  YAlignment * left1 = YUI::widgetFactory()->createLeft( hSplit );
1644  filterMenu = new NCPkgMenuFilter( left1, NCPkgStrings::Filter(), this );
1645 
1646  YAlignment * left2 = YUI::widgetFactory()->createLeft( hSplit );
1647  actionMenu = new NCPkgMenuAction( left2, NCPkgStrings::Actions(), this );
1648 
1649  YAlignment * left3 = YUI::widgetFactory()->createLeft( hSplit );
1650  viewMenu = new NCPkgMenuView( left3, NCPkgStrings::View(), this);
1651 
1652  YAlignment * left4 = YUI::widgetFactory()->createLeft( hSplit );
1653  depsMenu = new NCPkgMenuDeps( left4, NCPkgStrings::Deps(), this);
1654 
1655  // add the package table
1656  YTableHeader * tableHeader = new YTableHeader();
1657 
1658  pkgList = new NCPkgTable( split, tableHeader );
1659  YUI_CHECK_NEW( pkgList );
1660 
1661  // set table type 'T_Patches'
1662  NCPkgStatusStrategy * strategy;
1663  strategy = new PatchStatStrategy();
1664  pkgList->setTableType( NCPkgTable::T_Patches, strategy );
1665  pkgList->fillHeader();
1666 
1667  // set the pointer to the packager object
1668  pkgList->setPackager( this );
1669 
1670  // set sort strategy
1671  std::vector<std::string> pkgHeader;
1672  pkgList->getHeader( pkgHeader );
1673  pkgList->setSortStrategy( new NCPkgTableSort( pkgHeader ) );
1674 
1675  // HBox for Filter and Disk Space (both in additional HBoxes )
1676  YLayoutBox * hSplit2 = YUI::widgetFactory()->createHBox( split );
1677 
1678  YLayoutBox * hSplit3 = YUI::widgetFactory()->createHBox( hSplit2 );
1679  // label text - keep it short
1680  new NCLabel( hSplit3, _( "Filter: " ) );
1681  packageLabel = YUI::widgetFactory()->createLabel ( hSplit3, "....................................." );
1682 
1683  new NCSpacing( hSplit2, YD_HORIZ, true, 0.5 );
1684 
1685  YLayoutBox * hSplit4 = YUI::widgetFactory()->createHBox( hSplit2 );
1686  // label text - keep it short (use abbreviation if necessary)
1687  new NCLabel( hSplit4, _( "Total Download Size: " ) );
1688  // create label with spaces to have enough space available for download size
1689  diskspaceLabel = YUI::widgetFactory()->createLabel ( hSplit4, " " );
1690 
1691  YLayoutBox * vSplit = YUI::widgetFactory()->createVBox( split );
1692  replacePoint = YUI::widgetFactory()->createReplacePoint( vSplit );
1693 
1694  infoText = new NCPkgPackageDetails( replacePoint, " ", this );
1695  YUI_CHECK_NEW( infoText );
1696 
1697  YLayoutBox * bottom_bar = YUI::widgetFactory()->createHBox( vSplit );
1698  YAlignment *ll = YUI::widgetFactory()->createLeft( bottom_bar );
1699 
1700  helpMenu = new NCPkgMenuHelp (ll, _( "&Help" ), this);
1701 
1702  YAlignment *r = YUI::widgetFactory()->createRight( bottom_bar );
1703  YLayoutBox * hSplit5 = YUI::widgetFactory()->createHBox( r );
1704 
1705  // add the Cancel button
1706  cancelButton = new NCPushButton( hSplit5, _( "&Cancel" ) );
1707  YUI_CHECK_NEW( cancelButton );
1708  cancelButton->setFunctionKey( 9 );
1709 
1710  // add the OK button
1711  okButton = new NCPushButton( hSplit5, _( "&Accept" ) );
1712  YUI_CHECK_NEW( okButton );
1713  okButton->setFunctionKey( 10 );
1714 
1715 }
1716 
1717 //
1718 // Create layout for Package Selector
1719 //
1720 void NCPackageSelector::createPkgLayout( YWidget * selector, NCPkgTable::NCPkgTableType type )
1721 {
1722  // the vertical split is the (only) child of the dialog
1723  YLayoutBox * vsplit = YUI::widgetFactory()->createVBox( selector );
1724  YLayoutBox * menu_bar = YUI::widgetFactory()->createHBox( vsplit );
1725  YLayoutBox * panels = YUI::widgetFactory()->createVBox( vsplit );
1726  YLayoutBox * bottom_bar = YUI::widgetFactory()->createHBox( vsplit );
1727 
1728  YAlignment * left1 = YUI::widgetFactory()->createLeft( menu_bar );
1729 
1730  YLayoutBox * menu_buttons = YUI::widgetFactory()->createHBox( left1);
1731  depsMenu = new NCPkgMenuDeps( menu_buttons, NCPkgStrings::Deps(), this);
1732  viewMenu = new NCPkgMenuView( menu_buttons, NCPkgStrings::View(), this);
1733 
1734  //Add only if requested by `opt(`repoMgr) flag - #381956
1735  if (isRepoMgrEnabled())
1736  configMenu = new NCPkgMenuConfig( menu_buttons, _( "C&onfiguration" ), this);
1737 
1738  extrasMenu = new NCPkgMenuExtras( menu_buttons, NCPkgStrings::Extras(), this);
1739 
1740  YLayoutBox * hbox_top = YUI::widgetFactory()->createHBox( panels );
1741  YLayoutBox * hbox_bottom = YUI::widgetFactory()->createHBox( panels );
1742 
1743  YLayoutBox * vbox_left = YUI::widgetFactory()->createVBox( hbox_top );
1744  vbox_left->setWeight(YD_HORIZ,1);
1745  YFrame * fr = YUI::widgetFactory()->createFrame (vbox_left, "");
1746  YLayoutBox * vv = YUI::widgetFactory()->createVBox( fr );
1747  YAlignment *l = YUI::widgetFactory()->createLeft( vv );
1748  filterMain = new NCPkgFilterMain (l, NCPkgStrings::Filter(), this );
1749 
1750  replPoint = YUI::widgetFactory()->createReplacePoint( vv );
1751  //Search view is now default (#404694)
1752  searchPopup = new NCPkgFilterSearch( replPoint, YD_VERT, this );
1753  searchPopup->createLayout( replPoint );
1754 
1755  searchField = searchPopup->getSearchField();
1756  if ( searchField )
1757  {
1758  searchField->setKeyboardFocus();
1759  searchField->setNotify( true );
1760  }
1761 
1762  YAlignment *l1 = YUI::widgetFactory()->createLeft( vbox_left );
1763  patternLabel = new NCLabel( l1, " " );
1764 
1765  // add the package table
1766  YTableHeader * tableHeader = new YTableHeader();
1767 
1768  YLayoutBox * v = YUI::widgetFactory()->createVBox( hbox_top );
1769  v->setWeight(YD_HORIZ,2);
1770  pkgList = new NCPkgTable( v, tableHeader );
1771  YUI_CHECK_NEW( pkgList );
1772 
1773  NCPkgStatusStrategy * strategy;
1774  // set table type and status strategy (either 'normal' package list or update list)
1775  switch ( type )
1776  {
1777  case NCPkgTable::T_Packages:
1778  strategy = new PackageStatStrategy();
1779  pkgList->setTableType( NCPkgTable::T_Packages, strategy );
1780  case NCPkgTable::T_Update:
1781  strategy = new UpdateStatStrategy();
1782  pkgList->setTableType( NCPkgTable::T_Update, strategy );
1783  default:
1784  strategy = new PackageStatStrategy();
1785  pkgList->setTableType( NCPkgTable::T_Packages, strategy );
1786  }
1787  // set the pointer to the packager object
1788  pkgList->setPackager( this );
1789  pkgList->fillHeader();
1790 
1791  // set sort strategy
1792  std::vector<std::string> pkgHeader;
1793  pkgList->getHeader( pkgHeader );
1794  pkgList->setSortStrategy( new NCPkgTableSort( pkgHeader ) );
1795 
1796  // label text + actions menu
1797  YLayoutBox * hSplit2 = YUI::widgetFactory()->createHBox( v );
1798  new NCLabel( hSplit2, NCPkgStrings::PackageName() );
1799  packageLabel = YUI::widgetFactory()->createLabel ( hSplit2, "......................" );
1800  new NCSpacing( hSplit2, YD_HORIZ, true, 0.5 );
1801  actionMenu = new NCPkgMenuAction ( hSplit2, NCPkgStrings::Actions(), this );
1802 
1803  //Search parameters resp. filter description
1804  replPoint2 = YUI::widgetFactory()->createReplacePoint( hbox_bottom );
1805  replPoint2->setWeight(YD_HORIZ, 1);
1806  searchSet = new NCPkgSearchSettings( replPoint2, NCPkgStrings::SearchIn() );
1807 
1808  //Package description resp. package version table
1809  YLayoutBox * vSplit = YUI::widgetFactory()->createVBox( hbox_bottom );
1810  vSplit->setWeight(YD_HORIZ, 2);
1811  replacePoint = YUI::widgetFactory()->createReplacePoint( vSplit );
1812  infoText = new NCPkgPackageDetails( replacePoint, " ", this );
1813  YUI_CHECK_NEW( infoText );
1814 
1815  //Bottom button bar
1816  YAlignment *ll = YUI::widgetFactory()->createLeft( bottom_bar );
1817  helpMenu = new NCPkgMenuHelp (ll, _( "&Help" ), this);
1818  YUI_CHECK_NEW( helpMenu );
1819 
1820  //right-alignment for OK-Cancel
1821  YAlignment *right = YUI::widgetFactory()->createRight( bottom_bar );
1822  YLayoutBox * hSplit = YUI::widgetFactory()->createHBox( right );
1823 
1824  // add the Cancel button
1825  cancelButton = new NCPushButton( hSplit, _( "&Cancel" ) );
1826  YUI_CHECK_NEW( cancelButton );
1827  cancelButton->setFunctionKey( 9 );
1828 
1829  // add the OK button
1830  okButton = new NCPushButton( hSplit, _( "&Accept" ) );
1831  YUI_CHECK_NEW( okButton );
1832  okButton->setFunctionKey( 10 );
1833 
1834 }
1835 
1836 //
1837 // Fill package list with packages of default RPM group/update list or installable patches
1838 //
1840 {
1841  if ( !pkgList )
1842  return false;
1843 
1844  yuiMilestone() << "Filling package list: " << (NCWidget *) pkgList << endl;
1845 
1846  switch ( pkgList->getTableType() )
1847  {
1848  case NCPkgTable::T_Patches: {
1849  fillPatchList( NCPkgMenuFilter::F_Needed ); // default: needed patches
1850 
1851  // set the visible info to long description
1852  pkgList->setVisibleInfo(NCPkgTable::I_PatchDescr);
1853  // show the patch description of the current item
1854  pkgList->showInformation ();
1855  pkgList->setKeyboardFocus();
1856  break;
1857  }
1858  case NCPkgTable::T_Update: {
1859  if ( ! zypp::getZYpp()->resolver()->problematicUpdateItems().empty() )
1860  {
1861  fillUpdateList();
1862  // set the visible info to technical information
1863  pkgList->setVisibleInfo(NCPkgTable::I_Technical);
1864  // show the package information of the current item
1865  pkgList->showInformation ();
1866  break;
1867  }
1868  }
1869  case NCPkgTable::T_Packages: {
1870  //Search view is the default (#404694)
1871  pkgList->setVisibleInfo(NCPkgTable::I_Technical);
1872  searchField->setKeyboardFocus();
1873  break;
1874  }
1875  default:
1876  break;
1877  }
1878 
1879  // if started with `repoMode or `summaryMode replace filter accordingly
1880  if ( repoMode )
1881  {
1882  replaceFilter ( NCPackageSelector::Repositories );
1883  if ( filterMain)
1884  filterMain->setReposSelected();
1885  }
1886  else if ( summaryMode )
1887  {
1888  replaceFilter ( NCPackageSelector::Summary );
1889  if ( filterMain )
1890  filterMain->setSummarySelected();
1891  }
1892 
1893  return true;
1894 
1895 }