Fawkes API  Fawkes Development Version
multi_interface_chooser_dialog.cpp
1 /***************************************************************************
2  * multi_interface_chooser_dialog.cpp - Dialog for choosing a blackboard interface
3  *
4  * Created: Mon Oct 17 21:01:30 2011
5  * Copyright 2011 Christoph Schwering
6  *
7  ****************************************************************************/
8 
9 /* This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version. A runtime exception applies to
13  * this software (see LICENSE.GPL_WRE file mentioned below for details).
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU Library General Public License for more details.
19  *
20  * Read the full text in the LICENSE.GPL_WRE file in the doc directory.
21  */
22 
23 #include <blackboard/blackboard.h>
24 #include <core/exception.h>
25 #include <core/exceptions/software.h>
26 #include <gui_utils/multi_interface_chooser_dialog.h>
27 #include <interface/interface_info.h>
28 
29 #include <algorithm>
30 #include <cassert>
31 #include <cstring>
32 #include <gtkmm.h>
33 
34 namespace fawkes {
35 
36 /** @class MultiInterfaceChooserDialog::Record <gui_utils/multi_interface_chooser_dialog.h>
37  * Blackboard interface record.
38  * Adds a checkbox whether or not to load the specific interface.
39  * @author Christoph Schwering
40  */
41 
42 /** Constructor. */
44 {
45  add(load);
46 }
47 
48 /** @class MultiInterfaceChooserDialog <gui_utils/multi_interface_chooser_dialog.h>
49  * Blackboard interface chooser dialog that supports multiple choices.
50  * Allows to choose multiple blackboard interfaces from a list of interfaces
51  * matching given type and ID patterns.
52  * @author Christoph Schwering
53  */
54 
55 /** Factory method.
56  *
57  * Why a factory method instead of a ctor?
58  * The factory method calls init(), and init() calls other virtual methods.
59  * If this was a ctor, this ctor would not be allowed to be called by
60  * subclasses, because then the virtual methods in init() don't dispatch the
61  * right way during construction (see Effective C++ #9).
62  *
63  * @param parent parent window
64  * @param blackboard blackboard instance to query interfaces from
65  * @param type_pattern pattern with shell like globs (* for any number of
66  * characters, ? for exactly one character) to match the interface type.
67  * @param id_pattern pattern with shell like globs (* for any number of
68  * characters, ? for exactly one character) to match the interface ID.
69  * @param loaded_interfaces list of interfaces which are already loaded
70  * @param title title of the dialog
71  * @return new MultiInterfaceChooserDialog
72  */
74 MultiInterfaceChooserDialog::create(Gtk::Window & parent,
75  BlackBoard * blackboard,
76  const char * type_pattern,
77  const char * id_pattern,
78  const TypeIdPairList &loaded_interfaces,
79  const Glib::ustring & title)
80 {
82  new MultiInterfaceChooserDialog(parent, loaded_interfaces, title);
83  d->init(blackboard, type_pattern, id_pattern);
84  return d;
85 }
86 
87 /** Constructor for subclasses.
88  *
89  * After calling this constructor, the init() method needs to be called.
90  *
91  * @param parent parent window
92  * @param loaded_interfaces list of interfaces which are already loaded
93  * @param title title of the dialog
94  */
96  const TypeIdPairList &loaded_interfaces,
97  const Glib::ustring & title)
98 : InterfaceChooserDialog(parent, title), record_(NULL)
99 {
100  loaded_interfaces_.insert(loaded_interfaces.begin(), loaded_interfaces.end());
101  Glib::RefPtr<Gtk::TreeSelection> treesel = treeview_.get_selection();
102  treeview_.set_reorderable(true);
103  treeview_.set_tooltip_text("Drag the rows to change the painting order.");
104  treesel->set_mode(Gtk::SELECTION_NONE);
105  // May *NOT* call init(), because init() calls virtual methods.
106 }
107 
108 /** Destructor. */
110 {
111  if (record_) {
112  delete record_;
113  }
114 }
115 
116 void
117 MultiInterfaceChooserDialog::on_load_toggled(const Glib::ustring &path)
118 {
119  Gtk::TreeModel::Row row = *model_->get_iter(path);
120  row[record().load] = !row[record().load];
121 }
122 
123 /** Returns the Record of this chooser dialog.
124  * Subclasses of InterfaceChooserDialog might want to override this method.
125  * @return Record implementation.
126  */
129 {
130  if (!record_) {
131  MultiInterfaceChooserDialog *this_nonconst = const_cast<MultiInterfaceChooserDialog *>(this);
132  this_nonconst->record_ = new Record();
133  }
134  return *record_;
135 }
136 
137 /** Initializes the columns GUI-wise.
138  * Called in the ctor.
139  * Subclasses of InterfaceChooserDialog might want to override this method,
140  * but should probably still call their super-class's implementation
141  * (i.e., this one).
142  * @return The number of columns added.
143  */
144 int
146 {
147  treeview_.append_column("Load", record().load);
148 
149  const int n = InterfaceChooserDialog::init_columns();
150 
151  Gtk::CellRendererToggle *renderer =
152  dynamic_cast<Gtk::CellRendererToggle *>(treeview_.get_column_cell_renderer(0));
153  assert(renderer != NULL);
154 
155  renderer->set_activatable(true);
156  renderer->signal_toggled().connect(
157  sigc::mem_fun(*this, &MultiInterfaceChooserDialog::on_load_toggled));
158 
159  return n + 2;
160 }
161 
162 /** Initializes a row with the given interface.
163  * Called in the ctor.
164  * Subclasses of InterfaceChooserDialog might want to override this method,
165  * but should probably still call their super-class's implementation
166  * (i.e., this one).
167  * @param row The row whose content is to be set.
168  * @param ii The interface info that should populate the row.
169  */
170 void
171 MultiInterfaceChooserDialog::init_row(Gtk::TreeModel::Row &row, const InterfaceInfo &ii)
172 {
174  row[record().load] =
175  loaded_interfaces_.find(std::make_pair(ii.type(), ii.id())) != loaded_interfaces_.end();
176 }
177 
178 /** Get selected interface types and their respective IDs.
179  * @return A list of type + id pairs of interfaces that are to be loaded.
180  */
183 {
184  TypeIdPairList types_and_ids;
185 
186  const Gtk::TreeNodeChildren children = model_->children();
187  for (Gtk::TreeNodeChildren::const_iterator it = children.begin(); it != children.end(); ++it) {
188  const Gtk::TreeRow &row = *it;
189  if (row[record().load]) {
190  TypeIdPair pair = std::make_pair(row[record().type], row[record().id]);
191  types_and_ids.push_back(pair);
192  }
193  }
194 
195  return types_and_ids;
196 }
197 
198 /** Get selected interface types and their respective IDs.
199  * @return A list of type + id pairs of interfaces that are to be loaded,
200  * and *NOT* contained in the list of loaded interfaces handed
201  * over to create().
202  */
205 {
206  TypeIdPairList types_and_ids;
207 
208  const Gtk::TreeNodeChildren children = model_->children();
209  for (Gtk::TreeNodeChildren::const_iterator it = children.begin(); it != children.end(); ++it) {
210  const Gtk::TreeRow &row = *it;
211  if (row[record().load]) {
212  TypeIdPair pair = std::make_pair(row[record().type], row[record().id]);
213  if (loaded_interfaces_.find(pair) == loaded_interfaces_.end()) {
214  types_and_ids.push_back(pair);
215  }
216  }
217  }
218 
219  return types_and_ids;
220 }
221 
222 } // end of namespace fawkes
fawkes::InterfaceChooserDialog::init_row
virtual void init_row(Gtk::TreeModel::Row &row, const InterfaceInfo &ii)
Initializes a row with the given interface.
Definition: interface_chooser_dialog.cpp:208
fawkes::MultiInterfaceChooserDialog::create
static MultiInterfaceChooserDialog * create(Gtk::Window &parent, BlackBoard *blackboard, const char *type_pattern, const char *id_pattern, const TypeIdPairList &loaded_interfaces, const Glib::ustring &title=DEFAULT_TITLE)
Factory method.
Definition: multi_interface_chooser_dialog.cpp:80
fawkes::MultiInterfaceChooserDialog::get_selected_interfaces
TypeIdPairList get_selected_interfaces() const
Get selected interface types and their respective IDs.
Definition: multi_interface_chooser_dialog.cpp:188
fawkes::MultiInterfaceChooserDialog::TypeIdPair
std::pair< Glib::ustring, Glib::ustring > TypeIdPair
Pair of type and IDs of interfaces.
Definition: multi_interface_chooser_dialog.h:50
fawkes::MultiInterfaceChooserDialog::Record::Record
Record()
Constructor.
Definition: multi_interface_chooser_dialog.cpp:49
fawkes::InterfaceChooserDialog::init
void init(BlackBoard *blackboard, const char *type_pattern, const char *id_pattern)
Initialization method.
Definition: interface_chooser_dialog.cpp:124
fawkes::MultiInterfaceChooserDialog::TypeIdPairList
std::list< TypeIdPair > TypeIdPairList
List of type and ID of an interface.
Definition: multi_interface_chooser_dialog.h:52
fawkes::BlackBoard
Definition: blackboard.h:50
fawkes::InterfaceChooserDialog::init_columns
virtual int init_columns()
Initializes the columns GUI-wise.
Definition: interface_chooser_dialog.cpp:190
fawkes::InterfaceInfo::id
const char * id() const
Get interface ID.
Definition: interface_info.cpp:145
fawkes
fawkes::InterfaceChooserDialog
Definition: interface_chooser_dialog.h:47
fawkes::MultiInterfaceChooserDialog::init_columns
virtual int init_columns()
Initializes the columns GUI-wise.
Definition: multi_interface_chooser_dialog.cpp:151
fawkes::MultiInterfaceChooserDialog::~MultiInterfaceChooserDialog
virtual ~MultiInterfaceChooserDialog()
Destructor.
Definition: multi_interface_chooser_dialog.cpp:115
fawkes::InterfaceChooserDialog::treeview_
Gtk::TreeView treeview_
Tree widget for interfaces.
Definition: interface_chooser_dialog.h:84
fawkes::MultiInterfaceChooserDialog::record
virtual const Record & record() const
Returns the Record of this chooser dialog.
Definition: multi_interface_chooser_dialog.cpp:134
fawkes::InterfaceChooserDialog::model_
Glib::RefPtr< Gtk::ListStore > model_
Data model of the tree.
Definition: interface_chooser_dialog.h:85
fawkes::MultiInterfaceChooserDialog
Definition: multi_interface_chooser_dialog.h:40
fawkes::MultiInterfaceChooserDialog::init_row
virtual void init_row(Gtk::TreeModel::Row &row, const InterfaceInfo &ii)
Initializes a row with the given interface.
Definition: multi_interface_chooser_dialog.cpp:177
fawkes::MultiInterfaceChooserDialog::Record::load
Gtk::TreeModelColumn< bool > load
Load this interface?
Definition: multi_interface_chooser_dialog.h:71
fawkes::MultiInterfaceChooserDialog::MultiInterfaceChooserDialog
MultiInterfaceChooserDialog(Gtk::Window &parent, const TypeIdPairList &loaded_interfaces, const Glib::ustring &title)
Constructor for subclasses.
Definition: multi_interface_chooser_dialog.cpp:101
fawkes::InterfaceInfo::type
const char * type() const
Get interface type.
Definition: interface_info.cpp:136
fawkes::InterfaceInfo
Definition: interface_info.h:40
fawkes::MultiInterfaceChooserDialog::Record
Definition: multi_interface_chooser_dialog.h:67
fawkes::MultiInterfaceChooserDialog::get_newly_selected_interfaces
TypeIdPairList get_newly_selected_interfaces() const
Get selected interface types and their respective IDs.
Definition: multi_interface_chooser_dialog.cpp:210