[scribus-dev] The handleSelectionChanged() thing again
Elvis Stansvik
elvstone at gmail.com
Tue Jul 12 11:48:52 UTC 2011
2011/7/12 Andreas Vox <andreas.vox at googlemail.com>:
>
>
>> -----Ursprüngliche Nachricht-----
>> Von: Elvis Stansvik [mailto:elvstone at gmail.com]
>> Gesendet: Dienstag, 12. Juli 2011 10:59
>> An: Scribus Development Mailing List
>> Betreff: Re: [scribus-dev] The handleSelectionChanged() thing again
>>
>> 2011/7/12 Elvis Stansvik <elvstone at gmail.com>:
>> > Good morning,
>>
>> <snip>
>>
>> > This is what I'm trying to work around now in the best way possible.
>>
>> I guess that the best solution right now would be something like
>>
>> PropertiesPalette_Table::startEdit() { m_inEdit = true; }
>> PropertiesPalette_Table::endEdit() { m_inEdit = false; }
>> PropertiesPalette_Table::inEdit() { return m_inEdit; }
>> PropertiesPalette_Table::handleSelectionChanged()
>> {
>> if (inEdit())
>> return;
>> // Update all controls et.c.
>> }
>> PropertiesPalette_Table::handleSomePropertyChange()
>> {
>> startEdit();
>> m_item->setSomeProperty();
>> m_item->update();
>> endEdit();
>> }
>>
>> But is update() blocking enough for that or could endEdit() possibly
>> be called before handleSelectionChanged()?
>
> I usually use a similar pattern when dealing with this situation:
>
> private bool withinUpdate = false;
>
> // event from Qt:
> public void valueChanged(...)
> {
> try {
> withinUpdate = true;
> document->setNewValue(...);
> }
> finally {
> withinUpdate = false;
> }
> }
>
> // event from our model:
> public void changed(...)
> {
> if (!withinUpdate)
> ...
> }
Ah. Good idea with the try/catch construct. I guess another approach
would be to use RAII and define an inner class to
PropertiesPalette_Table, like:
private bool withinUpdate = false;
class ChangeBlocker()
{
public:
ChangeBlocker(PropertiesPalette_Table *parent) : m_parent(parent)
{
m_parent->withinUpdate = true;
}
~ChangeBlocker()
{
m_parent->withinUpdate = false;
}
private:
PropertiesPalette_Table *m_parent;
};
The handler for event from Qt would then be reduced to
// event from Qt:
public void valueChanged(...)
{
ChangeBlocker blocker(this);
document->setNewValue(...);
}
(untested)
But now that I wrote that down I think your try/catch is prettier and
more explicit ;)
> I view the event chain from model -> UI as very important(*), so I'm
> hesitant to turn off all signals. So I just protect sections where UI code
> changes the model data by "withinUpdate = true" and ignore any events that
> come from the model during that time. That ensures other parts of Scribus
> still get the events and only the critical loop is broken.
Yep.
> (*) Having a robust mechanism that updates the view each time the model
> changes goes a long way to implement the model/view/controller pattern. Even
> if it seems round-about that the UI first sends the data to the model and
> then updates itself from the model, this architecture is very sound and
> makes developing and testing much easier. The resulting UI is also more
> stable and resilient to errors this way.
All valid points. I stand corrected!
Elvis
More information about the scribus-dev
mailing list