Re: How can I port this gtk construct to gtkmm?



Paul Davis wrote:
On 3/20/07, Jef Driesen <jefdriesen hotmail com> wrote:
Paul Davis wrote:
On 3/20/07, Jef Driesen <jefdriesen hotmail com> wrote:
I am writing my first gtkmm application (actually my first GUI
application). To get familiar with the toolkit (both gtk and gtkmm), I
studied the code of some existing applications. And in one of those
applications I found a construct that I would like to use in my own
application, but I don't know how to port the gtk code to gtkmm.

The main application contains a treeview and a secondary dialog is used
to edit the treeview entries. But if you try to edit an entry that is
already "open", the existing dialog is activated instead of creating a
new one (see code snippet below). How can I do this in C++?

And how do I automatically destroy the dialog after clicking the (close)
button?

[code removed]

I think I'd make a column in your TreeModelColumnRecord a smart
pointer to the dialog.

I'm not certain what I'd do to delete the window when its closed.  You
could connect to the dialog's signal_hide, bind the smart pointer to
the call back and search the tree view for the corresponding row, but
that seems rather inefficient. I suppose you could store weak pointers
in the tree view, the shared ptr's in a std::set and then your search
for the dialog to delete would be a bit faster.

Generally, I would only allow editing of a single row at a time to
prevent this but I could imagine there are times when having the
multiple row selection would be a good thing.

Storing a smart pointer in the treeview model is not the solution in my
case, because the treeview is not the only widget that can make the
dialog appear. That's why I liked the approach with the hashtable from
the code snippet. Because it doesn't matter at what place the function
is called, only one dialog will appear for the same object.

I'm not certain I follow. I suppose I am running under the assumption
that one object corresponds to a single row in the treeview.  The
problem at hand is that you need to have a method to correlate a
specific dialog instance to a specific row. This means that you need
to map from the rows to a dialog.

If your rows are globaly unique, then you *could* derive some hash key
that would allow you to store the dialog ptrs in a hash table ( or
std::map in C++ most likely).

I'll try to explain more clearly what I'm trying to do.

The treeview in my application will more or less display the contents of a table from an sqlite database. Each row in that table has a unique ID. I did say more or less, because the treeview will display only a summary of the whole "object" (e.g. some data is stored in auxiliary tables and linked to the row ID of the main table and that data is only shown in the dialog, but not in the treeview) and some treeview columns do not correspond directly to an column in the table (e.g. a one to many relationship in the database can be shown as a comma separated list in treeview column.).

So your assumption that one object corresponds to a single row is correct. But instead of associating a dialog with a row in the treeview, I wanted to associate it with the row ID from the database.

Storing a reference to the dialog along with the row removes this need
and makes things more general. Ie, you could change your tree view
model later as long as you leave the dialog ptr column named the same.

But with that approach it is not possible to edit objects that do not exist in the treeview model. Because in that case there is no place to store the reference to the dialog. I'm thinking of situations where only a subset of the whole table is displayed (e.g. searching or filtering).

Just because you store a reference to the dialog in the treeview
doesn't mean that the treeview is the only object capable of showing
the dialogs.  Storing it here is just a means of maintaining the
row->dialog relationship.

I know, but that makes those other places dependent on the internals of the treeview widget. Even if they are not directly related, except for having both the ability to show the dialog of course.

Maybe it is easier to see what I mean, by looking at an existing application, for instance Gnome Planner (where I found this idea). There is a view "Resources" (which would correspond to my treeview) and a another view "Resource usage". From both views it is possible to show the dialog to edit a resource object.

This is reinforced when we think about only storing the weak pointer
and using a std::set to store the actual shared ptrs. (Using the set
saves us from having to do a linear search through the tree model.)

I was not planning to allow multiple row selections in the treeview. But
it is possible to edit more than one entry simultaneously (e.g activate
an item in the treeview, move to the next and activate that one also).
The treeview doesn't have to be notified directly by the dialog about
changes. I wanted to make the database engine (sqlite) responsible for
doing that.

Yeah, s/selection/editing/

And its a good idea to go through your database layer so that all the
checking you do to make sure you're getting valid data occurrs before
your gui is updated.  (Although not necessary, it makes lifer easier
to prevent a change rather than undo a change).

The reason why I wanted to do this in the first place was different: If I make a change to the database somewhere, I don't have to notify every other widget about the change myself. Instead the widgets can update themself if they are notified by the database.





[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]