PDA

View Full Version : Model/View separation advice sought



ChrisW67
19th May 2012, 07:13
Please bear with me. I have a longish post. Here are the players:

A table model that maintains a series of locations in a route and some related, mostly computed, information. Rows in the model are not totally independent of each other.
A QTableView that displays said model.
A database of predefined routes (Rn) between two locations, e.g. R1 is A to D via C and Q, R2 is A to D via B, R3 is D to Z via R etc. There are also compound routes (CRn) built from others , eg. CR1 is A to Z using R1 and R3, CR2 is A to Z using R2 and R3, just because this was not enough fun already :)


The user's perspective:

The user can edit a location in a new model row in order to add a new point.
When user adds a point any predefined routes between the preceding point and the new point are displayed allowing the user to select one or opt to go direct.
The points of the selected route (if not direct) should be inserted between the preceding point and the new point and the view's current item should be the newly edited item.


The programming monkey options:

In the view delegate on the location column I can intercept the attempt to save a location change, do the route option lookup, present the options, and expand the route from the delegate.
I can allow the location change to go through to the model and then have the model look up relevant routes, get a user response on which route, then expand the route.
I can simply put the location in the model with a null route. When the model is computed (i.e. distances, bearings) and I see a null route look up relevant routes, get a user response on which route, then expand the route before computation.


Option 1 makes the view (delegate) logic aware of the location and route data sources and puts the non-trivial logic of expanding the route in the UI; generally this is not good for separation of concerns. It has the advantage the the user interface is nearby to ask, "Which route?" in a straightforward way.

Options 2 and 3 have the difficulty that there's no straightforward way to get a user response on which route to use but they are already in contact with the underlying data. Slots cannot return a value, i.e. the index of a route selected from a list, so they are of limited use. I can use std::tr1::function to provide a call back to a method in the UI with a return value.


typedef std::tr1::function<int(const QStringList&)> RoutingDecisionFunc;

I did start off down option 3 but the plumbing is becoming a bit of a mess. Option 2 may be better in hindsight because the view already sees the model (I have a similar problem with ambiguous locations where prompting the user would be helpful).

I am wondering which approach you would choose? Have I missed really obvious options to do this in the model/view framework?

Thanks for reading this far. I hope I have not just earned a face palm
7738

wysota
20th May 2012, 16:32
I would choose option 1. Making the delegate logic-aware is nothing bad. Most likely you only have to make the editor widget logic aware or make all the fun happen in setModelData() method of the delegate (or combine both -- expand routes in the editor, save in setModelData).