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
34namespace 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 */
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
116void
117MultiInterfaceChooserDialog::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 */
127const MultiInterfaceChooserDialog::Record &
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 */
144int
146{
147 treeview_.append_column("Load", record().load);
148
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 */
170void
171MultiInterfaceChooserDialog::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
The BlackBoard abstract class.
Definition: blackboard.h:46
Blackboard interface chooser dialog.
virtual int init_columns()
Initializes the columns GUI-wise.
Gtk::TreeView treeview_
Tree widget for interfaces.
void init(BlackBoard *blackboard, const char *type_pattern, const char *id_pattern)
Initialization method.
virtual void init_row(Gtk::TreeModel::Row &row, const InterfaceInfo &ii)
Initializes a row with the given interface.
Glib::RefPtr< Gtk::ListStore > model_
Data model of the tree.
Interface info.
const char * type() const
Get interface type.
const char * id() const
Get interface ID.
Gtk::TreeModelColumn< bool > load
Load this interface?
Blackboard interface chooser dialog that supports multiple choices.
virtual int init_columns()
Initializes the columns GUI-wise.
std::list< TypeIdPair > TypeIdPairList
List of type and ID of an interface.
TypeIdPairList get_selected_interfaces() const
Get selected interface types and their respective IDs.
TypeIdPairList get_newly_selected_interfaces() const
Get selected interface types and their respective IDs.
virtual const Record & record() const
Returns the Record of this chooser dialog.
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.
virtual void init_row(Gtk::TreeModel::Row &row, const InterfaceInfo &ii)
Initializes a row with the given interface.
std::pair< Glib::ustring, Glib::ustring > TypeIdPair
Pair of type and IDs of interfaces.
MultiInterfaceChooserDialog(Gtk::Window &parent, const TypeIdPairList &loaded_interfaces, const Glib::ustring &title)
Constructor for subclasses.
Fawkes library namespace.