libyui-ncurses-pkg  2.50.7
NCPkgMenuExtras.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: NCPkgMenuExtras.cc
37 
38  Author: Hedgehog Painter <kmachalkova@suse.cz>
39 
40 /-*/
41 #define YUILogComponent "ncurses-pkg"
42 #include <YUILog.h>
43 
44 #include "NCPkgMenuExtras.h"
45 #include "NCPackageSelector.h"
46 #include "NCPopupInfo.h"
47 
48 #include <boost/bind.hpp>
49 #include <fstream>
50 #include <iomanip>
51 #include <zypp/SysContent.h>
52 
53 using std::endl;
54 
55 typedef zypp::syscontent::Reader::Entry ZyppReaderEntry;
56 typedef std::pair<std::string, ZyppReaderEntry> importMapPair;
57 
58 #define DEFAULT_EXPORT_FILE_NAME "user-packages.xml"
59 
60 /*
61  Textdomain "ncurses-pkg"
62 */
63 
64 NCPkgMenuExtras::NCPkgMenuExtras (YWidget *parent, std::string label, NCPackageSelector *pkger)
65  : NCMenuButton( parent, label)
66  , pkg (pkger)
67 {
68  createLayout();
69 }
70 
71 NCPkgMenuExtras::~NCPkgMenuExtras()
72 {
73 
74 }
75 
76 void NCPkgMenuExtras::createLayout()
77 {
78  exportFile = new YMenuItem( _( "&Export Package List to File" ) );
79  items.push_back( exportFile );
80 
81  importFile = new YMenuItem( _( "&Import Package List from File" ) );
82  items.push_back( importFile );
83 
84  diskSpace = new YMenuItem( _( "&Show Available Disk Space" ) );
85  items.push_back( diskSpace );
86 
87  if ( pkg->isOnlineSearchEnabled() ) {
88  onlineSearch = new YMenuItem(_("Search &Online"));
89  items.push_back(onlineSearch);
90  }
91 
92  addItems( items );
93 }
94 
95 bool NCPkgMenuExtras::handleEvent ( const NCursesEvent & event)
96 {
97  if (!event.selection)
98  return false;
99 
100  if ( event.selection == exportFile )
101  exportToFile();
102  else if ( event.selection == importFile )
103  importFromFile();
104  else if ( event.selection == diskSpace )
105  showDiskSpace();
106  else if ( event.selection == onlineSearch ) {
107  const_cast<NCursesEvent &>(event).result = "online_search";
108  yuiMilestone() << "Launching online search " << endl;
109 
110  //and close the main loop
111  return false;
112  }
113 
114  /*else if ( event.selection == repoManager )
115  {
116  // return `repo_mgr symbol to YCP module (FaTE #302517)
117  const_cast<NCursesEvent &>(event).result = "repo_mgr";
118  yuiMilestone() << "Launching repository manager " << endl;
119 
120  // and close the main loop
121  return false;
122  }*/
123  return true;
124 }
125 
126 void NCPkgMenuExtras::importSelectable( ZyppSel selectable, bool isWanted, const char*kind )
127 {
128  ZyppStatus oldStatus = selectable->status();
129  ZyppStatus newStatus = oldStatus;
130 
131  // Package/Pattern is on the list
132  if (isWanted)
133  {
134  switch (oldStatus)
135  {
136  // Keep status for installed ones
137  case S_Install:
138  case S_AutoInstall:
139  case S_Update:
140  case S_AutoUpdate:
141  case S_KeepInstalled:
142  case S_Protected:
143  newStatus = oldStatus;
144  break;
145 
146  // Keep also those marked for deletion
147  case S_Del:
148  case S_AutoDel:
149  newStatus = S_KeepInstalled;
150  yuiDebug() << "Keeping " << kind << " " << selectable->name().c_str() << endl;
151  break;
152 
153  // Add not yet installed pkgs (if they have candidate available)
154  case S_NoInst:
155  case S_Taboo:
156  if ( selectable->hasCandidateObj() )
157  {
158  newStatus = S_Install;
159  yuiDebug() << "Adding " << kind << " " << selectable->name().c_str() << endl;
160  }
161  else
162  {
163  yuiDebug() << "Cannot add " << kind << " " << selectable->name().c_str() <<
164  " " << " - no candidate." << endl;
165  }
166  break;
167  }
168  }
169  // Package/Pattern is not on the list
170  else
171  {
172  switch (oldStatus)
173  {
174  // Mark installed ones for deletion
175  case S_Install:
176  case S_AutoInstall:
177  case S_Update:
178  case S_AutoUpdate:
179  case S_KeepInstalled:
180  case S_Protected:
181  newStatus = S_Del;
182  yuiDebug() << "Deleting " << kind << " " << selectable->name().c_str() << endl;
183  break;
184 
185  // Keep status for not installed, taboo and to-be-deleted
186  case S_Del:
187  case S_AutoDel:
188  case S_NoInst:
189  case S_Taboo:
190  newStatus = oldStatus;
191  break;
192  }
193  }
194 
195  if (oldStatus != newStatus)
196  selectable->setStatus( newStatus );
197 }
198 
199 
200 bool NCPkgMenuExtras::exportToFile()
201 { // Ask for file to save into
202  std::string filename = YUI::app()->askForSaveFileName( DEFAULT_EXPORT_FILE_NAME,
203  "*.xml",
204  _( "Export List of All Packages and Patterns to File" ));
205 
206  if ( ! filename.empty() )
207  {
208  zypp::syscontent::Writer writer;
209  const zypp::ResPool & pool = zypp::getZYpp()->pool();
210 
211  // some strange C++ magic (c) by ma
212  for_each( pool.begin(), pool.end(),
213  boost::bind( &zypp::syscontent::Writer::addIf,
214  boost::ref(writer),
215  _1));
216 
217  try
218  {
219  // open file for writing and try to dump syscontent into it
220  std::ofstream exportFile( filename.c_str() );
221  exportFile.exceptions(std::ios_base::badbit | std::ios_base::failbit );
222  exportFile << writer;
223 
224  yuiMilestone() << "Exported list of packages and patterns to " << filename << endl;
225  }
226 
227  catch (std::exception & exception)
228  {
229  yuiWarning() << "Error exporting list of packages and patterns to " << filename << endl;
230 
231  // delete partially written file (don't care if it doesn't exist)
232  (void) unlink( filename.c_str() );
233 
234  // present error popup to the user
235  NCPopupInfo * errorMsg = new NCPopupInfo( wpos( (NCurses::lines()-5)/2, (NCurses::cols()-40)/2 ),
236  NCPkgStrings::ErrorLabel(),
237  _( "Error exporting list of packages and patterns to " )
238  // FIXME: String addition is evil for translators!
239  + filename,
241  "");
242  errorMsg->setPreferredSize(40, 5);
243  NCursesEvent input = errorMsg->showInfoPopup();
244 
245  YDialog::deleteTopmostDialog();
246  }
247 
248  return true;
249  }
250 
251  return false;
252 }
253 
254 bool NCPkgMenuExtras::importFromFile()
255 {
256  // ask for file to open
257  std::string filename = YUI::app()->askForExistingFile( DEFAULT_EXPORT_FILE_NAME,
258  "*.xml",
259  _( "Import List of All Packages and Patterns from File" ));
260  if ( ! filename.empty() )
261  {
262  NCPkgTable * packageList = pkg->PackageList();
263  yuiMilestone() << "Importing list of packages and patterns from " << filename << endl;
264 
265  try
266  {
267  std::ifstream importFile ( filename.c_str() );
268  zypp::syscontent::Reader reader (importFile);
269 
270  // maps to store package/pattern data into
271  std::map<std::string, ZyppReaderEntry> importPkgs;
272  std::map<std::string, ZyppReaderEntry> importPatterns;
273 
274  // Import syscontent reader to a map $[ "package_name" : pointer_to_data]
275  for (zypp::syscontent::Reader::const_iterator it = reader.begin();
276  it != reader.end();
277  it ++ )
278  {
279  std::string kind = it->kind();
280 
281  // importMapPair => std::pair<std::string, ZyppReaderEntry>
282  if ( kind == "package" )
283  importPkgs.insert( importMapPair( it->name(), *it ) );
284  else if ( kind == "pattern" )
285  importPatterns.insert( importMapPair( it->name(), *it ) );
286  }
287 
288  yuiMilestone() << "Found " << importPkgs.size() << " packages and " << importPatterns.size() << " patterns." << endl;
289 
290  // Change status of appropriate packages and patterns
291  for (ZyppPoolIterator it = zyppPkgBegin();
292  it != zyppPkgEnd();
293  it++ )
294  {
295  ZyppSel selectable = *it;
296  // isWanted => package name found in importPkgs map
297  importSelectable ( *it, importPkgs.find( selectable->name() ) != importPkgs.end(), "package" );
298  }
299 
300  for (ZyppPoolIterator it = zyppPatternsBegin();
301  it != zyppPatternsEnd();
302  it++ )
303  {
304  ZyppSel selectable = *it;
305  importSelectable ( *it, importPatterns.find( selectable->name() ) != importPatterns.end(), "pattern" );
306  }
307 
308  // Switch to installation summary filter
309  packageList->fillSummaryList(NCPkgTable::L_Changes);
310 
311  //... and finally display the result
312  packageList->showInformation();
313  packageList->setKeyboardFocus();
314 
315  return true;
316  }
317  catch ( const zypp::Exception & exception )
318  {
319  yuiWarning() << "Error importing list of packages and patterns from" << filename << endl;
320 
321  NCPopupInfo * errorMsg = new NCPopupInfo( wpos( (NCurses::lines()-5)/2, (NCurses::cols()-40)/2) ,
322  NCPkgStrings::ErrorLabel(),
323  _( "Error importing list of packages and patterns from " )
324  // FIXME: String addition is evil for translators!
325  + filename,
327  "");
328  errorMsg->setPreferredSize(40, 5);
329  NCursesEvent input = errorMsg->showInfoPopup();
330 
331  YDialog::deleteTopmostDialog();
332  }
333  }
334  return true;
335 
336 }
337 
338 bool NCPkgMenuExtras::showDiskSpace()
339 {
340  pkg->diskSpacePopup()->showInfoPopup( NCPkgStrings::DiskspaceLabel() );
341  // FIXME: move focus back to pkg table?
342 
343  return true;
344 }
bool showInformation()
Show the corresponding information (e.g.
Definition: NCPkgTable.cc:731
The package table class.
Definition: NCPkgTable.h:205
static const std::string DiskspaceLabel()
The headline of the disk space popup.
static const std::string OKLabel()
The label of the OK button.