1 #ifndef FORM_EDITOR_PROPERTIES__PROPERTIES_EDITOR_H
2 #define FORM_EDITOR_PROPERTIES__PROPERTIES_EDITOR_H
3 
4 #include "Property.h"
5 #include "PropertyCaller.h"
6 #include <ExpandFrame/ExpandFrame.h>
7 #include <FormEditorCommon/FormEditorCommon.h>
8 
9 #define LAYOUTFILE <FormEditorProperties/FormEditorProperties.lay>
10 #include <CtrlCore/lay.h>
11 
12 template <class T>
13 class PropertiesWindowBase : public WithPropertiesLayout<TopWindow>
14 {
15 	typedef PropertiesWindowBase CLASSNAME;
16 
17 protected:
GetProperties()18 	T* GetProperties() { return _Properties; }
19 	virtual void Cancel();
20 	virtual void Load();
21 	virtual void Save();
22 
23 public:
24 	PropertiesWindowBase(T* p);
25 	virtual ~PropertiesWindowBase();
GetObjectWidgetClass()26 	virtual String GetObjectWidgetClass() const { return String(); }
27 	virtual int Execute();
28 
29 private:
30 	T* _Properties;
31 	Array<StaticRect> _Panes;
32 };
33 
34 template <class T>
PropertiesWindowBase(T * p)35 PropertiesWindowBase<T>::PropertiesWindowBase(T* p)
36 {
37 	CtrlLayoutOKCancel(*this, t_("Properties"));
38 	ToolWindow().Sizeable();
39 	_Properties = p;
40 	_Properties->InitProperties();
41 	Load();
42 }
43 
44 template <class T>
~PropertiesWindowBase()45 PropertiesWindowBase<T>::~PropertiesWindowBase()
46 {
47 	_Properties->ClearProperties();
48 }
49 
50 template <class T>
Execute()51 int PropertiesWindowBase<T>::Execute()
52 {
53 	if (!_Properties->GetProperties().GetCount())
54 	{
55 		PromptOK(t_("No properties for object!"));
56 		return IDCANCEL;
57 	}
58 	int r = WithPropertiesLayout<TopWindow>::Execute();
59 	r == IDOK ? Save() : Cancel();
60 	return r;
61 }
62 
63 template <class T>
Load()64 void PropertiesWindowBase<T>::Load()
65 {
66 	Vector<String> groups = _Properties->GetPropertiesGroups();
67 	propGroups.Clear();
68 	_Panes.Clear();
69 
70 	for (int i = 0; i < groups.GetCount(); ++i)
71 	{
72 		if (groups[i].IsEmpty())
73 			groups[i] = t_("Others");
74 		Array<Property*> gProps = _Properties->GetPropertiesByGroup(groups[i]);
75 		StaticRect& pane = _Panes.Add();
76 		int paneCY = 10;
77 		for (int j = 0; j < gProps.GetCount(); ++j)
78 		{
79 			gProps[j]->ToPane(pane, paneCY, 5);
80 		}
81 		paneCY += 15;
82 		propGroups.AddExpander(pane, true, paneCY).SetTitle(groups[i]);
83 	}
84 }
85 
86 template <class T>
Save()87 void PropertiesWindowBase<T>::Save()
88 {
89 	Array<Property>& props = _Properties->GetProperties();
90 	for (int i = 0; i < props.GetCount(); ++i)
91 		if (props[i].IsChanged())
92 			props[i].Apply();
93 	Break();
94 }
95 
96 template <class T>
Cancel()97 void PropertiesWindowBase<T>::Cancel()
98 {
99 	Array<Property>& props = _Properties->GetProperties();
100 	for (int i = 0; i < props.GetCount(); ++i)
101 		if (props[i].IsChanged())
102 			props[i].Restore();
103 	Break();
104 }
105 
106 template <class T>
107 class PropertiesWindowHistory
108 {
109 	class HChangeProperty : public IHistoryItem
110 	{
111 		String _Name;
112 		Value _Last;
113 		Value _Next;
114 		int _Prop;
115 		T* _Ptr;
116 
117 	public:
HChangeProperty(T * obj,String name,int prop,Value last,Value v)118 		HChangeProperty(T* obj, String name, int prop, Value last, Value v)
119 			: _Ptr(obj), _Name(name), _Prop(prop), _Last(last), _Next(v) {}
~HChangeProperty()120 		virtual ~HChangeProperty() {}
121 
122 		virtual String GetDesc() const;
123 		virtual void   Undo();
124 		virtual void   Do();
125 	};
126 
127 public:
PropertiesWindowHistory(T * p)128 	PropertiesWindowHistory(T* p) : _Properties(p) {}
129 
130 private:
131 	T* _Properties;
132 
133 protected:
134 	virtual void Save();
135 };
136 
137 template <class T>
Save()138 void PropertiesWindowHistory<T>::Save()
139 {
140 	Array<Property>& props = _Properties->GetProperties();
141 	for (int i = 0; i < props.GetCount(); ++i)
142 		if (props[i].IsChanged())
143 		{
144 			T* c = _Properties->GetObject();
145 			if (!c) continue;
146 			Value v;
147 			props[i].Get(v, Vector<Value>());
148 			c->AddToHistory(new HChangeProperty(c, props[i].MetaString("Name"),
149 				i, props[i].GetLast(), v));
150 		}
151 }
152 
153 // History: Property changes
154 template <class T>
Do()155 void PropertiesWindowHistory<T>::HChangeProperty::Do()
156 {
157 	if (!_Ptr) return;
158 	_Ptr->InitProperties();
159 	Property& prop = _Ptr->GetProperties()[_Prop];
160 	prop.Set(Vector<Value>() << _Next);
161 	_Ptr->ClearProperties();
162 }
163 
164 template <class T>
Undo()165 void PropertiesWindowHistory<T>::HChangeProperty::Undo()
166 {
167 	if (!_Ptr) return;
168 	_Ptr->InitProperties();
169 	Property& prop = _Ptr->GetProperties()[_Prop];
170 	prop.Set(Vector<Value>() << _Last);
171 	_Ptr->ClearProperties();
172 }
173 
174 template <class T>
GetDesc()175 String PropertiesWindowHistory<T>::HChangeProperty::GetDesc() const
176 {
177 	if (!_Ptr) return String(t_("Unable to change the property: NULL-pointer."));
178 	return NFormat(t_("Property of the object (type \"%s\"), named \"%s\", changed to: \"%s\""),
179 		_Ptr->GetObjectWidgetClass(), _Name, _Next.ToString());
180 }
181 
182 template <class T>
183 class PropertiesWindow : public PropertiesWindowBase<T>, public PropertiesWindowHistory<T>
184 {
185 public:
PropertiesWindow(T * p)186 	PropertiesWindow(T* p) : PropertiesWindowBase<T>(p), PropertiesWindowHistory<T>(p)
187 		{ _useHistory = false; }
~PropertiesWindow()188 	virtual ~PropertiesWindow() {}
189 
Save()190 	virtual void Save()
191 	{
192 		PropertiesWindowBase<T>::Save();
193 
194 		if (_useHistory)
195 			PropertiesWindowHistory<T>::Save();
196 	}
197 
198 	bool UseHistory(bool flag = true) { _useHistory = flag; }
199 
200 private:
201 	bool _useHistory;
202 };
203 
204 #endif
205