ACF $AcfVersion:0$
TGuiObserverWrap.h
Go to the documentation of this file.
1// SPDX-License-Identifier: LGPL-2.1-or-later OR GPL-2.0-or-later OR GPL-3.0-or-later OR LicenseRef-ACF-Commercial
2#pragma once
3
4
5// Qt includes
6#include <QtCore/QtGlobal>
7#if QT_VERSION >= 0x050000
8#include <QtWidgets/QWidget>
9#else
10#include <QtGui/QWidget>
11#endif
12
13// ACF includes
14#include <imod/IModelEditor.h>
15#include <imod/IModel.h>
16
17
18namespace iqtgui
19{
20
21
27template <class Gui, class Observer>
29 public Gui,
30 public Observer,
31 virtual public imod::IModelEditor
32{
33public:
35
36 // pseudo-reimplemented (imod::IObserver)
37 virtual bool OnModelAttached(imod::IModel* modelPtr, istd::IChangeable::ChangeSet& changeMask) override;
38 virtual bool OnModelDetached(imod::IModel* modelPtr) override;
39
40protected:
42 {
43 public:
44 explicit UpdateBlocker(const TGuiObserverWrap<Gui, Observer>* parentPtr);
46
47 private:
48 const TGuiObserverWrap<Gui, Observer>& m_parent;
49 };
50
54 virtual void OnGuiModelShown();
55
59 virtual void OnGuiModelHidden();
60
64 virtual void OnGuiModelAttached();
65
69 virtual void OnGuiModelDetached();
70
74 bool IsUpdateBlocked() const;
75
80 bool DoUpdateModel() const;
81
86 virtual void UpdateModel() const;
87
92 virtual void UpdateGui(const istd::IChangeable::ChangeSet& changeSet);
93
94 // reimplemented (imod::IModelEditor)
95 virtual void UpdateEditor(const istd::IChangeable::ChangeSet& changeSet) override;
96 virtual void UpdateModelFromEditor() const override;
97
98 // pseudo-reimplemented (iqtgui::CGuiComponentBase)
99 virtual void OnGuiShown() override;
100 virtual void OnGuiHidden() override;
101 virtual void OnGuiRetranslate() override;
102 virtual void OnGuiCreated() override;
103 virtual void OnGuiDestroyed() override;
104
105 // pseudo-reimplemented (imod::IObserver)
106 virtual void AfterUpdate(imod::IModel* modelPtr, const istd::IChangeable::ChangeSet& changeSet) override;
107
108 // pseudo-reimplemented (imod::IModelEditor)
109 virtual bool IsReadOnly() const override;
110 virtual void SetReadOnly(bool state) override;
111
112protected:
117 void SetDisableUiIfReadOnly(bool state);
118
120
121private:
122 void DoUpdate(const istd::IChangeable::ChangeSet& changeSet);
123
124private:
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(false),
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(NULL));
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 Q_UNUSED(updateBlocker);
184
185 UpdateModel();
186 }
187
188 OnGuiModelDetached();
189 }
190 }
191
192 return Observer::OnModelDetached(modelPtr);
193}
194
195
196// protected methods
197
198template <class Gui, class Observer>
202
203
204template <class Gui, class Observer>
208
209
210template <class Gui, class Observer>
212{
213 Q_ASSERT(Gui::IsGuiCreated());
214 Q_ASSERT(Observer::IsModelAttached(NULL));
215
216 static const istd::IChangeable::ChangeSet initChangeSet(CF_INIT_EDITOR);
217 UpdateEditor(initChangeSet);
218}
219
220
221template <class Gui, class Observer>
223{
224 if (!m_isReadOnly && Observer::IsModelAttached(NULL) && !IsUpdateBlocked() && !m_isUpdatePending){
225 UpdateBlocker updateBlocker(this);
226 Q_UNUSED(updateBlocker);
227
228 UpdateModel();
229 }
230}
231
232
233template <class Gui, class Observer>
235{
236 return (m_ignoreUpdatesCounter > 0);
237}
238
239
240template <class Gui, class Observer>
242{
243 m_disableUiIfReadOnly = state;
244}
245
246
247// provate methods
248
249template <class Gui, class Observer>
251{
252 if (!m_isReadOnly && !IsUpdateBlocked() && Observer::IsModelAttached()){
253 UpdateBlocker updateBlocker(this);
254 Q_UNUSED(updateBlocker);
255
256 UpdateModel();
257
258 return true;
259 }
260
261 return false;
262}
263
264
265template <class Gui, class Observer>
269
270
271template <class Gui, class Observer>
275
276
277// reimplemented (imod::IModelEditor)
278
279template <class Gui, class Observer>
281{
282 if (Gui::IsGuiShown()){
283 DoUpdate(changeSet);
284 }
285 else{
286 // prepare postponed update
287 m_isUpdatePending = true;
288 m_onShowChangeIds += changeSet;
289 }
290}
291
292
293template <class Gui, class Observer>
295{
296 if (!m_isReadOnly && !m_isUpdatePending){
297 DoUpdateModel();
298 }
299}
300
301
302// pseudo-reimplemented (iqtgui::CGuiComponentBase)
303
304template <class Gui, class Observer>
306{
307 Gui::OnGuiShown();
308
309 if (Observer::IsModelAttached(NULL)){
310 if (m_isUpdatePending){
311 // skip update if the UI is not visible:
312 DoUpdate(m_onShowChangeIds);
313
314 m_onShowChangeIds.Reset();
315
316 m_isUpdatePending = false;
317 }
318
319 OnGuiModelShown();
320 }
321}
322
323
324template <class Gui, class Observer>
326{
327 Gui::OnGuiHidden();
328
329 if (Observer::IsModelAttached(NULL)){
330 OnGuiModelHidden();
331 }
332}
333
334
335template <class Gui, class Observer>
337{
338 UpdateBlocker updateBlocker(this);
339 Q_UNUSED(updateBlocker);
340
341 Gui::OnGuiRetranslate();
342}
343
344
345template <class Gui, class Observer>
347{
348 Gui::OnGuiCreated();
349
350 if (m_disableUiIfReadOnly){
351 QWidget* widgetPtr = Gui::GetWidget();
352 Q_ASSERT(widgetPtr != NULL);
353
354 widgetPtr->setEnabled(!m_isReadOnly);
355 }
356
357 if (Observer::IsModelAttached(NULL)){
358 OnGuiModelAttached();
359 }
360}
361
362
363template <class Gui, class Observer>
365{
366 if (Observer::IsModelAttached(NULL)){
367 OnGuiModelDetached();
368 }
369
370 Gui::OnGuiDestroyed();
371}
372
373
374// pseudo-reimplemented (imod::IObserver)
375
376template <class Gui, class Observer>
378{
379 Q_ASSERT(modelPtr != NULL);
380 Q_ASSERT(Observer::IsModelAttached(modelPtr));
381
382 Observer::AfterUpdate(modelPtr, changeSet);
383
384 if (!Gui::IsGuiCreated() || changeSet.ContainsExplicit(istd::IChangeable::CF_DESTROYING)){
385 return;
386 }
387
388 UpdateEditor(changeSet);
389}
390
391
392// pseudo-reimplemented (imod::IModelEditor)
393
394template <class Gui, class Observer>
396{
397 return m_isReadOnly;
398}
399
400
401template <class Gui, class Observer>
403{
404 m_isReadOnly = state;
405
406 if (m_disableUiIfReadOnly && Gui::IsGuiCreated()){
407 QWidget* widgetPtr = Gui::GetWidget();
408 Q_ASSERT(widgetPtr != NULL);
409
410 widgetPtr->setEnabled(!m_isReadOnly);
411 }
412}
413
414
415// private methods
416
417template <class Gui, class Observer>
419{
420 if (changeSet.IsEmpty() || IsUpdateBlocked() || !Gui::IsGuiCreated()){
421 return;
422 }
423
424 UpdateBlocker updateBlocker(this);
425 Q_UNUSED(updateBlocker);
426
427 UpdateGui(changeSet);
428}
429
430
431// public methods of embedded class UpdateBlocker
432
433template <class Gui, class Observer>
435: m_parent(*parentPtr)
436{
437 ++m_parent.m_ignoreUpdatesCounter;
438}
439
440
441template <class Gui, class Observer>
443{
444 --m_parent.m_ignoreUpdatesCounter;
445}
446
447
448} // namespace iqtgui
449
450
451
452
Common interface for an model editor.
Common interface for model objects, that supports Model/Observer design pattern.
Definition IModel.h:25
UpdateBlocker(const TGuiObserverWrap< Gui, Observer > *parentPtr)
Join functionality of iqtgui::IGuiObject interface and imod::IObserver.
virtual void SetReadOnly(bool state) override
Set flag that the model data can be changed.
bool DoUpdateModel() const
Secure update model.
virtual void OnGuiShown() override
virtual void UpdateModelFromEditor() const override
Updates model from editor.
virtual bool OnModelAttached(imod::IModel *modelPtr, istd::IChangeable::ChangeSet &changeMask) override
virtual void OnGuiCreated() override
virtual bool IsReadOnly() const override
Returns true if the model data can be changed.
virtual void OnGuiHidden() override
virtual void OnGuiDestroyed() override
virtual void UpdateModel() const
Do update of the model to reflect the current contents of GUI.
void SetDisableUiIfReadOnly(bool state)
Control if GUI should be disaled for read-only editors.
virtual void UpdateGui(const istd::IChangeable::ChangeSet &changeSet)
Do update of the GUI to reflect the state of model.
virtual void UpdateEditor(const istd::IChangeable::ChangeSet &changeSet) override
Updates editor with model data.
virtual void OnGuiModelDetached()
Called when model is detached or GUI is destroyed.
virtual void OnGuiModelShown()
Called when model is attached and GUI is shown.
virtual void AfterUpdate(imod::IModel *modelPtr, const istd::IChangeable::ChangeSet &changeSet) override
bool IsUpdateBlocked() const
Check if GUI updating is blocked.
virtual void OnGuiRetranslate() override
virtual bool OnModelDetached(imod::IModel *modelPtr) override
virtual void OnGuiModelHidden()
Called when model is detached or GUI is hidden.
virtual void OnGuiModelAttached()
Called when model is attached and GUI is created.
Set of change flags (its IDs).
Definition IChangeable.h:36
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.
#define NULL
Definition istd.h:74
Standard GUI specific interfaces and components based on Qt.
Standard library.
Definition IComponent.h:17