source: projects/synaptic/trunk/common/rpackageview.cc @ 280

Revision 280, 11.8 KB checked in by yasumichi, 13 years ago (diff)

first import

Line 
1/* rpackageview.cc - Package sectioning system
2 *
3 * Copyright (c) 2000, 2001 Conectiva S/A
4 *               2002 Michael Vogt <mvo@debian.org>
5 *
6 * Author: Alfredo K. Kojima <kojima@conectiva.com.br>
7 *         Michael Vogt <mvo@debian.org>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of the
12 * License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
22 * USA
23 */
24
25#include <apt-pkg/pkgrecords.h>
26#include <apt-pkg/configuration.h>
27#include <rpackage.h>
28#include <rpackageview.h>
29#include <rconfiguration.h>
30
31#include <map>
32#include <vector>
33#include <sstream>
34
35#include "sections_trans.h"
36
37using namespace std;
38
39bool RPackageView::setSelected(string name)
40{
41   map<string, vector<RPackage *> >::iterator I = _view.find(name);
42   if (I != _view.end()) {
43      _hasSelection = true;
44      _selectedName = name;
45      _selectedView = (*I).second;
46   } else {
47      clearSelection();
48   }
49   return _hasSelection;
50}
51
52vector<string> RPackageView::getSubViews()
53{
54   vector<string> subViews;
55   for (map<string, vector<RPackage *> >::iterator I = _view.begin();
56        I != _view.end(); I++)
57      subViews.push_back((*I).first);
58   return subViews;
59}
60
61void RPackageView::clear()
62{
63   clearSelection();
64   _view.clear();
65}
66
67void RPackageView::clearSelection()
68{
69   _hasSelection = false;
70   _selectedName.clear();
71   _selectedView.clear();
72}
73
74void RPackageViewSections::addPackage(RPackage *package)
75{
76   string str = trans_section(package->section());
77   _view[str].push_back(package);
78};
79
80RPackageViewStatus::RPackageViewStatus(vector<RPackage *> &allPkgs) 
81   : RPackageView(allPkgs), markUnsupported(false)
82{
83   if(_config->FindB("Synaptic::mark-unsupported",false)) {
84      markUnsupported = true;
85      string components = _config->Find("Synaptic::supported-components", "main updates/main");
86
87      stringstream sstream(components);
88      string s;
89      while(!sstream.eof()) {
90         sstream >> s;
91         supportedComponents.push_back(s);
92      }
93   }
94};
95
96void RPackageViewStatus::addPackage(RPackage *pkg)
97{
98   string str;
99   int flags = pkg->getFlags();
100   string component = pkg->component();
101   bool unsupported = false;
102   
103   // we mark packages as unsupported if requested
104   if(markUnsupported) {
105      unsupported = true;
106      for(unsigned int i=0;i<supportedComponents.size();i++) {
107         if(supportedComponents[i] == component) {
108            unsupported = false;
109            break;
110         }
111      }
112   }
113
114   if(flags & RPackage::FInstalled) {
115      if( !(flags & RPackage::FNotInstallable) && unsupported)
116         str = _("Installed (unsupported)");
117      else 
118         str = _("Installed");
119   } else {
120      if( unsupported )
121         str = _("Not installed (unsupported)");
122      else
123         str = _("Not installed");
124   }
125   _view[str].push_back(pkg);
126
127   str.clear();
128   if (flags & RPackage::FNew)
129      str = _("New in repository");
130   else if (flags & RPackage::FPinned) 
131      str = _("Pinned");
132   else if ((flags & RPackage::FNotInstallable) &&
133            !(flags & RPackage::FResidualConfig) &&
134            (flags & RPackage::FInstalled))
135      str = _("Installed (local or obsolete)");
136   else if (flags & RPackage::FInstalled) {
137      if (flags & RPackage::FOutdated)
138         str = _("Installed (upgradable)");
139   } else {
140      if (flags & RPackage::FResidualConfig)
141         str = _("Not installed (residual config)");
142   }
143
144   if(!str.empty())
145      _view[str].push_back(pkg);
146}
147
148//------------------------------------------------------------------
149
150void RPackageViewSearch::addPackage(RPackage *pkg)
151{
152   string str;
153   const char *tmp=NULL;
154   bool global_found=true;
155
156   if(!pkg || searchStrings.empty())
157      return;
158
159   // build the string
160   switch(searchType) {
161   case RPatternPackageFilter::Name:
162      tmp = pkg->name();
163      break;
164   case RPatternPackageFilter::Version:
165      tmp = pkg->availableVersion();
166      break;
167   case RPatternPackageFilter::Description:
168      str = pkg->name();
169      str += string(pkg->description());
170      break;
171   case RPatternPackageFilter::Maintainer:
172      tmp = pkg->maintainer();
173      break;
174   case RPatternPackageFilter::Depends: 
175      {
176         vector<DepInformation> d = pkg->enumDeps(true);
177         for(unsigned int i=0;i<d.size();i++)
178            str += string(d[i].name);
179         break; 
180      }
181   case RPatternPackageFilter::Provides: 
182      {
183         vector<string> d = pkg->provides();
184         for(unsigned int i=0;i<d.size();i++)
185            str += d[i];
186         break;
187      }
188   }
189
190   if(tmp!=NULL)
191      str = tmp;
192     
193   // find the search pattern in the string "str"
194   for(unsigned int i=0;i<searchStrings.size();i++) {
195      string searchString = searchStrings[i];
196
197      if(!str.empty() && strcasestr(str.c_str(), searchString.c_str())) {
198         global_found &= true;
199      } else {
200         global_found &= false;
201      }
202   }
203   if(global_found) {
204      _view[searchName].push_back(pkg);
205      found++;
206   }
207
208   // FIXME: we push a _lot_ of empty pkgs here :(
209   // push a empty package in the view to make sure that the view is actually
210   // displayed
211   //_view[searchString].push_back(NULL);
212}
213
214int RPackageViewSearch::setSearch(string aSearchName, int type, 
215                                  string searchString)
216{
217   found = 0;
218   searchType = type;
219   searchName = aSearchName;
220
221   _view[searchName].clear();
222   searchStrings.clear();
223
224   // tokenize the str and add to the searchString vector
225   stringstream sstream(searchString);
226   string s;
227   while(!sstream.eof()) {
228      sstream >> s;
229      searchStrings.push_back(s);
230   }
231
232   // reapply search when a new search strng is giben
233   for(unsigned int i=0;i<_all.size();i++) 
234      if(_all[i]) 
235         addPackage(_all[i]);
236         
237   return found;
238}
239
240//------------------------------------------------------------------
241
242RPackageViewFilter::RPackageViewFilter(vector<RPackage *> &allPkgs) 
243   : RPackageView(allPkgs)
244{
245   // restore the filters
246   restoreFilters();
247
248   refreshFilters();
249}
250
251void RPackageViewFilter::refreshFilters()
252{
253   _view.clear();
254
255   // create a empty sub-views for each filter
256   for (vector<RFilter *>::iterator I = _filterL.begin();
257        I != _filterL.end(); I++) {
258      _view[(*I)->getName()].push_back(NULL);
259   }
260}
261
262int RPackageViewFilter::getFilterIndex(RFilter *filter)
263{
264  if (filter == NULL)
265     filter = findFilter(_selectedName);
266  for(unsigned int i=0;i<_filterL.size();i++)  {
267    if(filter == _filterL[i])
268      return i;
269  }
270  return -1;
271}
272
273
274RPackageViewFilter::iterator RPackageViewFilter::begin() 
275{ 
276//    cout << "RPackageViewFilter::begin() " << _selectedName <<  endl;
277
278   string name = _selectedName;
279   RFilter *filter = findFilter(name);
280
281   if(filter != NULL) {
282      _view[name].clear();
283
284      for(unsigned int i=0;i<_all.size();i++) {
285         if(_all[i] && filter->apply(_all[i]))
286            _view[name].push_back(_all[i]);
287      }
288      _selectedView = _view[name];
289   }
290
291   return _selectedView.begin(); 
292}
293
294vector<string> RPackageViewFilter::getFilterNames()
295{
296   vector<string> filters;
297   for (unsigned int i = 0; i != _filterL.size(); i++)
298      filters.push_back(_filterL[i]->getName());
299   return filters;
300}
301
302
303void RPackageViewFilter::addPackage(RPackage *pkg)
304{
305   // nothing to do for now, may add some sort of caching later
306   _sectionList.insert(pkg->section());
307}
308
309void RPackageViewFilter::storeFilters()
310{
311   ofstream out;
312
313   if (!RFilterDataOutFile(out))
314      return;
315
316   for (vector<RFilter *>::const_iterator iter = _filterL.begin();
317        iter != _filterL.end(); iter++) {
318
319      (*iter)->write(out);
320   }
321
322   out.close();
323}
324
325void RPackageViewFilter::restoreFilters()
326{
327   Configuration config;
328   RReadFilterData(config);
329
330   RFilter *filter;
331   const Configuration::Item *top = config.Tree("filter");
332   for (top = (top == 0 ? 0 : top->Child); top != 0; top = top->Next) {
333      filter = new RFilter();
334      filter->setName(top->Tag);
335
336      string filterkey = "filter::" + top->Tag;
337      if (filter->read(config, filterkey)) {
338         registerFilter(filter);
339      } else {
340         delete filter;
341      }
342   }
343
344   // Introduce new preset filters in the current config file.
345   // Already existent filters will be ignored, since the name
346   // will clash.
347   makePresetFilters();
348}
349
350bool RPackageViewFilter::registerFilter(RFilter *filter)
351{
352   string Name = filter->getName();
353   for (vector<RFilter *>::const_iterator I = _filterL.begin();
354        I != _filterL.end(); I++) {
355      if ((*I)->getName() == Name) {
356         delete filter;
357         return false;
358      }
359   }
360   _filterL.push_back(filter);
361   return true;
362}
363
364void RPackageViewFilter::unregisterFilter(RFilter *filter)
365{
366   for (vector<RFilter *>::iterator I = _filterL.begin();
367        I != _filterL.end(); I++) {
368      if (*I == filter) {
369         _filterL.erase(I);
370         return;
371      }
372   }
373}
374
375RFilter* RPackageViewFilter::findFilter(string name)
376{
377   RFilter *filter=NULL;
378   // find filter
379   for (vector<RFilter *>::iterator I = _filterL.begin();
380        I != _filterL.end(); I++) {
381      if((*I)->getName() == name) {
382         filter = (*I);
383      }
384   }
385   return filter;
386}
387
388// we make only preset filters that are not covered by the status view
389void RPackageViewFilter::makePresetFilters()
390{
391   RFilter *filter;
392
393   // Notice that there's a little hack in filter names below. They're
394   // saved *without* i18n, but there's an i18n version for i18n. This
395   // allows i18n to be done in RFilter.getName().
396   {
397      filter = new RFilter();
398      filter->preset = true;
399      filter->setName("Search Filter");
400      _("Search Filter");
401      registerFilter(filter);
402   }
403#ifdef HAVE_RPM
404   {
405      filter = new RFilter();
406      filter->pattern.addPattern(RPatternPackageFilter::Name,
407                                 "^task-.*", false);
408      filter->setName("Tasks"); _("Tasks");
409      registerFilter(filter);
410   }
411   {
412      filter = new RFilter();
413      filter->reducedview.enable();
414      filter->setName("Reduced View"); _("Reduced View");
415      registerFilter(filter);
416   }
417#endif
418   {
419      filter = new RFilter();
420      filter->preset = true;
421      filter->status.setStatus(RStatusPackageFilter::Broken);
422      filter->setName("Broken"); _("Broken");
423      registerFilter(filter);
424   }
425   {
426      filter = new RFilter();
427      filter->preset = true;
428      filter->status.setStatus(RStatusPackageFilter::MarkInstall
429                               | RStatusPackageFilter::MarkRemove
430                               | RStatusPackageFilter::Broken);
431      filter->setName("Marked Changes"); _("Marked Changes");
432      registerFilter(filter);
433   }
434#ifndef HAVE_RPM
435   {
436      filter = new RFilter();
437      filter->preset = true;
438      filter->pattern.addPattern(RPatternPackageFilter::Depends,
439                                 "^debconf", false);
440      // TRANSLATORS: This is a filter that will give you all packages
441      // with debconf support (that can be reconfigured with debconf)
442      filter->setName("Package with Debconf"); _("Package with Debconf");
443      registerFilter(filter);
444   }
445#endif
446   filter = new RFilter();
447   filter->preset = true;
448   filter->status.setStatus(RStatusPackageFilter::UpstreamUpgradable);
449   filter->setName("Upgradable (upstream)"); _("Upgradable (upstream)");
450   registerFilter(filter);
451
452   {
453      filter = new RFilter();
454      filter->pattern.addPattern(RPatternPackageFilter::Name,
455                                 "#", false);
456      filter->pattern.addPattern(RPatternPackageFilter::Name,
457                                 "^kernel*", true);
458      filter->setName("Multiple Versions"); _("Multiple Versions");
459      registerFilter(filter);
460   }
461}
462
463
464// vim:sts=3:sw=3
Note: See TracBrowser for help on using the repository browser.