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