1
#include "listmodel_wrapper.h"
2
#include "gtk_helpers.h"
3
#include <gtkmm/cellrenderercombo.h>
4
#include <gtkmm/icontheme.h>
5
#include "custom_renderers.h"
6
#include "grt/common.h"
12
#define lmwdprint(...) fprintf(stderr, __VA_ARGS__)
14
#define lmwdprint(...)
18
static void process_menu_actions(const std::string &command
19
, bec::ListModel* model
20
, const std::vector<bec::NodeId>& nodes
21
, const sigc::slot<void, const std::string&, const std::vector<bec::NodeId>&> fe_menu_handler
24
if (!model->activate_popup_item_for_nodes(command, nodes) && !fe_menu_handler.empty())
25
fe_menu_handler(command, nodes);
28
//------------------------------------------------------------------------------
29
static void run_menu_and_forward_action(const bec::MenuItemList& items
33
,bec::ListModel* model
34
,const std::vector<bec::NodeId>& nodes
35
,const sigc::slot<void, const std::string&, const std::vector<bec::NodeId>&> fe_menu_handler
42
,sigc::bind(sigc::ptr_fun(process_menu_actions), model, nodes, fe_menu_handler)
49
Index::ExternalMap Index::_ext_map;
51
//------------------------------------------------------------------------------
52
Index::Index(GtkTreeIter* it, const bec::NodeId& node)
53
: _raw_data((char *)it)
56
//memset(_raw_data, 0xff, sizeof(*it));
60
const int depth = node.depth();
62
const Mode m = (depth < MaxDepth) ? (depth == 1 ? ListNode : Internal) : External;
67
const std::string nrepr = node.repr();
68
std::pair<ExternalMap::iterator, bool> res = _ext_map.insert(nrepr);
69
_ext = const_cast<std::string*>(&(*(res.first)));
70
it->user_data = (void*)_ext;
72
else if (m == Internal)
74
for (int i = 0; i < depth; ++i)
77
else if (m == ListNode)
79
it->user_data = (void*)(node[0]);
83
//------------------------------------------------------------------------------
84
Index::Index(const GtkTreeIter* it)
85
: _raw_data((char *)it)
88
if (mode() == External)
89
_ext = reinterpret_cast<std::string*>(((GtkTreeIter*)_raw_data)->user_data);
92
//------------------------------------------------------------------------------
93
void Index::stamp(const int st)
95
((Info*)_raw_data)->stamp = st % StampMax;
98
//------------------------------------------------------------------------------
99
int Index::stamp() const
101
return ((Info*)_raw_data)->stamp;
104
//------------------------------------------------------------------------------
105
bool Index::cmp_stamp(const int st) const
107
return ((Info*)_raw_data)->stamp == (st % StampMax);
110
//------------------------------------------------------------------------------
111
int Index::word(const int w) const
115
if (mode() == Internal)
117
char* dest = (char*)&ret;
118
const int start_byte = (w * K) + 1;
120
memcpy(dest, _raw_data + start_byte, K);
126
//------------------------------------------------------------------------------
127
void Index::word(const int w, const int v)
129
if (mode() == Internal)
131
int start_byte = (w * K) + 1;
132
char* dest = _raw_data + start_byte;
133
char* src = (char*)&v;
135
memcpy(dest, src, K);
139
throw std::logic_error("Can't change external Node ref\n");
143
//------------------------------------------------------------------------------
144
bec::NodeId Index::to_node() const
147
if (mode() == Internal)
150
char* dst = (char*)&v;
151
char* src = _raw_data + 1;
153
for (int i = 0; i < MaxDepth; ++i)
164
else if (mode() == External)
167
node = bec::NodeId(*_ext);
169
else if (mode() == ListNode)
170
node.append((long)(((GtkTreeIter*)_raw_data)->user_data));
175
//------------------------------------------------------------------------------
176
void Index::reset_iter(GtkTreeIter* it)
178
memset(it, 0xff, sizeof(*it));
184
//------------------------------------------------------------------------------
185
Gtk::TreeModel::Path node2path(const ::bec::NodeId& node)
187
const int depth = node.depth();
188
Gtk::TreeModel::Path path;
190
for ( int i = 0; i < depth; i++ )
191
path.append_index(node[i]);
196
//------------------------------------------------------------------------------
197
ColumnsModel::~ColumnsModel()
199
reset(true); // true means clean up only self, and do not touch tree view
202
//------------------------------------------------------------------------------
203
void ColumnsModel::reset(const bool cleanup_only_self)
205
if (!cleanup_only_self)
206
_treeview->remove_all_columns();
208
std::list<Gtk::TreeModelColumnBase*>::iterator it = _columns.begin();
209
std::list<Gtk::TreeModelColumnBase*>::const_iterator last = _columns.end();
211
for ( ; last != it; ++it )
217
//------------------------------------------------------------------------------
218
void ColumnsModel::add_bec_index_mapping(const int bec_tm_index)
220
_ui2bec.push_back(bec_tm_index);
223
//------------------------------------------------------------------------------
224
int ColumnsModel::ui2bec(const int index_of_ui_column) const
226
g_assert((size_t)index_of_ui_column < _ui2bec.size());
228
return _ui2bec[index_of_ui_column];
231
//------------------------------------------------------------------------------
233
ColumnsModel::set_text_column(const int bec_tm_idx
239
// add mapping from ui to bec
240
// add them with add() to the model
241
// add columns to the IconView
242
// check if editable and bind signals
244
Gtk::TreeModelColumn<Glib::ustring> *text = new Gtk::TreeModelColumn<Glib::ustring>;
245
Gtk::TreeModelColumn<Glib::RefPtr<Gdk::Pixbuf> > *icon = new Gtk::TreeModelColumn<Glib::RefPtr<Gdk::Pixbuf> >;
247
_columns.push_back(text);
248
_columns.push_back(icon);
250
add_bec_index_mapping(bec_tm_idx);
251
add_bec_index_mapping(bec_tm_idx);
256
iv->set_text_column(*text);
257
iv->set_pixbuf_column(*icon);
263
//------------------------------------------------------------------------------
264
void ColumnsModel::add_tooltip_column(int bec_tm_idx)
266
Gtk::TreeModelColumn<Glib::ustring> *col = new Gtk::TreeModelColumn<Glib::ustring>;
268
add_bec_index_mapping(-bec_tm_idx); // negative means pick description
270
_columns.push_back(col);
273
//------------------------------------------------------------------------------
275
ColumnsModel::append_int_column(const int bec_tm_idx, const std::string& name, const Editable editable)
277
Gtk::TreeModelColumn<int> *col = new Gtk::TreeModelColumn<int>;
280
add_bec_index_mapping(bec_tm_idx);
283
if ( editable == EDITABLE )
285
nr_of_cols= _treeview->append_column_editable(bec::replace_string(name, "_", "__"), *col);
287
Gtk::CellRendererText *cell = (Gtk::CellRendererText*)(_treeview->get_column_cell_renderer(nr_of_cols - 1));
288
cell->signal_edited().connect(sigc::bind
290
,&ListModelWrapper::after_cell_edit<int>
297
nr_of_cols= _treeview->append_column(bec::replace_string(name, "_", "__"), *col);
299
_treeview->get_column(nr_of_cols-1)->set_resizable(true);
301
_columns.push_back(col);
306
//------------------------------------------------------------------------------
308
ColumnsModel::append_double_column(const int bec_tm_idx, const std::string& name, const Editable editable)
310
Gtk::TreeModelColumn<double> *col = new Gtk::TreeModelColumn<double>;
311
add_bec_index_mapping(bec_tm_idx);
314
_columns.push_back(col);
319
//------------------------------------------------------------------------------
321
ColumnsModel::append_string_column(const int bec_tm_idx, const std::string& name, const Editable editable, const Iconic have_icon)
323
Gtk::TreeModelColumn<Glib::RefPtr<Gdk::Pixbuf> > *icon= 0;
325
Gtk::TreeViewColumn *column= Gtk::manage(new Gtk::TreeViewColumn(bec::replace_string(name, "_", "__")));
327
if ( have_icon == WITH_ICON )
329
icon = new Gtk::TreeModelColumn<Glib::RefPtr<Gdk::Pixbuf> >;
331
add_bec_index_mapping(bec_tm_idx);
332
column->pack_start(*icon, false);
334
_columns.push_back(icon);
337
Gtk::TreeModelColumn<Glib::ustring> *col = new Gtk::TreeModelColumn<Glib::ustring>;
339
add_bec_index_mapping(bec_tm_idx);
340
column->pack_start(*col);
342
_columns.push_back(col);
344
int nr_of_cols= _treeview->append_column(*column);
345
_treeview->get_column(nr_of_cols-1)->set_resizable(true);
347
if (editable == EDITABLE)
349
std::vector<Gtk::CellRenderer*> rends= column->get_cell_renderers();
351
Gtk::CellRendererText *cell = (Gtk::CellRendererText*)rends[icon ? 1 : 0];
352
cell->property_editable()= true;
353
cell->signal_edited().connect(sigc::bind
355
,&ListModelWrapper::after_cell_edit<Glib::ustring>
365
//------------------------------------------------------------------------------
367
ColumnsModel::append_markup_column(const int bec_tm_idx, const std::string& name, const Iconic have_icon)
369
Gtk::TreeModelColumn<Glib::RefPtr<Gdk::Pixbuf> > *icon= 0;
371
Gtk::TreeViewColumn *column= Gtk::manage(new Gtk::TreeViewColumn(bec::replace_string(name, "_", "__")));
373
if ( have_icon == WITH_ICON )
375
icon = new Gtk::TreeModelColumn<Glib::RefPtr<Gdk::Pixbuf> >;
377
add_bec_index_mapping(bec_tm_idx);
378
column->pack_start(*icon, false);
380
_columns.push_back(icon);
383
Gtk::TreeModelColumn<Glib::ustring> *col = new Gtk::TreeModelColumn<Glib::ustring>;
384
Gtk::CellRendererText *cell = Gtk::manage(new Gtk::CellRendererText());
386
add_bec_index_mapping(bec_tm_idx);
387
column->pack_start(*cell);
388
column->add_attribute(cell->property_markup(), *col);
390
_columns.push_back(col);
392
int nr_of_cols= _treeview->append_column(*column);
393
_treeview->get_column(nr_of_cols-1)->set_resizable(true);
399
//------------------------------------------------------------------------------
401
ColumnsModel::append_combo_column(const int bec_tm_idx
402
,const std::string &name
403
,Glib::RefPtr<Gtk::ListStore> list_w
404
,const Editable editable
407
Gtk::TreeModelColumn<Glib::ustring> *choosen = new Gtk::TreeModelColumn<Glib::ustring>;
408
_columns.push_back(choosen);
410
add_bec_index_mapping(bec_tm_idx);
412
Gtk::TreeView::Column *col = Gtk::manage(new Gtk::TreeViewColumn(bec::replace_string(name, "_", "__")));
413
Gtk::CellRendererCombo *cell = Gtk::manage(new Gtk::CellRendererCombo);
414
col->pack_start(*cell);
416
col->add_attribute(cell->property_text(), *choosen);
417
cell->property_model() = list_w;
418
cell->property_text_column() = 0;
419
cell->property_editable() = editable;
420
cell->property_has_entry() = !popup_only;
422
Gtk::TreeModelColumn<Glib::RefPtr<Gtk::TreeModel> > *model_col = new Gtk::TreeModelColumn<Glib::RefPtr<Gtk::TreeModel> >();
423
add_bec_index_mapping(bec_tm_idx);
425
const int nr_of_cols = _treeview->append_column(*col);
427
_columns.push_back(model_col);
429
_treeview->get_column(nr_of_cols-1)->set_resizable(true);
431
if ( editable == EDITABLE )
433
Gtk::CellRendererText *cell = (Gtk::CellRendererText*)(_treeview->get_column_cell_renderer(nr_of_cols - 1));
434
cell->signal_edited().connect(sigc::bind
436
,&ListModelWrapper::after_cell_edit<Glib::ustring>
438
, sigc::ref(*choosen)
446
//------------------------------------------------------------------------------
448
ColumnsModel::append_check_column(const int bec_tm_idx
449
,const std::string &name
450
,const Editable editable
451
,const ToggleAction action
454
Gtk::TreeModelColumn<bool> *col = new Gtk::TreeModelColumn<bool>;
455
_columns.push_back(col);
457
add_bec_index_mapping(bec_tm_idx);
460
// If we have bec_tm_idx set to negative value it means that column added is not
461
// directly mapped to a model. Handling of values set/get are done through
462
// ListModelWrapper::_fake_column_value_getter/setter slot
463
if ( editable == EDITABLE )
465
nr_of_cols= _treeview->append_column_editable(bec::replace_string(name, "_", "__"), *col);
467
Gtk::CellRendererToggle *cell = (Gtk::CellRendererToggle*)(_treeview->get_column_cell_renderer(nr_of_cols - 1));
468
cell->property_activatable() = true;
469
if ( action == TOGGLE_BY_WRAPPER /* && bec_tm_idx >= 0 */)
471
cell->signal_toggled().connect(sigc::bind
473
,&ListModelWrapper::after_cell_toggle/*<bool>*/
481
nr_of_cols= _treeview->append_column(bec::replace_string(name, "_", "__"), *col);
483
_treeview->get_column(nr_of_cols-1)->set_resizable(true);
488
//------------------------------------------------------------------------------
490
int ColumnsModel::add_generic_column(const int bec_tm_idx, Gtk::TreeModelColumnBase *column,
491
Gtk::TreeViewColumn *vcolumn)
494
add_bec_index_mapping(bec_tm_idx);
496
return _treeview->append_column(*vcolumn);
499
//------------------------------------------------------------------------------
500
void ColumnsModel::add_model_column(Gtk::TreeModelColumnBase *col, int bec_tm_idx)
503
add_bec_index_mapping(bec_tm_idx);
504
_columns.push_back(col);
507
//------------------------------------------------------------------------------
508
//------------------------------------------------------------------------------
509
ListModelWrapper::ListModelWrapper(bec::ListModel* tm, Gtk::TreeView *treeview, const std::string& name)
510
: Glib::ObjectBase(typeid(ListModelWrapper))
514
, _treeview(treeview)
518
, _columns(this, treeview)
519
, _icon_size(bec::Icon16)
520
, _self_ref(new ListModelWrapper*(this))
523
scoped_connect(tm->tree_changed_signal(), boost::bind(&::ListModelWrapper::model_changed, this, _1, _2));
524
tm->add_destroy_notify_callback(_self_ref, &ListModelWrapper::on_bec_model_destroyed);
525
#ifndef NO_MENU_MANAGER
527
_treeview->signal_event().connect(sigc::mem_fun(this, &ListModelWrapper::handle_popup_event));
531
//------------------------------------------------------------------------------
532
void* ListModelWrapper::on_bec_model_destroyed(void* data)
534
ListModelWrapper** self = (ListModelWrapper**)data;
543
//------------------------------------------------------------------------------
544
ListModelWrapper::~ListModelWrapper()
546
delete _context_menu;
548
_tm->remove_destroy_notify_callback(_self_ref);
554
//------------------------------------------------------------------------------
555
void ListModelWrapper::set_iconview(Gtk::IconView* iv)
558
#ifndef NO_MENU_MANAGER
560
_iconview->signal_event().connect(sigc::mem_fun(this, &ListModelWrapper::handle_popup_event));
564
//------------------------------------------------------------------------------
565
ListModelWrapper::NodeIdArray ListModelWrapper::get_selection() const
568
std::vector<Gtk::TreePath> paths;
571
paths = _treeview->get_selection()->get_selected_rows();
573
paths = _iconview->get_selected_items();
575
const int size = paths.size();
577
for (int i = 0; i < size; ++i)
578
nodes.push_back(get_node_for_path(paths[i]));
583
//------------------------------------------------------------------------------
584
void ListModelWrapper::set_be_model(bec::ListModel* tm)
587
_tm->remove_destroy_notify_callback(_self_ref);
590
_tm->add_destroy_notify_callback(_self_ref, &ListModelWrapper::on_bec_model_destroyed);
593
#ifndef NO_MENU_MANAGER
594
//------------------------------------------------------------------------------
595
void ListModelWrapper::handle_popup(const int x, const int y, const int time, GdkEventButton* evb)
597
Gtk::TreeModel::Path path;
598
Gtk::TreeView::Column *column(0);
602
ListModelWrapper::NodeIdArray list = get_selection();
604
bool there_is_path_at_pos = false;
606
there_is_path_at_pos = _treeview->get_path_at_pos(x, y, path, column, cell_x, cell_y);
609
path = _iconview->get_path_at_pos(x, y);
610
there_is_path_at_pos = path.gobj() && !path.empty();
613
if ( !there_is_path_at_pos )
617
// Check that @path is on selection, otherwise add @path to selection
618
bec::NodeId node = get_node_for_path(path);
619
// list stores current selection
620
bool path_at_pos_is_in_selection = false;
621
for (int i = list.size() - 1; i >= 0; --i)
625
path_at_pos_is_in_selection = true;
630
if (!path_at_pos_is_in_selection)
632
// Add it, if user holds Ctrl while clicking right mouse btn
633
// Otherwise clear selection, and select only @path
634
const bool clear_selection = evb ? (!(evb->state & GDK_CONTROL_MASK)) : false;
638
_treeview->get_selection()->unselect_all();
640
_iconview->unselect_all();
644
_treeview->get_selection()->select(path);
646
_iconview->select_path(path);
648
list = get_selection();
652
_context_menu = new Gtk::Menu();
654
run_menu_and_forward_action(_tm->get_popup_items_for_nodes(list), x, y, time, _tm, list, _fe_menu_handler, _context_menu);
658
//------------------------------------------------------------------------------
659
bool ListModelWrapper::handle_popup_event(GdkEvent* event)
662
if ( event->type == GDK_BUTTON_PRESS && event->button.button == 3 )
664
GdkEventButton* evb = (GdkEventButton*)event;
665
handle_popup((int)event->button.x, (int)event->button.y, event->button.time, evb);
666
// Return true to preserve selection. In handle_popup check that popup is requested
674
//------------------------------------------------------------------------------
675
Gtk::TreeModelFlags ListModelWrapper::get_flags_vfunc() const
677
return Gtk::TREE_MODEL_ITERS_PERSIST | Gtk::TREE_MODEL_LIST_ONLY;
680
//------------------------------------------------------------------------------
681
bec::NodeId ListModelWrapper::get_node_for_path(const Gtk::TreeModel::Path &path) const
684
return bec::NodeId();
685
return bec::NodeId(path.to_string());
688
//------------------------------------------------------------------------------
689
bool ListModelWrapper::init_gtktreeiter(GtkTreeIter *it, const bec::NodeId &node) const
691
if ( _tm && it && node.is_valid() )
696
return it && node.is_valid();
700
//------------------------------------------------------------------------------
701
bec::NodeId ListModelWrapper::node_for_iter(const iterator &iter) const
703
const GtkTreeIter* it = iter.gobj();
709
if (id.cmp_stamp(_stamp))
716
//------------------------------------------------------------------------------
717
void ListModelWrapper::refresh()
719
if (_tm) _tm->refresh();
720
model_changed(bec::NodeId(), -1);
724
//------------------------------------------------------------------------------
725
void ListModelWrapper::note_row_added()
730
Gtk::TreePath path(_tm->count()-1);
732
row_inserted(path, get_iter(path));
736
//------------------------------------------------------------------------------
737
void ListModelWrapper::set_fake_column_value_getter(FakeColumnValueGetter fake_getter)
739
_fake_column_value_getter = fake_getter;
742
//------------------------------------------------------------------------------
743
void ListModelWrapper::set_fake_column_value_setter(FakeColumnValueSetter fake_setter)
745
_fake_column_value_setter = fake_setter;
748
//------------------------------------------------------------------------------
749
void ListModelWrapper::reset_iter(iterator& iter) const throw()
751
GtkTreeIter *it = iter.gobj();
752
Index::reset_iter(it);
755
//------------------------------------------------------------------------------
756
int ListModelWrapper::get_n_columns_vfunc() const
758
return _columns.size();
761
//------------------------------------------------------------------------------
762
GType ListModelWrapper::get_column_type_vfunc(int index) const
764
return *(_columns.types() + index);
767
//------------------------------------------------------------------------------
768
bool ListModelWrapper::iter_next_vfunc(const iterator& iter, iterator& iter_next) const
771
bec::NodeId current_node= node_for_iter(iter);
773
//g_message("LMW::iter_next_vfunc: %s", _name.c_str());
775
// Invalidate iter_next
776
reset_iter(iter_next);
780
if (current_node.is_valid() && _tm->has_next(current_node))
784
// Obtain parent of the current node to get number of children of the parent node
785
current_node = _tm->get_next(current_node);
789
current_node= bec::NodeId();
791
// Check if the resulted nodeid is valid and setup iter_next with values pointing to the nodeid
792
if ( current_node.is_valid() )
793
ret = init_gtktreeiter(iter_next.gobj(), current_node);
799
//------------------------------------------------------------------------------
800
bool ListModelWrapper::get_iter_vfunc(const Path& path, iterator& iter) const
803
GtkTreeIter* it = iter.gobj();
805
// Invalidate iter_next
810
bec::NodeId node(path.to_string());
812
if ( node.is_valid() && node.back() < _tm->count() )
813
ret = init_gtktreeiter(it, node);
818
//------------------------------------------------------------------------------
819
bool ListModelWrapper::iter_children_vfunc(const iterator& parent, iterator& iter) const
824
//------------------------------------------------------------------------------
825
bool ListModelWrapper::iter_parent_vfunc(const iterator& child, iterator& iter) const
830
//------------------------------------------------------------------------------
831
bool ListModelWrapper::iter_nth_child_vfunc(const iterator& parent, int n, iterator& iter) const
836
//------------------------------------------------------------------------------
837
bool ListModelWrapper::iter_nth_root_child_vfunc(int n, iterator& iter) const
840
//Sets @a iter to be the child of at the root level using the given index. The first
841
//index is 0. If @a n is too big, or if there are no children, @a iter is set
842
//to an invalid iterator and false is returned.
843
//See also iter_nth_child_vfunc().
844
if ( _tm && n >= 0 && n < iter_n_root_children_vfunc() )
846
bec::NodeId node = _tm->get_node(n);
847
init_gtktreeiter(iter.gobj(), node);
854
//------------------------------------------------------------------------------
855
bool ListModelWrapper::iter_has_child_vfunc(const iterator& iter) const
857
return iter_n_children_vfunc(iter) != 0;
860
//------------------------------------------------------------------------------
861
int ListModelWrapper::iter_n_children_vfunc(const iterator& iter) const
866
//------------------------------------------------------------------------------
867
int ListModelWrapper::iter_n_root_children_vfunc() const
869
const int ret = _tm ? _tm->count() : 0;
873
//------------------------------------------------------------------------------
874
Gtk::TreeModel::Path ListModelWrapper::get_path_vfunc(const iterator& iter) const
876
const bec::NodeId node = node_for_iter(iter);
877
Gtk::TreeModel::Path path;
879
if ( node.is_valid() )
881
const int node_depth = node.depth();
883
for ( int i = 0; i < node_depth; i++ )
884
path.push_back(node[i]);
890
//------------------------------------------------------------------------------
891
void ListModelWrapper::get_icon_value(const iterator& iter, int column, const bec::NodeId &node, Glib::ValueBase& value) const
896
static ImageCache *pixbufs = ImageCache::get_instance();
897
static Glib::RefPtr<Gtk::IconTheme> icon_theme= Gtk::IconTheme::get_default();
898
GValue *gval = value.gobj();
900
bec::IconId icon_id = _tm->get_field_icon(node, column, get_icon_size());
902
g_value_init(gval, GDK_TYPE_PIXBUF);
905
Glib::RefPtr<Gdk::Pixbuf> pixbuf = pixbufs->image(icon_id);
909
g_value_set_object(gval, pixbuf->gobj());
914
//------------------------------------------------------------------------------
915
void ListModelWrapper::get_value_vfunc(const iterator& iter, int column, Glib::ValueBase& value) const
920
bec::NodeId node= node_for_iter(iter);
922
if ( node.is_valid() )
924
const GType type = *(_columns.types() + column);
926
column = _columns.ui2bec(column);
930
if ( !_fake_column_value_getter.empty() )
931
_fake_column_value_getter(iter, column, type, value);
933
else if ( type == GDK_TYPE_PIXBUF )
935
get_icon_value(iter, column, node, value);
944
_tm->get_field(node, column, bv);
945
set_glib_bool(value, bv);
946
lmwdprint("LMW::get_value_vfunc: %s: node %s, col %i: value: %i\n", _name.c_str(), node.repr().c_str(), column, bv);
953
_tm->get_field(node, column, iv);
954
set_glib_int(value, iv);
955
lmwdprint("LMW::get_value_vfunc: %s: node %s, col %i: value: %i\n", _name.c_str(), node.repr().c_str(), column, iv);
963
throw std::logic_error("Imlement long ints in get_value_func");
970
_tm->get_field(node, column, dv);
971
set_glib_double(value, dv);
972
lmwdprint("LMW::get_value_vfunc: %s: node %s, col %i: value: %f\n", _name.c_str(), node.repr().c_str(), column, dv);
979
sv= _tm->get_field_description(node, -column);
981
_tm->get_field_repr(node, column, sv);
982
set_glib_string(value, sv, true);
983
lmwdprint("LMW::get_value_vfunc: %s: node %s, col %i: value: '%s'\n", _name.c_str(), node.repr().c_str(), column, sv.c_str());
987
set_glib_string(value, "<unkn>");
994
//------------------------------------------------------------------------------
995
bool ListModelWrapper::iter_is_valid(const iterator& iter) const
997
bec::NodeId node(node_for_iter(iter));
999
return node.is_valid();
1002
//------------------------------------------------------------------------------
1003
void ListModelWrapper::set_value_impl(const iterator& row, int column, const Glib::ValueBase& value)
1008
bec::NodeId node(node_for_iter(row));
1010
if ( node.is_valid() )
1012
const GType type = *(_columns.types() + column);
1013
column = _columns.ui2bec(column);
1017
if ( !_fake_column_value_setter.empty() )
1018
_fake_column_value_setter(row, column, type, value);
1024
case G_TYPE_BOOLEAN:
1026
Glib::Value<bool> v;
1027
v.init(value.gobj());
1028
lmwdprint("LMW::set_value_impl:%s node %s, column %i, value %i\n", _name.c_str(), node.repr().c_str(), column, v.get());
1029
_tm->set_field(node, column, v.get());
1036
v.init(value.gobj());
1037
lmwdprint("LMW::set_value_impl: node %s, column %i, value %i\n", node.repr().c_str(), column, v.get());
1038
_tm->set_field(node, column, v.get());
1044
Glib::Value<double> v;
1045
v.init(value.gobj());
1046
_tm->set_field(node, column, v.get());
1051
Glib::Value<std::string> v;
1052
v.init(value.gobj());
1053
_tm->set_field(node, column, v.get());
1054
lmwdprint("LMW::set_value: %s '%s'\n", _name.c_str(), v.get().c_str());
1064
//------------------------------------------------------------------------------
1065
void ListModelWrapper::get_value_impl(const iterator& row, int column, Glib::ValueBase& value) const
1067
get_value_vfunc(row, column, value);
1070
//------------------------------------------------------------------------------
1071
void ListModelWrapper::set_row_draggable_slot(const sigc::slot<bool, Gtk::TreeModel::Path> &slot)
1073
_row_draggable= slot;
1076
//------------------------------------------------------------------------------
1077
bool ListModelWrapper::drag_data_get_vfunc(const Gtk::TreeModel::Path& path, Gtk::SelectionData& selection_data) const
1079
selection_data.set("text/path", path.to_string());
1083
//------------------------------------------------------------------------------
1084
bool ListModelWrapper::drag_data_delete_vfunc (const Gtk::TreeModel::Path& path)
1089
//------------------------------------------------------------------------------
1090
bool ListModelWrapper::row_draggable_vfunc(const TreeModel::Path &path) const
1093
return _row_draggable(path);
1098
//------------------------------------------------------------------------------
1099
bool ListModelWrapper::row_drop_possible_vfunc(const Gtk::TreeModel::Path& dest, const Gtk::SelectionData& selection_data) const
1104
//------------------------------------------------------------------------------
1105
bool ListModelWrapper::drag_data_received_vfunc(const Gtk::TreeModel::Path& dest, const Gtk::SelectionData& selection_data)
1108
// Currently this works for linear lists
1111
_tm->reorder(bec::NodeId((const char*)selection_data.get_data()), dest.front());
1114
catch (const std::logic_error& e)