Hello, I am trying to write a program showing a list of books. There are three columns, the first column having two renderers (Icon + Text). I have appended a file with the list implementation, also a test package (can be compiled using "g++ *.cc -o test `pkg-config gtkmm-2.4 --cflags --libs`") wich demonstrates the following problems: (1) When using Gtk::TreeModelSort, the initial sorting is done on the second column, while through using sortstore->set_sort_column_id(columns.author_and_title, Gtk::SORT_ASCENDING); i expected it to be done on the first column. How can I change that? (2) When clicking the first column to change the sort order, the program is trying to sort the column by the icon rather then the text. How can I change that? (3) Most importantly: I am trying to somehow remove the currently selected row. But when using store->erase(get_selection()->get_selected()); (the offending code is in GtkBookList::remove_selected()) There is an error message (test:22738): Gtk-CRITICAL **: file gtkliststore.c: line 1013 (gtk_list_store_remove): assertion `VALID_ITER (iter, list_store)' failed (This can be tested by clicking "delete" in the appended test.) I have been hunting especially the last bug for hours and hours and now I'm completely lost. Any hints appreciated. Thanks, -Samuel -- ------------------------------------------------------ | Samuel Abels | http://www.debain.org | | spam ad debain dod org | knipknap ad jabber dod org | ------------------------------------------------------
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "GtkBookList.h"
GtkBookList::GtkBookList()
{
// Attach the liststore to the treeview.
store = Gtk::ListStore::create(columns);
sortstore = Gtk::TreeModelSort::create(store);
sortstore->set_sort_column_id(columns.author_and_title, Gtk::SORT_ASCENDING);
set_model(sortstore);
set_rules_hint();
set_headers_visible(TRUE);
set_headers_clickable();
// Load the icon.
pixbuf_book = Gdk::Pixbuf::create_from_file("book.png");
// Create a cell renderer and pack it into the "Author and Title" column.
Gtk::TreeView::Column* col = Gtk::manage(
new Gtk::TreeView::Column("Autor und Titel"));
col->pack_start(columns.icon, FALSE);
col->pack_start(columns.author_and_title, TRUE);
// Enable pango markup language for the text renderer and change the layout
// for the icon renderer.
std::vector<Gtk::CellRenderer*> rends = col->get_cell_renderers();
rends[0]->set_fixed_size(60, 48);
col->clear_attributes(*rends[1]);
col->add_attribute(*rends[1], "markup", 1);
rends[1]->property_yalign() = 0.3;
// Append all columns.
append_column(*col);
get_column(0)->set_resizable(TRUE);
get_column(0)->set_sort_column_id(0);
append_column("Kategorie", columns.category);
get_column(1)->set_resizable(TRUE);
get_column(1)->set_sort_column_id(1);
append_column("ISBN", columns.isbn);
get_column(2)->set_resizable(TRUE);
get_column(2)->set_sort_column_id(2);
signal_row_activated().connect(
sigc::mem_fun(*this, &GtkBookList::on_selection_activated));
get_selection()->signal_changed().connect(
sigc::mem_fun(*this, &GtkBookList::on_selection_changed));
}
GtkBookList::~GtkBookList()
{
}
void GtkBookList::insert_book(Book* book)
{
Gtk::TreeIter iter = store->append();
Gtk::TreeRow row = *iter;
row_fill(row, book);
booklist[book] = iter;
}
void GtkBookList::remove_book(Book* book)
{
//FIXME: This does not work.
printf("GtkBookList::remove_book(): %s\n", book->get_title().c_str());
g_assert(booklist.find(book) != booklist.end());
Gtk::TreeIter iter = booklist.find(book)->second;
store->erase(iter);
booklist.erase(book);
}
void GtkBookList::remove_selected(void)
{
//FIXME: Neither does this.
printf("GtkBookList::remove_selected(): Called.\n");
if (!get_selection()->get_selected())
return;
Book* book = get_selection()->get_selected()->get_value(columns.book);
store->erase(get_selection()->get_selected());
booklist.erase(book);
}
void GtkBookList::update_soft(void)
{
std::map<Book*, Gtk::TreeIter>::iterator iter = booklist.begin();
while (iter != booklist.end()) {
Book* book = iter->first;
Gtk::TreeRow row = *iter->second;
row_fill(row, book);
iter++;
}
}
Book* GtkBookList::get_first_selected(void)
{
if (!get_selection()->get_selected())
return NULL;
return get_selection()->get_selected()->get_value(columns.book);
}
void GtkBookList::row_fill(Gtk::TreeModel::Row &row, Book* book)
{
std::vector<Gtk::CellRenderer*> rends = get_column(0)->get_cell_renderers();
row[columns.icon] = pixbuf_book;
row[columns.author_and_title] = "<b>" + book->get_author() + "</b>\n"
+ book->get_title();
row[columns.category] = book->get_category();
row[columns.isbn] = book->get_isbn();
row[columns.book] = book;
}
void GtkBookList::on_selection_activated(Gtk::TreePath path,
Gtk::TreeViewColumn* column)
{
Book* book = sortstore->get_iter(path)->get_value(columns.book);
signal_book_activated.emit(book);
}
void GtkBookList::on_selection_changed(void)
{
Book* book = get_selection()->get_selected()->get_value(columns.book);
signal_book_selected.emit(book);
}
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef _GTKBOOKLIST_H
#define _GTKBOOKLIST_H
#include <gtkmm.h>
#include <iostream>
#include <map>
#include "Book.h"
class GtkBookList : public Gtk::TreeView {
public:
GtkBookList();
~GtkBookList();
/* Triggered whenever a book has been selected. */
SigC::Signal1<void, Book*> signal_book_selected;
/* Triggered whenever a book has been activated. */
SigC::Signal1<void, Book*> signal_book_activated;
/* Inserts the given book. */
void insert_book(Book* book);
/* Removes the given book from the list. */
void remove_book(Book* book);
/* Removes the selected book. */
void remove_selected(void);
/* Walks through all books that are currently in the list, updating the
* row text in case anything changed. */
void update_soft(void);
/* Returns the first selected book. */
Book* get_first_selected(void);
private:
/* Fills the given tree row with the data from the given book. */
void row_fill(Gtk::TreeModel::Row &row, Book* book);
void on_selection_activated(Gtk::TreePath path,
Gtk::TreeViewColumn* column);
void on_selection_changed(void);
// List model columns.
class ModelColumns : public Gtk::TreeModel::ColumnRecord {
public:
Gtk::TreeModelColumn<Glib::RefPtr<Gdk::Pixbuf> > icon;
Gtk::TreeModelColumn<Glib::ustring> author_and_title;
Gtk::TreeModelColumn<Glib::ustring> category;
Gtk::TreeModelColumn<Glib::ustring> isbn;
Gtk::TreeModelColumn<Book*> book;
ModelColumns() {
add(icon);
add(author_and_title);
add(category);
add(isbn);
add(book);
}
};
Glib::RefPtr<Gtk::ListStore> store;
Glib::RefPtr<Gtk::TreeModelSort> sortstore;
Gtk::CellRendererText renderer_text;
Glib::RefPtr<Gdk::Pixbuf> pixbuf_book;
ModelColumns columns;
std::map<Book*, Gtk::TreeIter> booklist;
};
#endif /* _GTKBOOKLIST_H */
Attachment:
booklist.tar.bz2
Description: application/bzip-compressed-tar