1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
|
// dashboardtab.h -*-c++-*-
//
// Copyright (C) 2008-2009 Obey Arthur Liu
// Copyright (C) 2008 Daniel Burrows
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; see the file COPYING. If not, write to
// the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
// Boston, MA 02111-1307, USA.
#ifndef DASHBOARD_TAB_H
#define DASHBOARD_TAB_H
#include <cwidget/generic/util/ref_ptr.h>
#include <gtkmm.h>
#include "tab.h"
/** \file dashboardtab.h */
namespace aptitude
{
namespace matching
{
class pattern;
};
}
#include <generic/apt/aptitude_resolver_universe.h>
#include <generic/problemresolver/solution.h>
class resolver_manager;
namespace gui
{
class PkgView;
class PackageSearchEntry;
class ResolverTab;
/** \brief The main dashboard tab. */
class DashboardTab : public Tab
{
// The internal resolver that we use to calculate an upgrade
// solution. By convention, this is set to NULL if there's no
// upgrade to calculate. Note that although this handles
// restarting the resolver when a package's state changes, we must
// actually discard and recreate it ourselves as well: e.g., if a
// "hold" state changes, that can affect the upgrade calculation.
resolver_manager *upgrade_resolver;
// Collects code that keeps track of the "fixing upgrade" state.
class fixing_upgrade_info
{
// A separate internal resolver that's used if the user asks to
// fix the initial solution manually. The first upgrade
// solution that was produced is used for the initial state of
// this resolver. This manager is set to NULL until (1) an
// upgrade solution is produced AND (2) there is a "fixing
// upgrade" tab.
resolver_manager *fixing_upgrade_resolver;
// The "fixing upgrade" tab, if one exists; otherwise NULL.
ResolverTab *fixing_upgrade_tab;
/** \brief Invoked when the tab is closed. */
void handle_fixing_upgrade_tab_closed();
/** \brief Initialize the internal resolver manager from the
* given solution.
*
* If there is a fixing upgrade tab, notifies it of the new
* manager.
*/
void create_resolver(const generic_solution<aptitude_universe> &sol);
public:
fixing_upgrade_info();
// Discards the resolver and NULLs it out in the tab if there is
// one.
~fixing_upgrade_info();
/** \brief Throw away the resolver and NULL it out in the tab.
*
* Use this to get rid of the resolver after a cache reload,
* for instance.
*/
void discard_resolver();
/** \brief Pulse the progress bar on the "fixing upgrade" tab,
* if there is one.
*/
void pulse();
/** \brief Tell the "fixing upgrade" tab, if there is one, that
* the given solution was found.
*
* If there is a tab, creates a new resolver manager and hands
* it off to the tab.
*
* \param sol The solution that was calculated, or an invalid
* solution if the resolver failed.
*/
void solution_calculated(const generic_solution<aptitude_universe> &sol);
/** \brief Show the "fixing upgrade" tab and populate it with
* the given solution.
*
* Like solution_calculated(), but creates the tab if it
* doesn't exist.
*
* \param sol The solution that was calculated, or an invalid
* solution if the resolver failed.
*/
void show_fixing_upgrade(const generic_solution<aptitude_universe> &sol);
};
fixing_upgrade_info fixing_upgrade;
// The internal resolver solution that we use to calculate an
// upgrade solution. If this is invalid, the solution hasn't been
// calculated yet.
generic_solution<aptitude_universe> upgrade_solution;
// The timeout connection that's used to pulse the progress bar
// while we're calculating the upgrade.
sigc::connection pulse_progress_connection;
// An internal object that serves as the connection point for
// slots from the background thread. The only reason for this to
// exist is so that we can easily disconnect all those slots at
// once (by deleting it) and avoid "stale" events from a previous
// resolver run.
class redirect_from_background : public sigc::trackable
{
DashboardTab &parent;
public:
redirect_from_background(DashboardTab &_parent)
: parent(_parent)
{
}
void success(generic_solution<aptitude_universe> sol)
{
parent.upgrade_resolver_success(sol);
}
void no_more_solutions()
{
parent.upgrade_resolver_no_more_solutions();
}
void aborted(std::string errmsg)
{
parent.upgrade_resolver_aborted(errmsg);
}
};
redirect_from_background *background_upgrade_redirect;
cwidget::util::ref_ptr<PkgView> upgrades_pkg_view;
Gtk::TextView *upgrades_changelog_view;
Gtk::TextView *upgrades_summary_textview;
cwidget::util::ref_ptr<PackageSearchEntry> package_search_entry;
Gtk::ProgressBar *upgrade_resolver_progress;
Gtk::Label *upgrade_resolver_label;
Gtk::Button *fix_manually_button;
Gtk::Button *upgrade_button;
Gtk::Label *available_upgrades_label;
// Maps each version displayed in the upgrade list to the location
// of its changelog in the changelog text view.
std::map<pkgCache::VerIterator, Glib::RefPtr<Gtk::TextBuffer::Mark> > changelog_locations;
void do_search();
void do_upgrade();
void do_fix_manually();
// Download all the changelogs and show the new entries.
void create_upgrade_summary();
void handle_cache_closed();
void handle_cache_reloaded();
void handle_upgrades_store_reloaded();
void activated_upgrade_package_handler();
bool pulse_progress_timeout();
// NB: the resolver callbacks pass their argument by value to
// avoid any possible confusion about whether they could refer to
// a destroyed object.
/** \brief Invoked in the foreground when the background thread
* computes an upgrade solution.
*
* \param sol The solution that was calculated, or an invalid
* solution to indicate that nothing needs to be
* calculated.
*
* Hides the progress bar, shows the label, and activates the
* button; changes the label text to suggest to the user that
* they can press the button to install the upgrades that are
* available.
*/
void upgrade_resolver_success(generic_solution<aptitude_universe> sol);
/** \brief Invoked in the foreground when the background thread
* can't find an upgrade solution.
*
* Hides the progress bar, shows the label, deactivates the
* button, and informs the user that it was unable to find an
* upgrade solution.
*/
void upgrade_resolver_no_more_solutions();
/** \brief Invoked in the foreground when the background thread
* is aborted (by an exception) while searching for an upgrade solution.
*/
void upgrade_resolver_aborted(std::string errmsg);
class upgrade_continuation;
/** \brief Create the internal resolver if it doesn't exist and
* start its calculation.
*
* Shows the progress bar and hides the label; makes the button
* inactive and kicks off a timer to pulse the progress bar.
*/
void make_resolver();
/** \brief Throw away the internal resolver and solution, and hide
* the progress bar and label.
*/
void discard_resolver();
public:
DashboardTab(Glib::ustring label);
~DashboardTab();
bool get_edit_columns_available();
void dispatch_edit_columns();
};
}
#endif // DASHBOARD_TAB_H
|