2 Copyright (C) 2012 Carl Hetherington <cth@carlh.net>
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 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 /** @file src/job_manager_view.cc
21 * @brief Class generating a GTK widget to show the progress of jobs.
24 #include "lib/job_manager.h"
27 #include "lib/exceptions.h"
28 #include "job_manager_view.h"
32 using namespace boost;
34 /** Must be called in the GUI thread */
35 JobManagerView::JobManagerView ()
37 _scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_ALWAYS);
39 _store = Gtk::TreeStore::create (_columns);
40 _view.set_model (_store);
41 _view.append_column ("Name", _columns.name);
43 Gtk::CellRendererProgress* r = Gtk::manage (new Gtk::CellRendererProgress ());
44 int const n = _view.append_column ("Progress", *r);
45 Gtk::TreeViewColumn* c = _view.get_column (n - 1);
46 c->add_attribute (r->property_value(), _columns.progress);
47 c->add_attribute (r->property_pulse(), _columns.progress_unknown);
48 c->add_attribute (r->property_text(), _columns.text);
50 _scroller.add (_view);
51 _scroller.set_size_request (-1, 150);
56 /** Update the view by examining the state of each jobs.
57 * Must be called in the GUI thread.
60 JobManagerView::update ()
62 list<shared_ptr<Job> > jobs = JobManager::instance()->get ();
64 for (list<shared_ptr<Job> >::iterator i = jobs.begin(); i != jobs.end(); ++i) {
65 Gtk::ListStore::iterator j = _store->children().begin();
66 while (j != _store->children().end()) {
68 shared_ptr<Job> job = r[_columns.job];
76 if (j == _store->children().end ()) {
77 j = _store->append ();
79 r[_columns.name] = (*i)->name ();
81 r[_columns.progress_unknown] = -1;
82 r[_columns.informed_of_finish] = false;
87 bool inform_of_finish = false;
88 string const st = (*i)->status ();
90 if (!(*i)->finished ()) {
91 float const p = (*i)->overall_progress ();
93 r[_columns.text] = st;
94 r[_columns.progress] = p * 100;
96 r[_columns.progress_unknown] = r[_columns.progress_unknown] + 1;
100 /* Hack to work around our lack of cross-thread
101 signalling; we tell the job to emit_finished()
102 from here (the GUI thread).
105 if ((*i)->finished_ok ()) {
106 bool i = r[_columns.informed_of_finish];
108 r[_columns.progress_unknown] = -1;
109 r[_columns.progress] = 100;
110 r[_columns.text] = st;
111 inform_of_finish = true;
113 } else if ((*i)->finished_in_error ()) {
114 bool i = r[_columns.informed_of_finish];
116 r[_columns.progress_unknown] = -1;
117 r[_columns.progress] = 100;
118 r[_columns.text] = st;
119 inform_of_finish = true;
123 if (inform_of_finish) {
125 (*i)->emit_finished ();
126 } catch (OpenFileError& e) {
128 s << "Error: " << e.what();
129 error_dialog (s.str ());
131 r[_columns.informed_of_finish] = true;