//------------------------------------------------------------------------------
const StringColumn&
ColumnsModel::set_text_column(const int          bec_tm_idx
                                ,const bool         editable
                                ,Gtk::IconView     *iv
                                )
{
  // Create columns
  // add mapping from ui to bec
  // add them with add() to the model
  // add columns to the IconView
  // check if editable and bind signals

  Gtk::TreeModelColumn<Glib::ustring> *text = new Gtk::TreeModelColumn<Glib::ustring>;
  Gtk::TreeModelColumn<Glib::RefPtr<Gdk::Pixbuf> > *icon = new Gtk::TreeModelColumn<Glib::RefPtr<Gdk::Pixbuf> >;

  _columns.push_back(text);
  _columns.push_back(icon);

  add_bec_index_mapping(bec_tm_idx);
  add_bec_index_mapping(bec_tm_idx);

  add(*text);
  add(*icon);

  iv->set_text_column(*text);
  iv->set_pixbuf_column(*icon);

  return *text;
}
//------------------------------------------------------------------------------
const StringColumn& ColumnsModel::append_markup_column(const int bec_tm_idx, const std::string& name,
                                                       const Iconic have_icon) {
  Gtk::TreeModelColumn<Glib::RefPtr<Gdk::Pixbuf>>* icon = 0;

  Gtk::TreeViewColumn* column = Gtk::manage(new Gtk::TreeViewColumn(base::replaceString(name, "_", "__")));

  if (have_icon == WITH_ICON) {
    icon = new Gtk::TreeModelColumn<Glib::RefPtr<Gdk::Pixbuf>>;
    add(*icon);
    add_bec_index_mapping(bec_tm_idx);
    column->pack_start(*icon, false);

    _columns.push_back(icon);
  }

  Gtk::TreeModelColumn<Glib::ustring>* col = new Gtk::TreeModelColumn<Glib::ustring>;
  Gtk::CellRendererText* cell = Gtk::manage(new Gtk::CellRendererText());
  add(*col);
  add_bec_index_mapping(bec_tm_idx);
  column->pack_start(*cell);
  column->add_attribute(cell->property_markup(), *col);

  _columns.push_back(col);

  int nr_of_cols = _treeview->append_column(*column);
  _treeview->get_column(nr_of_cols - 1)->set_resizable(true);

  return *col;
}
const StringColumn&
ColumnsModel::append_string_column(const int bec_tm_idx, const std::string& name, const Editable editable, const Iconic have_icon)
{
  Gtk::TreeModelColumn<Glib::RefPtr<Gdk::Pixbuf> > *icon= 0;

  Gtk::TreeViewColumn *column= Gtk::manage(new Gtk::TreeViewColumn(bec::replace_string(name, "_", "__")));

  if ( have_icon == WITH_ICON )
  {
    icon = new Gtk::TreeModelColumn<Glib::RefPtr<Gdk::Pixbuf> >;
    add(*icon);
    add_bec_index_mapping(bec_tm_idx);
    column->pack_start(*icon, false);

    _columns.push_back(icon);
  }

  Gtk::TreeModelColumn<Glib::ustring> *col = new Gtk::TreeModelColumn<Glib::ustring>;
  add(*col);
  add_bec_index_mapping(bec_tm_idx);
  column->pack_start(*col);

  _columns.push_back(col);

  int nr_of_cols= _treeview->append_column(*column);
  _treeview->get_column(nr_of_cols-1)->set_resizable(true);

  if (editable == EDITABLE || editable == EDITABLE_WO_FIRST)
  {

    std::vector<Gtk::CellRenderer*> rends= column->get_cell_renderers();

    Gtk::CellRendererText *cell = (Gtk::CellRendererText*)rends[icon ? 1 : 0];
    cell->property_editable()= true;
    cell->signal_edited().connect(sigc::bind
                                  (sigc::mem_fun(*_tmw
                                                ,&ListModelWrapper::after_cell_edit<Glib::ustring>
                                                )
                                                , sigc::ref(*col)
                                  )
                                 );

    if (editable == EDITABLE_WO_FIRST)
      column->set_cell_data_func(*cell, sigc::mem_fun(this, &ColumnsModel::disable_edit_first_row));
  }

  return *col;
}
int ColumnsModel::add_generic_column(const int bec_tm_idx, Gtk::TreeModelColumnBase* column,
                                     Gtk::TreeViewColumn* vcolumn) {
  add(*column);
  add_bec_index_mapping(bec_tm_idx);

  return _treeview->append_column(*vcolumn);
}
//------------------------------------------------------------------------------
int ColumnsModel::append_check_column(const int bec_tm_idx, const std::string& name, const Editable editable,
                                      const ToggleAction action) {
  Gtk::TreeModelColumn<bool>* col = new Gtk::TreeModelColumn<bool>;
  _columns.push_back(col);
  add(*col);
  add_bec_index_mapping(bec_tm_idx);

  int nr_of_cols;
  // If we have bec_tm_idx set to negative value it means that column added is not
  // directly mapped to a model. Handling of values set/get are done through
  // ListModelWrapper::_fake_column_value_getter/setter slot
  if (editable == EDITABLE) {
    nr_of_cols = _treeview->append_column_editable(base::replaceString(name, "_", "__"), *col);

    Gtk::CellRendererToggle* cell = (Gtk::CellRendererToggle*)(_treeview->get_column_cell_renderer(nr_of_cols - 1));
    cell->property_activatable() = true;
    if (action == TOGGLE_BY_WRAPPER /* && bec_tm_idx >= 0 */) {
      cell->signal_toggled().connect(sigc::bind(sigc::mem_fun(*_tmw, &ListModelWrapper::after_cell_toggle /*<bool>*/
                                                              ),
                                                sigc::ref(*col)));
    }
  } else
    nr_of_cols = _treeview->append_column(base::replaceString(name, "_", "__"), *col);

  _treeview->get_column(nr_of_cols - 1)->set_resizable(true);

  return nr_of_cols;
}
//------------------------------------------------------------------------------
void ColumnsModel::add_tooltip_column(int bec_tm_idx) {
  Gtk::TreeModelColumn<Glib::ustring>* col = new Gtk::TreeModelColumn<Glib::ustring>;
  add(*col);
  add_bec_index_mapping(-bec_tm_idx); // negative means pick description

  _columns.push_back(col);
}
//------------------------------------------------------------------------------
const IntColumn&
ColumnsModel::append_int_column(const int bec_tm_idx, const std::string& name, const Editable editable)
{
  Gtk::TreeModelColumn<int> *col = new Gtk::TreeModelColumn<int>;

  add(*col);
  add_bec_index_mapping(bec_tm_idx);

  int nr_of_cols;
  if ( editable == EDITABLE )
  {
    nr_of_cols= _treeview->append_column_editable(bec::replace_string(name, "_", "__"), *col);

    Gtk::CellRendererText *cell = (Gtk::CellRendererText*)(_treeview->get_column_cell_renderer(nr_of_cols - 1));
    cell->signal_edited().connect(sigc::bind
                                  (sigc::mem_fun(*_tmw
                                                ,&ListModelWrapper::after_cell_edit<int>
                                                )
                                                , sigc::ref(*col)
                                  )
                                 );
  }
  else
    nr_of_cols= _treeview->append_column(bec::replace_string(name, "_", "__"), *col);

  _treeview->get_column(nr_of_cols-1)->set_resizable(true);

  _columns.push_back(col);

  return *col;
}
//------------------------------------------------------------------------------
const StringColumn&
ColumnsModel::append_combo_column(const int bec_tm_idx
                                     ,const std::string            &name
                                     ,Glib::RefPtr<Gtk::ListStore>  list_w
                                     ,const Editable                editable
                                     ,bool popup_only)
{
  Gtk::TreeModelColumn<Glib::ustring> *choosen = new Gtk::TreeModelColumn<Glib::ustring>;
  _columns.push_back(choosen);
  add(*choosen);
  add_bec_index_mapping(bec_tm_idx);

  Gtk::TreeView::Column   *col = Gtk::manage(new Gtk::TreeViewColumn(bec::replace_string(name, "_", "__")));
  Gtk::CellRendererCombo *cell = Gtk::manage(new Gtk::CellRendererCombo);
  col->pack_start(*cell);

  col->add_attribute(cell->property_text(), *choosen);
  cell->property_model() = list_w;
  cell->property_text_column() = 0;
  cell->property_editable() = editable;
  cell->property_has_entry() = !popup_only;
  
  Gtk::TreeModelColumn<Glib::RefPtr<Gtk::TreeModel> > *model_col = new Gtk::TreeModelColumn<Glib::RefPtr<Gtk::TreeModel> >();
  add_bec_index_mapping(bec_tm_idx);
  add(*model_col);
  const int nr_of_cols = _treeview->append_column(*col);

  _columns.push_back(model_col);

  _treeview->get_column(nr_of_cols-1)->set_resizable(true);

  if ( editable == EDITABLE )
  {
    Gtk::CellRendererText *cell = (Gtk::CellRendererText*)(_treeview->get_column_cell_renderer(nr_of_cols - 1));
    cell->signal_edited().connect(sigc::bind
                                    (sigc::mem_fun(*_tmw
                                                  ,&ListModelWrapper::after_cell_edit<Glib::ustring>
                                                  )
                                                  , sigc::ref(*choosen)
                                   )
                                 );
  }

  return *choosen;
}
//------------------------------------------------------------------------------
const DoubleColumn& ColumnsModel::append_double_column(const int bec_tm_idx, const std::string& name,
                                                       const Editable editable) {
  Gtk::TreeModelColumn<double>* col = new Gtk::TreeModelColumn<double>;
  add_bec_index_mapping(bec_tm_idx);
  add(*col);

  _columns.push_back(col);

  return *col;
}
//------------------------------------------------------------------------------
void ColumnsModel::add_model_column(Gtk::TreeModelColumnBase* col, int bec_tm_idx) {
  add(*col);
  add_bec_index_mapping(bec_tm_idx);
  _columns.push_back(col);
}