Hi Jaco,
Thanks for the detailed reply, it's got my mental juices going. I've replied inline.
I understand that by implementing it as an IContext some of your other helpers can take advantage of that (e.g. if you register that object in the object pool in automatically registers the context), but it's not strictly necessary to achieve the task since the context is just a string right? I can just register a context in the c'tor of my tab as you are doing there... From what I can see IContext provides contextHelpId() and a pure virtual contextString(). If I inherit IContext do I get any other benifits? I assume the debugger would still display my context if I were to register my context manually.
I'm asking this because I'm not sure I like that idea that everything ends up in this global object pool where everything is accessible from everywhere... I'm concerned it will make things very easy to use, but hard to maintain. e.g. Joe doing the database side can grab out pretty much any widget and change it's settings... data encapsulation etc. Essentially that you can stop designing your product because everything gets thrown in the pool... what are your feelings on this?
Don't get me wrong - I think it's great to have, it enables me to grab out actions from anywhere, but I'm not really in favour with EVERYTHING ending up in there. I guess one solution is just to have an internal (private) class which inheirts IContext which is added to the pool. It would still be deleted when the object is deleted but wouldn't make the tab accessible from anywhere...
>
> 3) Creation of backed actions:
>
> When you construct your backend actions in the editor tab, you do something like this:
>
> // Get the context ID for this widget:
>
> int context_id = CONTEXT_MANAGER->registerContext(d->global_meta_type);
>
> QList<int> context;
>
> context.push_front(context_id);
>
>
The global_meta_type part went over my head. I assume that's a member variable from whatever code you pulled this from - why are we registering another context? Don't we need to do this: int context_id = CONTEXT_MANAGER->contextID(d->tab_context) ?
> And then register your actions like this:
>
> QAction* actionInsertTable = new QAction(QIcon(),tr("Table"),this);
> connect(actionInsertTable,SIGNAL(triggered()),SLOT(handleActionInsertTable()));
> ACTION_MANAGER->registerAction(constant_insert_table_id,d->actionInsertTable,context);
>
> Qtilities will find the correct placeholder proxy action and add this new action it as an backend action for it.
>
> 4) Controlling the active context:
>
> When your editor tab gets its focus you need to set the active context in the context manager. This will cause the correct backend action to be triggered when the proxy action is triggered.
>
> Its easy to do, in your FocusIn event do this:
>
> CONTEXT_MANAGER->setNewContext(contextString(),true);
>
> And in your FocusOut event do this:
>
> // Remove the context from the set of active contexts.
> CONTEXT_MANAGER->removeContext(contextString());
>
A couple of things about doing it in FocusIn/Out:
1) It would have to be on the QTextEdit rather than the tab as the tab itself doesn't get focus.
2) When they click a menu item the QTextEdit loses focus, so it would remove that context and the action would essentially be disconnected right? It definitely loses focus, I tested this. I would need to set that context whenever the tab switches.
3) Wouldn't I want to append this context rather than set it? Wouldn't I want a scheme where I have the active contexts:
Editing
Editing.Document123
and then
Editing
Editing.Document987
For example, I would attach that Editing context to the Insert->Table so that if we're not editing (lets say you've got the contexts Browsing and Browsing.Document123 active) it disables that menu option.