void GscExecutorLogWindow::show_last()
{
	Gtk::TreeView* treeview = this->lookup_widget<Gtk::TreeView*>("command_list_treeview");

	if (treeview && !list_store->children().empty()) {
// 		Gtk::TreeRow row = *(list_store->children().rbegin());  // this causes invalid read error in valgrind
		Gtk::TreeRow row = *(--(list_store->children().end()));
		selection->select(row);
		// you would think that scroll_to_row would accept a TreeRow for a change (shock!)
		treeview->scroll_to_row(list_store->get_path(row));
	}

	show();
}
void GscExecutorLogWindow::on_command_output_received(const CmdexSyncCommandInfo& info)
{
	CmdexSyncCommandInfoRefPtr entry = info.copy();
	entries.push_back(entry);

	// update tree model
	Gtk::TreeRow row = *(list_store->append());
	row[col_num] = entries.size();
	row[col_command] = entry->command + " " + entry->parameters;
	row[col_entry] = entry;

	// if visible, set the selection to it
	if (this->is_visible()) {
		Gtk::TreeView* treeview = this->lookup_widget<Gtk::TreeView*>("command_list_treeview");

		if (treeview) {
			selection->select(row);
			treeview->scroll_to_row(list_store->get_path(row));
		}
	}
}
void GraphTreeModel::updateSelectionStatus(const Glib::RefPtr<Gtk::TreeSelection>& selection, const scene::INodePtr& node)
{
	NodeMap::const_iterator found = _nodemap.find(scene::INodeWeakPtr(node));

	GraphTreeNodePtr foundNode;

	if (found == _nodemap.end())
	{
		// The node is not in our map, it might have been previously hidden
		if (node->visible())
		{
			foundNode = insert(node);
		}
	}
	else
	{
		foundNode = found->second;
	}

	if (foundNode)
	{
		if (Node_isSelected(node))
		{
			// Select the row in the TreeView
			selection->select(foundNode->getIter());

			// Scroll to the row
			Gtk::TreeView* tv = selection->get_tree_view();

			Gtk::TreeModel::Path selectedPath(foundNode->getIter());

			tv->expand_to_path(selectedPath);
			tv->scroll_to_row(selectedPath, 0.3f);
		}
		else
		{
			selection->unselect(foundNode->getIter());
		}
	}
}