Defer setting group until after All Users/Just For Me is chosen
[cygwin-setup.git] / PickView.cc
blobc961b9f26434ced06f04f2e154e143e2587dc517
1 /*
2 * Copyright (c) 2002 Robert Collins.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * A copy of the GNU General Public License can be found at
10 * http://www.gnu.org/
12 * Written by Robert Collins <robertc@hotmail.com>
16 #include "PickView.h"
17 #include "PickPackageLine.h"
18 #include "PickCategoryLine.h"
19 #include <algorithm>
20 #include <limits.h>
21 #include <shlwapi.h>
23 #include "package_db.h"
24 #include "dialog.h"
25 #include "resource.h"
26 /* For 'source' */
27 #include "state.h"
28 #include "LogSingleton.h"
29 #include "Exception.h"
31 void
32 PickView::setViewMode (views mode)
34 view_mode = mode;
35 packagedb db;
37 size_t i;
38 for (i = 0; i < contents.size(); i++)
40 delete contents[i];
42 contents.clear();
44 if (view_mode == PickView::views::Category)
46 insert_category (cat_tree_root);
48 else
50 // iterate through every package
51 for (packagedb::packagecollection::iterator i = db.packages.begin ();
52 i != db.packages.end (); ++i)
54 packagemeta & pkg = *(i->second);
56 if (!pkg.isBinary())
57 continue;
59 if ( // "Full" : everything
60 (view_mode == PickView::views::PackageFull)
62 // "Pending" : packages that are being added/removed/upgraded
63 || (view_mode == PickView::views::PackagePending &&
64 ((!pkg.desired && pkg.installed) || // uninstall
65 (pkg.desired &&
66 (pkg.picked () || // install bin
67 pkg.srcpicked ())))) // src
69 // "Up to date" : installed packages that will not be changed
70 || (view_mode == PickView::views::PackageKeeps &&
71 (pkg.installed && pkg.desired && !pkg.picked ()
72 && !pkg.srcpicked ()))
74 // "Not installed"
75 || (view_mode == PickView::views::PackageSkips &&
76 (!pkg.desired && !pkg.installed))
78 // "UserPick" : installed packages that were picked by user
79 || (view_mode == PickView::views::PackageUserPicked &&
80 (pkg.installed && pkg.user_picked)))
82 // Filter by package name
83 if (packageFilterString.empty ()
84 || StrStrI (pkg.name.c_str (), packageFilterString.c_str ()))
85 insert_pkg (pkg);
90 listview->setContents(&contents, view_mode == PickView::views::Category);
93 PickView::views
94 PickView::getViewMode ()
96 return view_mode;
99 unsigned int
100 PickView::mode_caption (views mode)
102 switch (mode)
104 case views::PackageFull:
105 return IDS_VIEW_FULL;
106 case views::PackagePending:
107 return IDS_VIEW_PENDING;
108 case views::PackageKeeps:
109 return IDS_VIEW_UPTODATE;
110 case views::PackageSkips:
111 return IDS_VIEW_NOTINSTALLED;
112 case views::PackageUserPicked:
113 return IDS_VIEW_PICKED;
114 case views::Category:
115 return IDS_VIEW_CATEGORY;
116 default:
117 return 0;
121 /* meant to be called on packagemeta::categories */
122 bool
123 isObsolete (std::set <std::string, casecompare_lt_op> &categories)
125 std::set <std::string, casecompare_lt_op>::const_iterator i;
127 for (i = categories.begin (); i != categories.end (); ++i)
128 if (isObsolete (*i))
129 return true;
130 return false;
133 bool
134 isObsolete (const std::string& catname)
136 if (casecompare(catname, "ZZZRemovedPackages") == 0
137 || casecompare(catname, "_", 1) == 0)
138 return true;
139 return false;
142 /* Sets the mode for showing/hiding obsolete junk packages. */
143 void
144 PickView::setObsolete (bool doit)
146 showObsolete = doit;
147 refresh ();
150 void
151 PickView::insert_pkg (packagemeta & pkg, int indent)
153 if (!showObsolete && isObsolete (pkg.categories))
154 return;
156 contents.push_back(new PickPackageLine(*this, pkg, indent));
159 void
160 PickView::insert_category (CategoryTree *cat_tree)
162 if (!cat_tree)
163 return;
165 const Category *cat = &(cat_tree->category());
167 // Suppress obsolete category when not showing obsolete
168 if ((!showObsolete && isObsolete (cat->first)))
169 return;
171 // if it's not the "All" category
172 int packageCount = 0;
173 bool hasContents = false;
174 bool isAll = casecompare(cat->first, "All") == 0;
175 if (!isAll)
177 // count the number of packages in this category
178 for (std::vector <packagemeta *>::const_iterator i = cat->second.begin ();
179 i != cat->second.end () ; ++i)
181 if (packageFilterString.empty () \
182 || (*i
183 && StrStrI ((*i)->name.c_str (), packageFilterString.c_str ())))
185 packageCount++;
189 // if there are some packages in the category, or we are showing everything,
190 if (packageFilterString.empty () || packageCount)
192 hasContents = true;
196 if (!isAll && !hasContents)
197 return;
199 // insert line for the category
200 contents.push_back(new PickCategoryLine(*this, cat_tree, packageCount, isAll ? 0 : 1));
202 // if not collapsed
203 if (!cat_tree->collapsed())
205 // insert lines for the packages in this category
206 if (!isAll)
208 for (std::vector <packagemeta *>::const_iterator i = cat->second.begin ();
209 i != cat->second.end () ; ++i)
211 if (packageFilterString.empty () \
212 || (*i
213 && StrStrI ((*i)->name.c_str (), packageFilterString.c_str ())))
215 insert_pkg(**i, 2);
220 // recurse for contained categories
221 for (std::vector <CategoryTree *>::iterator i = cat_tree->bucket().begin ();
222 i != cat_tree->bucket().end();
223 i++)
225 insert_category(*i);
230 /* this means to make the 'category' column wide enough to fit the first 'n'
231 categories for each package. */
232 #define NUM_CATEGORY_COL_WIDTH 2
234 void
235 PickView::init_headers (void)
237 listview->noteColumnWidthStart();
239 // width of the 'src' checkbox column just needs to accommodate the
240 // column name
241 listview->noteColumnWidth (srctick_col, std::string(""));
243 // (In category view) accommodate the width of each category name
244 packagedb db;
245 for (packagedb::categoriesType::iterator n = packagedb::categories.begin();
246 n != packagedb::categories.end(); ++n)
248 listview->noteColumnWidth (cat_col, n->first);
251 /* For each package, accomodate the width of the installed version in the
252 current_col, the widths of all other versions in the new_col, and the width
253 of the sdesc for the pkg_col and the first NUM_CATEGORY_COL_WIDTH
254 categories in the category column. */
255 for (packagedb::packagecollection::iterator n = db.packages.begin ();
256 n != db.packages.end (); ++n)
258 packagemeta & pkg = *(n->second);
259 if (pkg.installed)
260 listview->noteColumnWidth (current_col, pkg.installed.Canonical_version ());
261 for (std::set<packageversion>::iterator i = pkg.versions.begin ();
262 i != pkg.versions.end (); ++i)
264 if (*i != pkg.installed)
265 listview->noteColumnWidth (new_col, i->Canonical_version ());
266 std::string z = format_1000s(i->source ()->size);
267 listview->noteColumnWidth (size_col, z);
268 z = format_1000s(i->sourcePackage ().source ()->size);
269 listview->noteColumnWidth (size_col, z);
271 std::string s = pkg.name;
272 listview->noteColumnWidth (pkgname_col, s);
274 s = pkg.SDesc ();
275 listview->noteColumnWidth (pkg_col, s);
277 if (pkg.categories.size () > 2)
279 std::string compound_cat("");
280 std::set<std::string, casecompare_lt_op>::const_iterator cat;
281 size_t cnt;
283 for (cnt = 0, cat = pkg.categories.begin ();
284 cnt < NUM_CATEGORY_COL_WIDTH && cat != pkg.categories.end ();
285 ++cat)
287 if (casecompare(*cat, "All") == 0)
288 continue;
289 if (compound_cat.size ())
290 compound_cat += ", ";
291 compound_cat += *cat;
292 cnt++;
294 listview->noteColumnWidth (cat_col, compound_cat);
298 // also ensure that new_col is wide enough for all the action labels
299 unsigned int captions[] = {
300 IDS_ACTION_UNINSTALL, IDS_ACTION_SKIP, IDS_ACTION_REINSTALL,
301 IDS_ACTION_RETRIEVE, IDS_ACTION_SOURCE, IDS_ACTION_KEEP,
302 IDS_ACTION_UNKNOWN, 0
304 for (int i = 0; captions[i]; i++)
305 listview->noteColumnWidth (new_col, LoadStringW(captions[i]));
307 listview->noteColumnWidthEnd();
308 listview->resizeColumns();
311 PickView::PickView() :
312 deftrust (TRUST_UNKNOWN),
313 showObsolete (false),
314 packageFilterString (),
315 cat_tree_root (NULL)
319 void
320 PickView::init(views _mode, ListView *_listview, Window *_parent)
322 view_mode = _mode;
323 listview = _listview;
324 parent = _parent;
327 void
328 PickView::build_category_tree()
330 /* Build the category tree */
332 /* Start collapsed. TODO: make that a flag */
333 bool collapsed = true;
335 /* Dispose of any existing category tree */
336 if (cat_tree_root)
338 for (std::vector <CategoryTree *>::const_iterator i = cat_tree_root->bucket().begin();
339 i != cat_tree_root->bucket().end();
340 i++)
341 delete *i;
343 delete cat_tree_root;
344 cat_tree_root = NULL;
347 /* Find the 'All' category */
348 for (packagedb::categoriesType::iterator n =
349 packagedb::categories.begin(); n != packagedb::categories.end();
350 ++n)
352 if (casecompare(n->first, "All") == 0)
354 cat_tree_root = new CategoryTree(*n, collapsed);
355 break;
359 /* Add all the other categories as children */
360 for (packagedb::categoriesType::iterator n =
361 packagedb::categories.begin(); n != packagedb::categories.end();
362 ++n)
364 if (casecompare(n->first, "All") == 0)
365 continue;
367 CategoryTree *cat_tree = new CategoryTree(*n, collapsed);
368 cat_tree_root->bucket().push_back(cat_tree);
371 refresh ();
374 PickView::~PickView()
378 void
379 PickView::defaultTrust (trusts trust)
381 this->deftrust = trust;
384 void
385 PickView::refresh()
387 setViewMode (view_mode);