ICF 3.1.1.10
Technical documentation of ICF Libraries
TGuiObserverWrap.h
Go to the documentation of this file.
1/********************************************************************************
2** This file is part of the ICF Framework. Copyright (C) Witold Gantzke & Kirill Lepskiy
3** ICF Framework may be used under the terms of the LGPL License v. 2.1 by the Free Software Foundation.
4********************************************************************************/
5
6#ifndef iqtgui_TGuiObserverWrap_included
7#define iqtgui_TGuiObserverWrap_included
8
9
10// Qt includes
11#include <QtCore/QtGlobal>
12#include <QtWidgets/QWidget>
13
14// ICF includes
15#include <imod/IModelEditor.h>
16#include <imod/IModel.h>
17
18
19namespace istdgui
20{
21
22
28template <class Gui, class Observer>
30 public Gui,
31 public Observer,
32 virtual public imod::IModelEditor
33{
34public:
36
37 // pseudo-reimplemented (imod::IObserver)
38 bool OnModelAttached(imod::IModel* modelPtr, istd::IChangeable::ChangeSet& changeMask) override;
39 bool OnModelDetached(imod::IModel* modelPtr) override;
40
41protected:
42 class [[maybe_unused]] UpdateBlocker
43 {
44 public:
45 explicit UpdateBlocker(const TGuiObserverWrap<Gui, Observer>* parentPtr);
46 ~UpdateBlocker();
47
48 private:
49 const TGuiObserverWrap<Gui, Observer>& m_parent;
50 };
51
55 virtual void OnGuiModelShown();
56
60 virtual void OnGuiModelHidden();
61
65 virtual void OnGuiModelAttached();
66
70 virtual void OnGuiModelDetached();
71
75 bool IsUpdateBlocked() const;
76
81 bool DoUpdateModel() const;
82
87 virtual void UpdateModel() const;
88
93 virtual void UpdateGui(const istd::IChangeable::ChangeSet& changeSet);
94
95 // reimplemented (imod::IModelEditor)
96 void UpdateEditor(const istd::IChangeable::ChangeSet& changeSet) override;
97 void UpdateModelFromEditor() const override;
98
99 // pseudo-reimplemented (istdgui::CGuiComponentBase)
100 void OnGuiShown() override;
101 void OnGuiHidden() override;
102 void OnGuiRetranslate() override;
103 void OnGuiCreated() override;
104 void OnGuiDestroyed() override;
105
106 // pseudo-reimplemented (imod::IObserver)
107 void AfterModelChange(imod::IModel* modelPtr, const istd::IChangeable::ChangeSet& changeSet) override;
108
109 // pseudo-reimplemented (imod::IModelEditor)
110 bool IsReadOnly() const override;
111 void SetReadOnly(bool state) override;
112
113protected:
118 void SetDisableUiIfReadOnly(bool state);
119
121
122private:
123 void DoUpdate(const istd::IChangeable::ChangeSet& changeSet);
124
125 bool m_disableUiIfReadOnly;
126 mutable int m_ignoreUpdatesCounter;
127
131 bool m_isUpdatePending;
132
136 istd::IChangeable::ChangeSet m_onShowChangeIds;
137};
138
139
140// public methods
141
142template <class Gui, class Observer>
144: m_isReadOnly(false),
145 m_disableUiIfReadOnly(true),
146 m_ignoreUpdatesCounter(0),
147 m_isUpdatePending(true),
148 m_onShowChangeIds(istd::IChangeable::GetAllChanges())
149{
150}
151
152
153// pseudo-reimplemented (imod::IObserver)
154
155template <class Gui, class Observer>
157{
158 bool retVal = false;
159
160 {
161 UpdateBlocker block(this);
162
163 retVal = Observer::OnModelAttached(modelPtr, changeMask);
164 }
165
166 if (retVal && Gui::IsGuiCreated()){
167 Q_ASSERT(Observer::IsModelAttached(nullptr));
168
169 OnGuiModelAttached();
170 }
171
172 return retVal;
173}
174
175
176template <class Gui, class Observer>
178{
179 if (Observer::IsModelAttached(modelPtr)){
180 if (Gui::IsGuiCreated()){
181 if (!m_isReadOnly && !IsUpdateBlocked() && !m_isUpdatePending){
182 UpdateBlocker updateBlocker(this);
183
184 UpdateModel();
185 }
186
187 OnGuiModelDetached();
188 }
189 }
190
191 return Observer::OnModelDetached(modelPtr);
192}
193
194
195// protected methods
196
197template <class Gui, class Observer>
201
202
203template <class Gui, class Observer>
207
208
209template <class Gui, class Observer>
211{
212 Q_ASSERT(Gui::IsGuiCreated());
213 Q_ASSERT(Observer::IsModelAttached(nullptr));
214
215 static const istd::IChangeable::ChangeSet initChangeSet(CF_INIT_EDITOR);
216 UpdateEditor(initChangeSet);
217}
218
219
220template <class Gui, class Observer>
222{
223 if (!m_isReadOnly && Observer::IsModelAttached(nullptr) && !IsUpdateBlocked() && !m_isUpdatePending){
224 UpdateBlocker updateBlocker(this);
225
226 UpdateModel();
227 }
228}
229
230
231template <class Gui, class Observer>
233{
234 return (m_ignoreUpdatesCounter > 0);
235}
236
237
238template <class Gui, class Observer>
240{
241 m_disableUiIfReadOnly = state;
242}
243
244
245// provate methods
246
247template <class Gui, class Observer>
249{
250 if (!m_isReadOnly && !IsUpdateBlocked() && Observer::IsModelAttached()){
251 UpdateBlocker updateBlocker(this);
252
253 UpdateModel();
254
255 return true;
256 }
257
258 return false;
259}
260
261
262template <class Gui, class Observer>
266
267
268template <class Gui, class Observer>
272
273
274// reimplemented (imod::IModelEditor)
275
276template <class Gui, class Observer>
278{
279 if (Gui::IsGuiShown()){
280 DoUpdate(changeSet);
281 }
282 else{
283 // prepare postponed update
284 m_isUpdatePending = true;
285 m_onShowChangeIds += changeSet;
286 }
287}
288
289
290template <class Gui, class Observer>
292{
293 if (!m_isReadOnly && !m_isUpdatePending){
294 DoUpdateModel();
295 }
296}
297
298
299// pseudo-reimplemented (istdgui::CGuiComponentBase)
300
301template <class Gui, class Observer>
303{
304 Gui::OnGuiShown();
305
306 if (Observer::IsModelAttached(nullptr)){
307 if (m_isUpdatePending){
308 // skip update if the UI is not visible:
309 DoUpdate(m_onShowChangeIds);
310
311 m_onShowChangeIds.Reset();
312
313 m_isUpdatePending = false;
314 }
315
316 OnGuiModelShown();
317 }
318}
319
320
321template <class Gui, class Observer>
323{
324 Gui::OnGuiHidden();
325
326 if (Observer::IsModelAttached(nullptr)){
327 OnGuiModelHidden();
328 }
329}
330
331
332template <class Gui, class Observer>
334{
335 UpdateBlocker updateBlocker(this);
336
337 Gui::OnGuiRetranslate();
338}
339
340
341template <class Gui, class Observer>
343{
344 Gui::OnGuiCreated();
345
346 if (m_disableUiIfReadOnly){
347 QWidget* widgetPtr = Gui::GetWidget();
348 Q_ASSERT(widgetPtr != nullptr);
349
350 widgetPtr->setEnabled(!m_isReadOnly);
351 }
352
353 if (Observer::IsModelAttached(nullptr)){
354 OnGuiModelAttached();
355 }
356}
357
358
359template <class Gui, class Observer>
361{
362 if (Observer::IsModelAttached(nullptr)){
363 OnGuiModelDetached();
364 }
365
366 Gui::OnGuiDestroyed();
367}
368
369
370// pseudo-reimplemented (imod::IObserver)
371
372template <class Gui, class Observer>
374{
375 Q_ASSERT(modelPtr != nullptr);
376 Q_ASSERT(Observer::IsModelAttached(modelPtr));
377
378 Observer::AfterModelChange(modelPtr, changeSet);
379
380 if (!Gui::IsGuiCreated() || changeSet.ContainsExplicit(istd::IChangeable::CF_DESTROYING)){
381 return;
382 }
383
384 Gui::m_updateGuiCaller.DoCall([this, changeSet]() { UpdateEditor(changeSet); });
385}
386
387
388// pseudo-reimplemented (imod::IModelEditor)
389
390template <class Gui, class Observer>
392{
393 return m_isReadOnly;
394}
395
396
397template <class Gui, class Observer>
399{
400 m_isReadOnly = state;
401
402 if (m_disableUiIfReadOnly && Gui::IsGuiCreated()){
403 QWidget* widgetPtr = Gui::GetWidget();
404 Q_ASSERT(widgetPtr != nullptr);
405
406 widgetPtr->setEnabled(!m_isReadOnly);
407 }
408}
409
410
411// private methods
412
413template <class Gui, class Observer>
415{
416 if (changeSet.IsEmpty() || IsUpdateBlocked() || !Gui::IsGuiCreated()){
417 return;
418 }
419
420 UpdateBlocker updateBlocker(this);
421
422 UpdateGui(changeSet);
423}
424
425
426// public methods of embedded class UpdateBlocker
427
428template <class Gui, class Observer>
430: m_parent(*parentPtr)
431{
432 ++m_parent.m_ignoreUpdatesCounter;
433}
434
435
436template <class Gui, class Observer>
438{
439 --m_parent.m_ignoreUpdatesCounter;
440}
441
442
443} // namespace istdgui
444
445
446#endif // !iqtgui_TGuiObserverWrap_included
447
448
Common interface for an model editor.
Common interface for model objects, that supports Model/Observer design pattern.
Definition IModel.h:29
Set of change flags (its IDs).
Definition IChangeable.h:38
bool IsEmpty() const
Check if there is any change in the set.
bool ContainsExplicit(int changeId, bool singleOnly=false) const
Check if there is specific change flag in the set explicit set by user.
@ CF_DESTROYING
Change flag indicate that model is during destruction.
UpdateBlocker(const TGuiObserverWrap< Gui, Observer > *parentPtr)
Join functionality of istdgui::IGuiObject interface and imod::IObserver.
virtual void OnGuiModelHidden()
Called when model is detached or GUI is hidden.
virtual void OnGuiModelDetached()
Called when model is detached or GUI is destroyed.
void UpdateEditor(const istd::IChangeable::ChangeSet &changeSet) override
Updates editor with model data.
virtual void UpdateGui(const istd::IChangeable::ChangeSet &changeSet)
Do update of the GUI to reflect the state of model.
bool OnModelAttached(imod::IModel *modelPtr, istd::IChangeable::ChangeSet &changeMask) override
bool OnModelDetached(imod::IModel *modelPtr) override
void SetReadOnly(bool state) override
Set flag that the model data can be changed.
virtual void UpdateModel() const
Do update of the model to reflect the current contents of GUI.
void UpdateModelFromEditor() const override
Updates model from editor.
bool IsReadOnly() const override
Returns true if the model data can be changed.
virtual void OnGuiModelShown()
Called when model is attached and GUI is shown.
virtual void OnGuiModelAttached()
Called when model is attached and GUI is created.
void AfterModelChange(imod::IModel *modelPtr, const istd::IChangeable::ChangeSet &changeSet) override
bool DoUpdateModel() const
Secure update model.
void SetDisableUiIfReadOnly(bool state)
Control if GUI should be disaled for read-only editors.
bool IsUpdateBlocked() const
Check if GUI updating is blocked.
Standard library.
Definition IComponent.h:17
Standard GUI specific interfaces and components based on Qt.

© Witold Gantzke and Kirill Lepskiy