1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 // wxFormBuilder - A Visual Dialog Editor for wxWidgets.
4 // Copyright (C) 2005 José Antonio Hurtado
5 //
6 // This program is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU General Public License
8 // as published by the Free Software Foundation; either version 2
9 // of the License, or (at your option) any later version.
10 //
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19 //
20 // Written by
21 //   José Antonio Hurtado - joseantonio.hurtado@gmail.com
22 //   Juan Antonio Ortega  - jortegalalmolda@gmail.com
23 //
24 ///////////////////////////////////////////////////////////////////////////////
25 
26 #ifndef __APP_DATA__
27 #define __APP_DATA__
28 
29 #include "utils/wxfbdefs.h"
30 #include "model/database.h"
31 #include "rad/cmdproc.h"
32 #include <set>
33 
34 namespace ticpp
35 {
36 
37 class Node;
38 
39 class Element;
40 }
41 
42 class Property;
43 
44 class wxFBEvent;
45 
46 class wxFBManager;
47 
48 class wxFBIPC;
49 
50 #define AppData()         	(ApplicationData::Get())
51 #define AppDataCreate(path) (ApplicationData::Get(path))
52 #define AppDataInit()	      (ApplicationData::Initialize())
53 #define AppDataDestroy()  	(ApplicationData::Destroy())
54 
55 // This class is a singleton class.
56 
57 class ApplicationData
58 {
59 
60 	private:
61 
62 		static ApplicationData *s_instance;
63 
64 		wxString m_rootDir;       // directorio raíz (mismo que el ejecutable)
65 
66 		bool m_modFlag;           // flag de proyecto modificado
67 
68 		bool m_warnOnAdditionsUpdate;	// flag to warn on additions update / class renames
69 
70 		PObjectDatabase m_objDb;  // Base de datos de objetos
71 
72 		PObjectBase m_project;    // Proyecto
73 
74 		PObjectBase m_selObj;     // Objeto seleccionado
75 
76 		PObjectBase m_clipboard;
77 
78 		bool m_copyOnPaste; // flag que indica si hay que copiar el objeto al pegar
79 
80 		// Procesador de comandos Undo/Redo
81 		CommandProcessor m_cmdProc;
82 
83 		wxString m_projectFile;
84 
85 		wxString m_projectPath;
86 
87 		PwxFBManager m_manager;
88 
89 		// Prevent more than one instance of a project
90 		boost::shared_ptr< wxFBIPC > m_ipc;
91 
92 
93 		typedef std::vector< wxEvtHandler* > HandlerVector;
94 
95 		HandlerVector m_handlers;
96 
97 		void NotifyEvent( wxFBEvent& event, bool forcedelayed = false );
98 
99 		// Notifican a cada observador el evento correspondiente
100 		void NotifyProjectLoaded();
101 
102 		void NotifyProjectSaved();
103 
104 		void NotifyObjectExpanded( PObjectBase obj );
105 
106 		void NotifyObjectSelected( PObjectBase obj, bool force = false );
107 
108 		void NotifyObjectCreated( PObjectBase obj );
109 
110 		void NotifyObjectRemoved( PObjectBase obj );
111 
112 		void NotifyPropertyModified( PProperty prop );
113 
114 		void NotifyEventHandlerModified( PEvent evtHandler );
115 
116 		void NotifyProjectRefresh();
117 
118 		void NotifyCodeGeneration( bool panelOnly = false, bool forcedelayed = false );
119 
120 		/**
121 		 * Comprueba las referencias cruzadas de todos los nodos del árbol
122 		 */
123 		void CheckProjectTree( PObjectBase obj );
124 
125 		/**
126 		 * Resuelve un posible conflicto de nombres.
127 		 * @note el objeto a comprobar debe estar insertado en proyecto, por tanto
128 		 *       no es válida para arboles "flotantes".
129 		 */
130 		void ResolveNameConflict( PObjectBase obj );
131 
132 		/**
133 		 * Rename all objects that have the same name than any object of a subtree.
134 		 */
135 		void ResolveSubtreeNameConflicts( PObjectBase obj, PObjectBase topObj = PObjectBase() );
136 
137 		/**
138 		 * Rutina auxiliar de ResolveNameConflict
139 		 */
140 		void BuildNameSet( PObjectBase obj, PObjectBase top, std::set<wxString> &name_set );
141 
142 		/**
143 		 * Calcula la posición donde deberá ser insertado el objeto.
144 		 *
145 		 * Dado un objeto "padre" y un objeto "seleccionado", esta rutina calcula la
146 		 * posición de inserción de un objeto debajo de "parent" de forma que el objeto
147 		 * quede a continuación del objeto "seleccionado".
148 		 *
149 		 * El algoritmo consiste ir subiendo en el arbol desde el objeto "selected"
150 		 * hasta encontrar un objeto cuyo padre sea el mismo que "parent" en cuyo
151 		 * caso se toma la posición siguiente a ese objeto.
152 		 *
153 		 * @param parent objeto "padre"
154 		 * @param selected objeto "seleccionado".
155 		 * @return posición de insercción (-1 si no se puede insertar).
156 		 */
157 		int CalcPositionOfInsertion( PObjectBase selected, PObjectBase parent );
158 
159 
160 		/**
161 		 * Elimina aquellos items que no contengan hijos.
162 		 *
163 		 * Esta rutina se utiliza cuando el árbol que se carga de un fichero
164 		 * no está bien formado, o la importación no ha sido correcta.
165 		 */
166 		void RemoveEmptyItems( PObjectBase obj );
167 
168 		/**
169 		 * Eliminar un objeto.
170 		 */
171 		void DoRemoveObject( PObjectBase object, bool cutObject );
172 
173 		void Execute( PCommand cmd );
174 
175 		/**
176 		 * Search a size in the hierarchy of an object
177 		 */
178 		PObjectBase SearchSizerInto( PObjectBase obj );
179 
180 
181 		/**
182 		Convert the properties of the project element. Handle this separately because it does not repeat.
183 		@param project The project element.
184 		@param path The path to the project file.
185 		@param fileMajor The major revision of the file.
186 		@param fileMinor The minor revision of the file.
187 		*/
188 		void ConvertProjectProperties( ticpp::Element* project, const wxString& path, int fileMajor, int fileMinor );
189 
190 		/**
191 		Iterates through 'property' element children of @a parent.
192 		Saves all properties with a 'name' attribute matching one of @a names into @a properties
193 		@param parent Object element with child properties.
194 		@param names Set of property names to search for.
195 		@param properties Pointer to a set in which to store the result of the search.
196 		*/
197 		void GetPropertiesToConvert( ticpp::Node* parent, const std::set< std::string >& names, std::set< ticpp::Element* >* properties );
198 
199 		/**
200 		Iterates through 'property' element children of @a parent.
201 		Removes all properties with a 'name' attribute matching one of @a names
202 		@param parent Object element with child properties.
203 		@param names Set of property names to search for.
204 		*/
205 		void RemoveProperties( ticpp::Node* parent, const std::set< std::string >& names );
206 
207 		/**
208 		Transfers @a options from the text of @a prop to the text of @a newPropName, which will be created if it doesn't exist.
209 		@param prop Property containing the options to transfer.
210 		@param options Set of options to search for and transfer.
211 		@param newPropName Name of property to transfer to, will be created if non-existant.
212 		*/
213 		void TransferOptionList( ticpp::Element* prop, std::set< wxString >* options, const std::string& newPropName );
214 
215 		void PropagateExpansion(PObjectBase obj, bool expand, bool up);
216 
217 		// hiden constructor
218 		ApplicationData( const wxString &rootdir = wxT( "." ) );
219 
220 		/**
221 		 * Helper for GetOutputPath and GetEmbeddedFilesOutputPath
222 		 */
223 		wxString GetPathProperty( const wxString& pathName );
224 
225 		#ifdef __WXFB_DEBUG__
226 		wxLog* m_debugLogTarget;
227 		#endif
228 
229 		typedef std::map< std::string, std::set< std::string > > PropertiesToRemove;
230 		PropertiesToRemove& GetPropertiesToRemove_v1_12( void ) const;
231 
232 	public:
233 
234 		~ApplicationData();
235 
236 		#ifdef __WXFB_DEBUG__
GetDebugLogTarget()237 		wxLog* GetDebugLogTarget(){ return m_debugLogTarget; }
238 		#endif
239 
240 		static ApplicationData* Get( const wxString &rootdir = wxT( "." ) );
241 
242 		// Force the static AppData instance to Init()
243 		static void Initialize();
244 
245 		static void Destroy();
246 
247 		// Initialize application
248 		void LoadApp();
249 
250 		// Hold a pointer to the wxFBManager
251 		PwxFBManager GetManager();
252 
253 		// Procedures for register/unregister wxEvtHandlers to be notified of wxFBEvents
254 		void AddHandler( wxEvtHandler* handler );
255 
256 		void RemoveHandler( wxEvtHandler* handler );
257 
258 		// Operaciones sobre los datos
259 		bool LoadProject( const wxString &file, bool checkSingleInstance = true );
260 
261 		void SaveProject( const wxString &filename );
262 
263 		void NewProject();
264 
265 		/**
266 		Convert a project from an older version.
267 		@param path The path to the project file
268 		@param fileMajor The major revision of the file
269 		@param fileMinor The minor revision of the file
270 		@return true if successful, false otherwise
271 		*/
272 		bool ConvertProject( const wxString& path, int fileMajor, int fileMinor );
273 
274 		/**
275 		Recursive function used to convert the object tree in the project file to the latest version.
276 		@param object A pointer to the object element
277 		@param fileMajor The major revision of the file
278 		@param fileMinor The minor revision of the file
279 		*/
280 		void ConvertObject( ticpp::Element* object, int fileMajor, int fileMinor );
281 
282 		void ExpandObject( PObjectBase obj, bool expand );
283 
284 		void DetermineObjectToSelect( PObjectBase parent, unsigned int pos );
285 
286 		// Object will not be selected if it already is selected, unless force = true
287 		// Returns true if selection changed, false if already selected
288 		bool SelectObject( PObjectBase obj, bool force = false, bool notify = true );
289 
290 		void CreateObject( wxString name );
291 
292 		void RemoveObject( PObjectBase obj );
293 
294 		void CutObject( PObjectBase obj );
295 
296 		void CopyObject( PObjectBase obj );
297 
298 		bool PasteObject( PObjectBase parent, PObjectBase objToPaste = PObjectBase() );
299 
300 		void CopyObjectToClipboard( PObjectBase obj );
301 
302 		bool PasteObjectFromClipboard( PObjectBase parent );
303 
304 		void InsertObject( PObjectBase obj, PObjectBase parent );
305 
306 		void MergeProject( PObjectBase project );
307 
308 		void ModifyProperty( PProperty prop, wxString value );
309 
310 		void ModifyEventHandler( PEvent evt, wxString value );
311 
312 		void GenerateCode( bool projectOnly = false );
313 
314 		void GenerateInheritedClass( PObjectBase form, wxString className, wxString path, wxString file );
315 
316 		void MovePosition( PObjectBase, bool right, unsigned int num = 1 );
317 
318 		void MoveHierarchy( PObjectBase obj, bool up );
319 
320 		void Undo();
321 
322 		void Redo();
323 
324 		void ToggleExpandLayout( PObjectBase obj );
325 
326 		void ToggleStretchLayout( PObjectBase obj );
327 
328 		void ChangeAlignment ( PObjectBase obj, int align, bool vertical );
329 
330 		void ToggleBorderFlag( PObjectBase obj, int border );
331 
332 		void CreateBoxSizerWithObject( PObjectBase obj );
333 
334 		void ShowXrcPreview();
335 
336 		// Servicios para los observadores
337 		PObjectBase GetSelectedObject();
338 
339 		PObjectBase GetProjectData();
340 
341 		PObjectBase GetSelectedForm();
342 
CanUndo()343 		bool CanUndo() { return m_cmdProc.CanUndo(); }
344 
CanRedo()345 		bool CanRedo() { return m_cmdProc.CanRedo(); }
346 
347 		bool GetLayoutSettings( PObjectBase obj, int *flag, int *option, int *border, int* orient );
348 		bool CanPasteObject();
349 		bool CanPasteObjectFromClipboard();
350 		bool CanCopyObject();
351 		bool IsModified();
352 
GetPackage(unsigned int idx)353 		PObjectPackage GetPackage( unsigned int idx )
354 		{ return m_objDb->GetPackage( idx );}
355 
GetPackageCount()356 		unsigned int GetPackageCount()
357 		{ return m_objDb->GetPackageCount(); }
358 
GetObjectDatabase()359 		PObjectDatabase GetObjectDatabase()
360 		{ return m_objDb; }
361 
362 
363 		// Servicios específicos, no definidos en DataObservable
SetClipboardObject(PObjectBase obj)364 		void        SetClipboardObject( PObjectBase obj ) { m_clipboard = obj; }
365 
GetClipboardObject()366 		PObjectBase GetClipboardObject()                { return m_clipboard; }
367 
GetProjectFileName()368 		wxString GetProjectFileName() { return m_projectFile; }
369 
370 		const int m_fbpVerMajor;
371 
372 		const int m_fbpVerMinor;
373 
374 		/** Path to the fbp file that is opened. */
GetProjectPath()375 		const wxString &GetProjectPath() { return m_projectPath; };
376 
377 
378 		/**
379 		Path where the files will be generated.
380 		*/
381 		wxString GetOutputPath();
382 
383 		/**
384 		Path where the embedded bitmap files will be generated.
385 		*/
386 		wxString GetEmbeddedFilesOutputPath();
387 
SetProjectPath(const wxString & path)388 		void SetProjectPath( const wxString &path ) { m_projectPath = path; };
389 
GetApplicationPath()390 		const wxString &GetApplicationPath() { return m_rootDir; };
391 
SetApplicationPath(const wxString & path)392 		void SetApplicationPath( const wxString &path ) { m_rootDir = path; };
393 
394 		// Allow a single instance check from outsid the AppData class
395 		bool VerifySingleInstance( const wxString& file, bool switchTo = true );
396 };
397 
398 #endif //__APP_DATA__
399