treeview selection single
- From: Maurizio Umberto Puxeddu <mauriziopuxeddu yahoo it>
- To: gtk-list gnome org
- Subject: treeview selection single
- Date: 08 Apr 2003 22:34:49 +0200
I'm using gtk+ via gtkmm.
I'm porting an application from to the new API but I have a problem with
code that was working in the previous version. I use several selectors
that are connected to "folders" following the model/view pattern (well,
with gtkmm 2.0 it's model/model-of-the-model/view!). I use the same code
in folder editors pannel and in one-click pop-up menus. In this second
situation I use Gtk::SELECTION_SINGLE otherwise Gtk::SELECTION_BROWSE.
The problems seems to be that, even with Gtk::SELECTION_SINGLE,
somewhere Gtk automatically selects the first item and the pop-up
closes. Obviously this was not the case using gtkmm-1.2.
I also tried connecting my selection callback after the population of
the model and unselecting all in several places but there is no way.
Strange but the examples/book/tree/list demo behaves in a similar way.
The first item is selected even if it shouldn't. The gtk demo on the
list store seems to work fine instead.
Any suggestion?
I hope this is not a stupid error on my side. I attached the code.
Maurizio Umberto Puxeddu.
// MetaControl
// Copyright (C) 2003 Maurizio Umberto Puxeddu
#ifndef _itemList_H_
#define _itemList_H_
#include <iostream>
#include <list>
#include <string>
#include <algorithm>
#include <gtkmm.h>
#include "utility.H"
#include "box.H"
#include "folder.H"
#include "window.H"
#include "regex.H"
template <class Item, class ItemFolder>
class ItemList : public Gtk::TreeView {
public:
ItemList(ItemFolder &folder, bool autoselect = true, bool showtitle = true,
const std::list<std::string> &excluded = std::list<std::string>());
SigC::Signal1<void, const std::string &> item_selected;
SigC::Signal1<void, int> resized;
int size(void);
std::string get_focused_item(void) const;
void set_focused_item(const std::string &name, bool noemit = false);
void clear_selection(void);
void set_pattern(const std::string &pattern);
std::string get_pattern(void) const;
void copy_selection(void);
void remove_selection(void);
void add_item(void);
protected:
class ModelColumns : public Gtk::TreeModel::ColumnRecord {
public:
ModelColumns() {
add(m_col_id);
add(m_col_name);
}
Gtk::TreeModelColumn<unsigned int> m_col_id;
Gtk::TreeModelColumn<Glib::ustring> m_col_name;
};
ModelColumns m_Columns;
Glib::RefPtr<Gtk::ListStore> m_refTreeModel;
ItemFolder &m_folder;
std::string m_focused_item;
bool m_autoselect;
std::list<std::string> m_excluded;
Regex m_rx;
void item_selected_cb(void);
void update_list(void);
// Folder callbacks
void item_added_cb(const std::string &name, const Item &);
void item_removed_cb(const std::string &name);
void item_renamed_cb(const std::string &old_name, const std::string &new_name);
void folder_cleared_cb(void);
void copy_row(const Gtk::TreeModel::iterator& i);
void remove_row(const Gtk::TreeModel::iterator& i);
};
template <class Item, class ItemFolder>
ItemList<Item, ItemFolder>::ItemList(ItemFolder &folder, bool autoselect, bool showtitle,
const std::list<std::string> &excluded) :
m_folder(folder),
m_autoselect(autoselect),
m_excluded(excluded)
{
if (m_autoselect) {
get_selection()->set_mode(Gtk::SELECTION_BROWSE);
std::cout << "browse" << std::endl;
} else {
get_selection()->set_mode(Gtk::SELECTION_SINGLE);
std::cout << "single" << std::endl;
}
m_refTreeModel = Gtk::ListStore::create(m_Columns);
set_model(m_refTreeModel);
append_column("Name", m_Columns.m_col_name);
set_headers_visible(showtitle);
set_headers_clickable(false);
update_list();
get_selection()->signal_changed().connect(SigC::slot(*this, &ItemList::item_selected_cb));
m_folder.item_renamed.connect(SigC::slot(*this, &ItemList<Item, ItemFolder>::item_renamed_cb));
m_folder.item_added.connect(SigC::slot(*this, &ItemList<Item, ItemFolder>::item_added_cb));
m_folder.item_removed.connect(SigC::slot(*this, &ItemList<Item, ItemFolder>::item_removed_cb));
m_folder.cleared.connect(SigC::slot(*this, &ItemList<Item, ItemFolder>::folder_cleared_cb));
get_selection()->unselect_all();
std::cout << "created" << std::endl;
}
template <class Item, class ItemFolder>
void ItemList<Item, ItemFolder>::set_pattern(const std::string &pattern) {
m_rx.compile(pattern);
update_list();
}
template <class Item, class ItemFolder>
std::string ItemList<Item, ItemFolder>::get_pattern(void) const {
return m_rx.get_pattern();
}
template <class Item, class ItemFolder>
int ItemList<Item, ItemFolder>::size(void) {
return m_folder.size();
}
template <class Item, class ItemFolder>
void ItemList<Item, ItemFolder>::update_list(void) {
typename ItemFolder::Items::iterator i;
m_refTreeModel->clear();
for (i = m_folder.begin(); i != m_folder.end(); ++i) {
if (!m_rx.match(i->first)) continue;
if (std::find(m_excluded.begin(), m_excluded.end(), i->first) == m_excluded.end())
item_added_cb(i->first, i->second);
}
}
template <class Item, class ItemFolder>
void ItemList<Item, ItemFolder>::item_selected_cb(void) {
Gtk::TreeModel::iterator iter = get_selection()->get_selected();
if(iter) {
Gtk::TreeModel::Row row = *iter;
std::cout << row.get_value(m_Columns.m_col_name) << std::endl;
set_focused_item(row.get_value(m_Columns.m_col_name));
}
}
template <class Item, class ItemFolder>
void ItemList<Item, ItemFolder>::clear_selection(void) {
if (m_focused_item != "") {
m_focused_item = "";
get_selection()->unselect_all();
}
}
template <class Item, class ItemFolder>
void ItemList<Item, ItemFolder>::set_focused_item(const std::string &name, bool noemit) {
if (name == "" && m_focused_item == name) return;
m_focused_item = name;
if (!noemit) item_selected(name);
}
template <class Item, class ItemFolder>
std::string ItemList<Item, ItemFolder>::get_focused_item(void) const {
return m_focused_item;
}
template <class Item, class ItemFolder>
void ItemList<Item, ItemFolder>::item_added_cb(const std::string &name, const Item &) {
if (std::find(m_excluded.begin(), m_excluded.end(), name) != m_excluded.end()) return;
Gtk::TreeModel::iterator iter = m_refTreeModel->append();
Gtk::TreeModel::Row row = *iter;
row[m_Columns.m_col_name] = name;
if (m_autoselect) {
std::cout << "autoselecting: " << name << std::endl;
get_selection()->select(row);
}
resized(m_folder.size());
}
template <class Item, class ItemFolder>
void ItemList<Item, ItemFolder>::item_removed_cb(const std::string &name) {
int i;
if (std::find(m_excluded.begin(), m_excluded.end(), name) != m_excluded.end())
m_excluded.remove(name);
typedef Gtk::TreeModel::Children type_children;
type_children children = m_refTreeModel->children();
for(type_children::iterator i = children.begin(); i != children.end(); ++i) {
Gtk::TreeModel::Row row = *i;
if (row[m_Columns.m_col_name] == name) {
if (name == m_focused_item)
set_focused_item("");
m_refTreeModel->erase(i);
if (m_autoselect) {
}
resized(m_folder.size());
break;
}
}
}
template <class Item, class ItemFolder>
void ItemList<Item, ItemFolder>::item_renamed_cb(const std::string &old_name, const std::string &new_name) {
std::string s;
int i;
if (std::find(m_excluded.begin(), m_excluded.end(), old_name) != m_excluded.end()) {
m_excluded.remove(old_name);
m_excluded.push_back(new_name);
}
typedef Gtk::TreeModel::Children type_children;
type_children children = m_refTreeModel->children();
for(type_children::iterator iter = children.begin(); iter != children.end(); ++iter) {
Gtk::TreeModel::Row row = *iter;
#if 0
std::cout << "renaming " << old_name << " to " << new_name << " - " << row[m_Columns.m_col_name] << std::endl;
#endif
if (row[m_Columns.m_col_name] == old_name) {
row[m_Columns.m_col_name] = new_name;
break;
}
}
}
template <class Item, class ItemFolder>
void ItemList<Item, ItemFolder>::folder_cleared_cb(void) {
m_excluded.clear();
m_refTreeModel->clear();
set_focused_item("");
resized(0);
}
template <class Item, class ItemFolder>
void ItemList<Item, ItemFolder>::copy_row(const Gtk::TreeModel::iterator& i) {
std::string name;
if (i) {
name = i->get_value(m_Columns.m_col_name);
std::string new_name;
int i;
for (i = 1; i < 10000; ++i) {
new_name = name + " copy n." + int_to_string(i);
if (m_folder.copy_item_if_possible(name, new_name))
break;
}
}
}
template <class Item, class ItemFolder>
void ItemList<Item, ItemFolder>::copy_selection(void) {
get_selection()->selected_foreach(SigC::slot(*this, &ItemList<Item, ItemFolder>::copy_row));
}
template <class Item, class ItemFolder>
void ItemList<Item, ItemFolder>::remove_row(const Gtk::TreeModel::iterator& i) {
m_folder.remove_item(i->get_value(m_Columns.m_col_name));
}
template <class Item, class ItemFolder>
void ItemList<Item, ItemFolder>::remove_selection(void) {
get_selection()->selected_foreach(SigC::slot(*this, &ItemList<Item, ItemFolder>::remove_row));
}
template <class Item, class ItemFolder>
void ItemList<Item, ItemFolder>::add_item(void) {
std::string name;
int i;
name = m_folder.create_item();
typedef Gtk::TreeModel::Children type_children;
type_children children = m_refTreeModel->children();
for(type_children::iterator iter = children.begin(); iter != children.end(); ++iter) {
Gtk::TreeModel::Row row = *iter;
if (row[m_Columns.m_col_name] == name) {
get_selection()->select(row);
break;
}
}
}
#endif // _itemList_H_
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]