1 
2 ///////////////////////////////////////////////////////////
3 //                                                       //
4 //                         SAGA                          //
5 //                                                       //
6 //      System for Automated Geoscientific Analyses      //
7 //                                                       //
8 //                    User Interface                     //
9 //                                                       //
10 //                    Program: SAGA                      //
11 //                                                       //
12 //-------------------------------------------------------//
13 //                                                       //
14 //                 WKSP_Data_Manager.cpp                 //
15 //                                                       //
16 //          Copyright (C) 2005 by Olaf Conrad            //
17 //                                                       //
18 //-------------------------------------------------------//
19 //                                                       //
20 // This file is part of 'SAGA - System for Automated     //
21 // Geoscientific Analyses'. SAGA is free software; you   //
22 // can redistribute it and/or modify it under the terms  //
23 // of the GNU General Public License as published by the //
24 // Free Software Foundation, either version 2 of the     //
25 // License, or (at your option) any later version.       //
26 //                                                       //
27 // SAGA is distributed in the hope that it will be       //
28 // useful, but WITHOUT ANY WARRANTY; without even the    //
29 // implied warranty of MERCHANTABILITY or FITNESS FOR A  //
30 // PARTICULAR PURPOSE. See the GNU General Public        //
31 // License for more details.                             //
32 //                                                       //
33 // You should have received a copy of the GNU General    //
34 // Public License along with this program; if not, see   //
35 // <http://www.gnu.org/licenses/>.                       //
36 //                                                       //
37 //-------------------------------------------------------//
38 //                                                       //
39 //    contact:    Olaf Conrad                            //
40 //                Institute of Geography                 //
41 //                University of Goettingen               //
42 //                Goldschmidtstr. 5                      //
43 //                37077 Goettingen                       //
44 //                Germany                                //
45 //                                                       //
46 //    e-mail:     oconrad@saga-gis.org                   //
47 //                                                       //
48 ///////////////////////////////////////////////////////////
49 
50 //---------------------------------------------------------
51 #ifdef _SAGA_LINUX
52 #include <stdlib.h>
53 #endif
54 
55 #include <wx/filename.h>
56 
57 #include <saga_api/saga_api.h>
58 
59 #include "saga.h"
60 #include "saga_frame.h"
61 
62 #include "res_commands.h"
63 #include "res_dialogs.h"
64 
65 #include "helper.h"
66 #include "project.h"
67 
68 #include "wksp_data_control.h"
69 #include "wksp_data_manager.h"
70 #include "wksp_data_menu_files.h"
71 #include "wksp_data_layers.h"
72 
73 #include "wksp_layer.h"
74 
75 #include "wksp_table_manager.h"
76 #include "wksp_table.h"
77 #include "wksp_shapes_manager.h"
78 #include "wksp_shapes.h"
79 #include "wksp_tin_manager.h"
80 #include "wksp_pointcloud_manager.h"
81 #include "wksp_grid_manager.h"
82 
83 #include "wksp_map_manager.h"
84 
85 #include "wksp_tool.h"
86 
87 #include "active.h"
88 #include "active_parameters.h"
89 
90 
91 ///////////////////////////////////////////////////////////
92 //														 //
93 //														 //
94 //														 //
95 ///////////////////////////////////////////////////////////
96 
97 //---------------------------------------------------------
98 CWKSP_Data_Manager	*g_pData	= NULL;
99 
100 
101 ///////////////////////////////////////////////////////////
102 //														 //
103 //														 //
104 //														 //
105 ///////////////////////////////////////////////////////////
106 
107 //---------------------------------------------------------
CWKSP_Data_Manager(void)108 CWKSP_Data_Manager::CWKSP_Data_Manager(void)
109 {
110 	g_pData			= this;
111 
112 	m_pTables		= NULL;
113 	m_pShapes		= NULL;
114 	m_pTINs			= NULL;
115 	m_pPointClouds	= NULL;
116 	m_pGrids		= NULL;
117 
118 	m_pProject		= new CWKSP_Project;
119 	m_pMenu_Files	= new CWKSP_Data_Menu_Files;
120 
121 	//-----------------------------------------------------
122 	m_Parameters.Add_Node("",
123 		"NODE_GENERAL"			, _TL("General"),
124 		_TL("")
125 	);
126 
127 	m_Parameters.Add_Choice("NODE_GENERAL",
128 		"PROJECT_START"			, _TL("Startup Project"),
129 		_TL(""),
130 		CSG_String::Format("%s|%s|%s",
131 			_TL("empty"),
132 			_TL("last state"),
133 			_TL("always ask what to do")
134 		), 2
135 	);
136 
137 	m_Parameters.Add_Choice("NODE_GENERAL",
138 		"PROJECT_MAP_ARRANGE"	, _TL("Map Window Arrangement"),
139 		_TL("initial map window arrangement after a project is loaded"),
140 		CSG_String::Format("%s|%s|%s|%s",
141 			_TL("Cascade"),
142 			_TL("Tile Horizontally"),
143 			_TL("Tile Vertically"),
144 			_TL("Maximized")
145 		), 2
146 	);
147 
148 #ifndef _SAGA_MSW
149 	m_Parameters.Set_Enabled("PROJECT_MAP_ARRANGE", false);
150 #endif
151 
152 	m_Parameters.Add_Choice("NODE_GENERAL",
153 		"PROJECT_DB_REOPEN"		, _TL("Reopen Database Connections"),
154 		_TL("Reopen PostgreSQL database connections. Warning: if set to true account information including unencrypted passwords for automatic connection will be stored."),
155 		CSG_String::Format("%s|%s",
156 			_TL("no"),
157 			_TL("yes")
158 		), 0
159 	);
160 
161 	m_Parameters.Add_Int("PROJECT_DB_REOPEN",
162 		"PROJECT_DB_WAIT"		, _TL("Response Time"),
163 		_TL("Maximum time (seconds) to wait for server response. If zero it waits until the PostgreSQL connection is established or refused."),
164 		2, 0, true
165 	);
166 
167 	m_Parameters.Add_Bool("NODE_GENERAL",
168 		"SHOW_FILE_SOURCES"		, _TL("Show Data File Sources"),
169 		_TL("Show data sources tab for file system. Disabling might speed up start-up. Changes take effect after restart."),
170 		true
171 	);
172 
173 	m_Parameters.Add_Int("NODE_GENERAL",
174 		"NUMBERING"				, _TL("Numbering of Data Sets"),
175 		_TL("Leading zeros for data set numbering. Set to -1 for not using numbers at all."),
176 		m_Numbering = 2, -1, true
177 	);
178 
179 	m_Parameters.Add_Bool("NODE_GENERAL",
180 		"NAME_BY_FILE"			, _TL("Use File Name for Naming"),
181 		_TL("Use file name to name a data set, when it has been loaded from file."),
182 		false
183 	);
184 
185 	m_Parameters.Add_Colors("NODE_GENERAL",
186 		"COLORS_DEFAULT"		, _TL("Default Colors"),
187 		_TL("")
188 	);
189 
190 	m_Parameters.Add_Bool("NODE_GENERAL",
191 		"COLORS_FROM_TOOL"		, _TL("Tool Set Colors"),
192 		_TL("Allow tools to change data set colors programmatically."),
193 		true
194 	);
195 
196 	SG_DataObject_Set_Max_Samples(1000000);	// default to one million
197 
198 	m_Parameters.Add_Int("NODE_GENERAL",
199 		"DATA_SAMPLE_MAX"		, _TL("Maximum Samples"),
200 		_TL("Default maximum number of samples used to build statistics and histograms. Set to zero to use all data records."),
201 		(int)SG_DataObject_Get_Max_Samples(), 0, true
202 	);
203 
204 	//-----------------------------------------------------
205 	m_Parameters.Add_Node("",
206 		"NODE_HISTORY"			, _TL("History"),
207 		_TL("")
208 	);
209 
210 	m_Parameters.Add_Int("NODE_HISTORY",
211 		"HISTORY_DEPTH"			, _TL("History Depth"),
212 		_TL("Depth to which data history is stored. Set -1 keeps all history entries (default), 0 switches history option off."),
213 		SG_Get_History_Depth(), -1, true
214 	);
215 
216 	m_Parameters.Add_Bool("NODE_HISTORY",
217 		"HISTORY_LISTS"			, _TL("Ignore Input Lists"),
218 		_TL(""),
219 		SG_Get_History_Ignore_Lists() != 0
220 	);
221 
222 	//-----------------------------------------------------
223 	m_Parameters.Add_Node("",
224 		"NODE_THUMBNAILS"		, _TL("Thumbnails"),
225 		_TL("")
226 	);
227 
228 	m_Parameters.Add_Int("NODE_THUMBNAILS",
229 		"THUMBNAIL_SIZE"		, _TL("Thumbnail Size"),
230 		_TL(""),
231 		50, 10, true
232 	);
233 
234 	m_Parameters.Add_Bool("NODE_THUMBNAILS",
235 		"THUMBNAIL_CATEGORY"	, _TL("Show Categories"),
236 		_TL(""),
237 		true
238 	);
239 
240 	m_Parameters.Add_Color("NODE_THUMBNAILS",
241 		"THUMBNAIL_SELCOLOR"	, _TL("Selection Color"),
242 		_TL(""),
243 		Get_Color_asInt(SYS_Get_Color(wxSYS_COLOUR_BTNSHADOW))
244 	);
245 
246 	//-----------------------------------------------------
247 	m_Parameters.Add_Node("",
248 		"NODE_GRID"				, _TL("Grids"),
249 		_TL("")
250 	);
251 
252 	m_Parameters.Add_Choice("NODE_GRID",
253 		"GRID_FMT_DEFAULT"		, _TL("Default Output Format"),
254 		_TL(""),
255 		CSG_String::Format("%s (*.sg-grd-z)|%s (*.sg-grd)|%s (*.sgrd)|%s (*.tif)",
256 			_TL("SAGA Compressed Grid Files"),
257 			_TL("SAGA Grid Files"),
258 			_TL("SAGA Grid Files (old extension)"),
259 			_TL("GeoTIFF")
260 		), 2
261 	);
262 
263 	m_Parameters.Add_Int("NODE_GRID",
264 		"GRID_COORD_PRECISION"	, _TL("Coordinate Precision"),
265 		_TL("Precision used to store coordinates and cell sizes (i.e. number of decimals)."),
266 		10, 0, true
267 	);
268 
269 	m_Parameters.Add_Choice("NODE_GRID",
270 		"GRID_STRETCH_DEFAULT"	, _TL("Histogram Stretch"),
271 		_TL("Histogram stretch appolied by default to new grids."),
272 		CSG_String::Format("%s|%s|%s",
273 			_TL("Minimum/Maximum"),
274 			_TL("Standard Deviation"),
275 			_TL("Percentile")
276 		), 1
277 	);
278 
279 	//-----------------------------------------------------
280 	m_Parameters.Add_Int("NODE_GRID",
281 		"GRID_SELECT_MAX"		, _TL("Maximum Selection"),
282 		_TL("Maximum number of rows/columns in selection of grid cells."),
283 		100, 1, true
284 	);
285 
286 	//-----------------------------------------------------
287 	m_Parameters.Add_Choice("NODE_GRID",
288 		"GRID_CACHE_MODE"		, _TL("File Cache"),
289 		_TL("Activate file caching automatically, if memory size exceeds the threshold value."),
290 		CSG_String::Format("%s|%s|%s",
291 			_TL("no"),
292 			_TL("yes"),
293 			_TL("after confirmation")
294 		), SG_Grid_Cache_Get_Mode()
295 	);
296 
297 	m_Parameters.Add_Double("GRID_CACHE_MODE",
298 		"GRID_CACHE_THRSHLD"	, _TL("Threshold for automatic mode [MB]"),
299 		_TL(""),
300 		SG_Grid_Cache_Get_Threshold_MB(), 0.0, true
301 	);
302 
303 	m_Parameters.Add_FilePath("GRID_CACHE_MODE",
304 		"GRID_CACHE_TMPDIR"		, _TL("Temporary files"),
305 		_TL("Directory, where temporary cache files shall be saved."),
306 		NULL, SG_Grid_Cache_Get_Directory(), true, true
307 	);
308 
309 	//-----------------------------------------------------
310 	m_Parameters.Add_Node("",
311 		"NODE_TABLE"			, _TL("Tables"),
312 		_TL("")
313 	);
314 
315 	m_Parameters.Add_Choice("NODE_TABLE",
316 		"TABLE_FLT_STYLE"		, _TL("Floating Point Numbers"),
317 		_TL(""),
318 		CSG_String::Format("%s|%s|%s",
319 			_TL("system default"),
320 			_TL("compact"),
321 			_TL("fix number of decimals")
322 		), 1
323 	);
324 
325 	m_Parameters.Add_Int("NODE_TABLE",
326 		"TABLE_FLT_DECIMALS"	, _TL("Decimals"),
327 		_TL(""),
328 		6, 0, true
329 	);
330 
331 	//-----------------------------------------------------
332 	m_Parameters.Add_Node("",
333 		"NODE_SHAPES"			, _TL("Shapes"),
334 		_TL("")
335 	);
336 
337 	m_Parameters.Add_Choice("NODE_SHAPES",
338 		"SHAPES_FMT_DEFAULT"	, _TL("Default Output Format"),
339 		_TL(""),
340 		CSG_String::Format("%s|%s|%s",
341 			_TL("ESRI Shape File (*.shp)"),
342 			_TL("GeoPackage (*.gpkg)"),
343 			_TL("GeoJSON (*.geojson)")
344 		), 0
345 	);
346 
347 	//-----------------------------------------------------
348 	CONFIG_Read("/DATA", &m_Parameters);
349 
350 	SG_DataObject_Set_Max_Samples    (m_Parameters("DATA_SAMPLE_MAX"     )->asInt   ());
351 
352 	SG_Grid_Cache_Set_Mode           (m_Parameters("GRID_CACHE_MODE"     )->asInt   ());
353 	SG_Grid_Cache_Set_Threshold_MB   (m_Parameters("GRID_CACHE_THRSHLD"  )->asDouble());
354 	SG_Grid_Cache_Set_Directory      (m_Parameters("GRID_CACHE_TMPDIR"   )->asString());
355 
356 	CSG_Grid_System::Set_Precision   (m_Parameters("GRID_COORD_PRECISION")->asInt   ());
357 
358 	SG_Set_History_Depth             (m_Parameters("HISTORY_DEPTH"       )->asInt   ());
359 	SG_Set_History_Ignore_Lists      (m_Parameters("HISTORY_LISTS"       )->asInt   ());
360 
361 	switch( m_Parameters("GRID_FMT_DEFAULT")->asInt() )
362 	{
363 	default: SG_Grid_Set_File_Format_Default(GRID_FILE_FORMAT_Compressed); break;
364 	case  1: SG_Grid_Set_File_Format_Default(GRID_FILE_FORMAT_Binary    ); break;
365 	case  2: SG_Grid_Set_File_Format_Default(GRID_FILE_FORMAT_Binary_old); break;
366 	case  3: SG_Grid_Set_File_Format_Default(GRID_FILE_FORMAT_GeoTIFF   ); break;
367 	}
368 
369 	switch( m_Parameters("SHAPES_FMT_DEFAULT")->asInt() )
370 	{
371 	default: SG_Shapes_Set_File_Format_Default(SHAPE_FILE_FORMAT_ESRI      ); break;
372 	case  1: SG_Shapes_Set_File_Format_Default(SHAPE_FILE_FORMAT_GeoPackage); break;
373 	case  2: SG_Shapes_Set_File_Format_Default(SHAPE_FILE_FORMAT_GeoJSON   ); break;
374 	}
375 
376 	m_Numbering	= m_Parameters("NUMBERING")->asInt();
377 }
378 
379 //---------------------------------------------------------
~CWKSP_Data_Manager(void)380 CWKSP_Data_Manager::~CWKSP_Data_Manager(void)
381 {
382 	CONFIG_Write("/DATA", &m_Parameters);
383 
384 	delete(m_pProject);
385 	delete(m_pMenu_Files);
386 
387 	g_pData	= NULL;
388 }
389 
390 
391 ///////////////////////////////////////////////////////////
392 //														 //
393 ///////////////////////////////////////////////////////////
394 
395 //---------------------------------------------------------
Get_SAGA_GUI_CFG(void)396 wxFileName Get_SAGA_GUI_CFG(void)
397 {
398 #ifdef _SAGA_LINUX
399 //	wxFileName	fProject(wxString(getenv( "HOME"), wxConvFile ), wxT("saga_gui"), wxT("cfg"));
400 	CSG_String	sHome(getenv("HOME"));
401 	wxFileName	fProject(sHome.c_str(), "saga_gui", "cfg");
402 #else
403 	wxFileName	fProject(g_pSAGA->Get_App_Path(), "saga_gui", "cfg");
404 
405 	if(	( fProject.FileExists() && (!fProject.IsFileReadable() || !fProject.IsFileWritable()))
406 	||	(!fProject.FileExists() && (!fProject.IsDirReadable () || !fProject.IsDirWritable ())) )
407 	{
408 		fProject.Assign(wxGetHomeDir(), "saga_gui", "cfg");
409 	}
410 #endif
411 
412 	fProject.Normalize();
413 
414 	return( fProject );
415 }
416 
417 //---------------------------------------------------------
Initialise(void)418 bool CWKSP_Data_Manager::Initialise(void)
419 {
420 	//-----------------------------------------------------
421 	if( m_pProject->Has_File_Name() )	{	return( m_pProject->Load(false) );	}
422 	//-----------------------------------------------------
423 
424 	//-----------------------------------------------------
425 	wxFileName	fProject, fLastState	= Get_SAGA_GUI_CFG();
426 
427 	switch( m_Parameters("PROJECT_START")->asInt() )
428 	{
429 	case 0:	// empty
430 		return( true );
431 
432 	case 1:	// last state
433 		return( m_pProject->Load(fLastState.GetFullPath(), false, false) );
434 
435 	case 2:	// always ask what to do
436 		{
437 			wxArrayString	Projects;
438 
439 			Projects.Add(wxString::Format("[%s]", _TL("empty")));
440 
441 			if( fLastState.FileExists() )
442 			{
443 				Projects.Add(wxString::Format("[%s]", _TL("last state")));
444 			}
445 
446 			m_pMenu_Files->Recent_Get(SG_DATAOBJECT_TYPE_Undefined, Projects, true);
447 
448 			wxSingleChoiceDialog	dlg(MDI_Get_Top_Window(), _TL("Startup Project"), _TL("Select Startup Project"), Projects);
449 
450 			if( Projects.Count() <= 1 || dlg.ShowModal() != wxID_OK || dlg.GetSelection() == 0 )
451 			{	// empty
452 				return( true );
453 			}
454 
455 			if( fLastState.FileExists() && dlg.GetSelection() == 1 )
456 			{	// last state
457 				return( m_pProject->Load(fLastState.GetFullPath(), false, false) );
458 			}
459 			else
460 			{	// recently opened project
461 				return( m_pProject->Load(dlg.GetStringSelection(), false, true) );
462 			}
463 		}
464 	}
465 
466 	//-----------------------------------------------------
467 	//wxString	FileName	= Get_FilePath_Absolute(g_pSAGA->Get_App_Path(), fProject.GetFullPath());
468 
469 	return( false );
470 }
471 
472 //---------------------------------------------------------
Finalise(void)473 bool CWKSP_Data_Manager::Finalise(void)
474 {
475 	wxFileName	fProject	= Get_SAGA_GUI_CFG();
476 
477 	if( Get_Count() > 0 )
478 	{	// last state
479 		m_pProject->Save(fProject.GetFullPath(), false);
480 
481 		if( fProject.GetPath().Find(g_pSAGA->Get_App_Path()) == 0 )
482 		{
483 			fProject.MakeRelativeTo(g_pSAGA->Get_App_Path());
484 		}
485 	}
486 	else if( fProject.FileExists() )
487 	{
488 		wxRemoveFile(fProject.GetFullPath());
489 	}
490 
491 	return( true );
492 }
493 
494 
495 ///////////////////////////////////////////////////////////
496 //														 //
497 ///////////////////////////////////////////////////////////
498 
499 //---------------------------------------------------------
Get_Name(void)500 wxString CWKSP_Data_Manager::Get_Name(void)
501 {
502 	return( _TL("Data") );
503 }
504 
505 //---------------------------------------------------------
Get_Description(void)506 wxString CWKSP_Data_Manager::Get_Description(void)
507 {
508 	wxString	s;
509 
510 	//-----------------------------------------------------
511 	s	+= wxString::Format("<h4>%s</h4>", _TL("Data"));
512 
513 	s	+= "<table border=\"0\">";
514 
515 	DESC_ADD_INT(_TL("Number of Data Sets"), Get_Count());
516 
517 	if( m_pProject->Has_File_Name() )
518 	{
519 		DESC_ADD_STR(_TL("Project File"), m_pProject->Get_File_Name());
520 	}
521 
522 	DESC_ADD_INT(_TL("Tables"      ), Get_Tables     () ? Get_Tables     ()->Get_Count      () : 0);
523 	DESC_ADD_INT(_TL("Shapes"      ), Get_Shapes     () ? Get_Shapes     ()->Get_Items_Count() : 0);
524 	DESC_ADD_INT(_TL("TIN"         ), Get_TINs       () ? Get_TINs       ()->Get_Count      () : 0);
525 	DESC_ADD_INT(_TL("Point Clouds"), Get_PointClouds() ? Get_PointClouds()->Get_Count      () : 0);
526 	DESC_ADD_INT(_TL("Grid Systems"), Get_Grids      () ? Get_Grids      ()->Get_Count      () : 0);
527 	DESC_ADD_INT(_TL("Grids"       ), Get_Grids      () ? Get_Grids      ()->Get_Items_Count() : 0);
528 
529 	s	+= wxT("</table>");
530 
531 	return( s );
532 }
533 
534 //---------------------------------------------------------
Get_Menu(void)535 wxMenu * CWKSP_Data_Manager::Get_Menu(void)
536 {
537 	if( m_Sel_Items.Count() > 0 )
538 	{
539 		wxMenu	*pMenu	= new wxMenu;
540 
541 		CMD_Menu_Add_Item(pMenu, false, ID_CMD_WKSP_ITEM_CLOSE);
542 		CMD_Menu_Add_Item(pMenu, false, ID_CMD_WKSP_ITEM_SHOW);
543 		CMD_Menu_Add_Item(pMenu, false, ID_CMD_WKSP_ITEM_SETTINGS_LOAD);
544 		CMD_Menu_Add_Item(pMenu, false, ID_CMD_WKSP_ITEM_SETTINGS_COPY);
545 
546 		return( pMenu );
547 	}
548 
549 	//-----------------------------------------------------
550 	wxMenu	*pMenu	= new wxMenu(_TL("Data"));
551 
552 	if( wxGetKeyState(WXK_CONTROL) ) // add advanced/hidden commands
553 	{
554 		wxMenu *pAdvanced = new wxMenu;
555 
556 		CMD_Menu_Add_Item(pAdvanced, false, ID_CMD_DATA_MANAGER_LIST);
557 
558 		pMenu->AppendSubMenu(pAdvanced, _TL("Advanced"));
559 		pMenu->AppendSeparator();
560 	}
561 
562 	//-----------------------------------------------------
563 	CMD_Menu_Add_Item(pMenu, false, ID_CMD_DATA_PROJECT_OPEN);
564 //	CMD_Menu_Add_Item(pMenu, false, ID_CMD_DATA_PROJECT_OPEN_ADD);
565 	CMD_Menu_Add_Item(pMenu, false, ID_CMD_DATA_PROJECT_NEW);
566 
567 	if( Get_Count() > 0 )
568 	{
569 		CMD_Menu_Add_Item(pMenu, false, ID_CMD_DATA_PROJECT_SAVE);
570 		CMD_Menu_Add_Item(pMenu, false, ID_CMD_DATA_PROJECT_SAVE_AS);
571 		CMD_Menu_Add_Item(pMenu, false, ID_CMD_DATA_PROJECT_COPY);
572 	//	CMD_Menu_Add_Item(pMenu, false, ID_CMD_DATA_PROJECT_COPY_DB);
573 		pMenu->AppendSeparator();
574 		CMD_Menu_Add_Item(pMenu, false, ID_CMD_WKSP_ITEM_SEARCH);
575 	}
576 
577 	//-----------------------------------------------------
578 	return( pMenu );
579 }
580 
581 
582 ///////////////////////////////////////////////////////////
583 //														 //
584 ///////////////////////////////////////////////////////////
585 
586 //---------------------------------------------------------
On_Command(int Cmd_ID)587 bool CWKSP_Data_Manager::On_Command(int Cmd_ID)
588 {
589 	if( Open_CMD(Cmd_ID) )
590 	{
591 		return( true );
592 	}
593 
594 	if( m_pTables && Cmd_ID >= ID_CMD_TABLE_FIRST  && Cmd_ID <= ID_CMD_TABLE_LAST  && m_pTables->On_Command(Cmd_ID) )
595 	{
596 		return( true );
597 	}
598 
599 	if( m_pShapes && Cmd_ID >= ID_CMD_SHAPES_FIRST && Cmd_ID <= ID_CMD_SHAPES_LAST && m_pShapes->On_Command(Cmd_ID) )
600 	{
601 		return( true );
602 	}
603 
604 	if( m_pTINs   && Cmd_ID >= ID_CMD_TIN_FIRST    && Cmd_ID <= ID_CMD_TIN_LAST    && m_pTINs  ->On_Command(Cmd_ID) )
605 	{
606 		return( true );
607 	}
608 
609 	if( m_pPointClouds && Cmd_ID >= ID_CMD_POINTCLOUD_FIRST && Cmd_ID <= ID_CMD_POINTCLOUD_LAST && m_pPointClouds->On_Command(Cmd_ID) )
610 	{
611 		return( true );
612 	}
613 
614 	if( m_pGrids  && Cmd_ID >= ID_CMD_GRID_FIRST   && Cmd_ID <= ID_CMD_GRID_LAST   && m_pGrids ->On_Command(Cmd_ID) )
615 	{
616 		return( true );
617 	}
618 
619 	if( m_pGrids  && Cmd_ID >= ID_CMD_GRIDS_FIRST  && Cmd_ID <= ID_CMD_GRIDS_LAST  && m_pGrids ->On_Command(Cmd_ID) )
620 	{
621 		return( true );
622 	}
623 
624 	//-----------------------------------------------------
625 	switch( Cmd_ID )
626 	{
627 	default:
628 		return( CWKSP_Base_Manager::On_Command(Cmd_ID) );
629 
630 	//-----------------------------------------------------
631 	case ID_CMD_WKSP_ITEM_RETURN     :                                      break;
632 	case ID_CMD_WKSP_ITEM_CLOSE      : Close(false);                        break;
633 
634 	//-----------------------------------------------------
635 	case ID_CMD_DATA_PROJECT_OPEN    : m_pProject->Load(false);             break;
636 	case ID_CMD_DATA_PROJECT_OPEN_ADD: m_pProject->Load( true);             break;
637 	case ID_CMD_DATA_PROJECT_BROWSE  : Open_Browser();                      break;
638 	case ID_CMD_DATA_PROJECT_NEW     : Close(false);                        break;
639 	case ID_CMD_DATA_PROJECT_SAVE    : m_pProject->Save(true);              break;
640 	case ID_CMD_DATA_PROJECT_SAVE_AS : m_pProject->Save();                  break;
641 	case ID_CMD_DATA_PROJECT_COPY    : m_pProject->Copy();                  break;
642 	case ID_CMD_DATA_PROJECT_COPY_DB : m_pProject->CopyToDB();              break;
643 
644 	//-----------------------------------------------------
645 	case ID_CMD_TABLE_OPEN           : Open(SG_DATAOBJECT_TYPE_Table     ); break;
646 	case ID_CMD_SHAPES_OPEN          : Open(SG_DATAOBJECT_TYPE_Shapes    ); break;
647 	case ID_CMD_TIN_OPEN             : Open(SG_DATAOBJECT_TYPE_TIN       ); break;
648 	case ID_CMD_POINTCLOUD_OPEN      : Open(SG_DATAOBJECT_TYPE_PointCloud); break;
649 	case ID_CMD_GRID_OPEN            : Open(SG_DATAOBJECT_TYPE_Grid      ); break;
650 	case ID_CMD_GRIDS_OPEN           : Open(SG_DATAOBJECT_TYPE_Grids     ); break;
651 
652 	//-----------------------------------------------------
653 	case ID_CMD_DATA_MANAGER_LIST    : {
654 		CSG_String s(SG_Get_Data_Manager().Get_Summary());
655 		MSG_General_Add_Line();
656 		MSG_General_Add(s.c_str());
657 		MSG_General_Add_Line();
658 		break; }
659 	}
660 
661 	//-----------------------------------------------------
662 	return( true );
663 }
664 
665 //---------------------------------------------------------
On_Command_UI(wxUpdateUIEvent & event)666 bool CWKSP_Data_Manager::On_Command_UI(wxUpdateUIEvent &event)
667 {
668 	switch( event.GetId() )
669 	{
670 	default:
671 		return( CWKSP_Base_Manager::On_Command_UI(event) );
672 
673 	case ID_CMD_WKSP_ITEM_CLOSE:
674 		event.Enable(Get_Count() > 0 && g_pTool == NULL);
675 		break;
676 
677 	case ID_CMD_DATA_PROJECT_SAVE:
678 		event.Enable(Get_Count() > 0 && m_pProject->Has_File_Name() );
679 		break;
680 
681 	case ID_CMD_DATA_PROJECT_SAVE_AS:
682 		event.Enable(Get_Count() > 0);
683 		break;
684 	}
685 
686 	return( true );
687 }
688 
689 
690 ///////////////////////////////////////////////////////////
691 //														 //
692 ///////////////////////////////////////////////////////////
693 
694 //---------------------------------------------------------
Get_Parameters(void)695 CSG_Parameters * CWKSP_Data_Manager::Get_Parameters(void)
696 {
697 	if( m_Sel_Parms[0].Get_Count() > 0 )
698 	{
699 		return( &m_Sel_Parms[0] );
700 	}
701 
702 	return( m_Parameters.Get_Count() > 0 ? &m_Parameters : NULL );
703 }
704 
705 //---------------------------------------------------------
Parameters_Changed(void)706 void CWKSP_Data_Manager::Parameters_Changed(void)
707 {
708 	if( MultiSelect_Update() )
709 	{
710 		return;
711 	}
712 
713 	SG_DataObject_Set_Max_Samples    (m_Parameters("DATA_SAMPLE_MAX"     )->asInt   ());
714 
715 	SG_Grid_Cache_Set_Mode           (m_Parameters("GRID_CACHE_MODE"     )->asInt   ());
716 	SG_Grid_Cache_Set_Threshold_MB   (m_Parameters("GRID_CACHE_THRSHLD"  )->asDouble());
717 	SG_Grid_Cache_Set_Directory      (m_Parameters("GRID_CACHE_TMPDIR"   )->asString());
718 
719 	CSG_Grid_System::Set_Precision   (m_Parameters("GRID_COORD_PRECISION")->asInt   ());
720 
721 	SG_Set_History_Depth             (m_Parameters("HISTORY_DEPTH"       )->asInt   ());
722 	SG_Set_History_Ignore_Lists      (m_Parameters("HISTORY_LISTS"       )->asInt   ());
723 
724 	switch( m_Parameters("GRID_FMT_DEFAULT")->asInt() )
725 	{
726 	default: SG_Grid_Set_File_Format_Default(GRID_FILE_FORMAT_Compressed); break;
727 	case  1: SG_Grid_Set_File_Format_Default(GRID_FILE_FORMAT_Binary    ); break;
728 	case  2: SG_Grid_Set_File_Format_Default(GRID_FILE_FORMAT_Binary_old); break;
729 	case  3: SG_Grid_Set_File_Format_Default(GRID_FILE_FORMAT_GeoTIFF   ); break;
730 	}
731 
732 	switch( m_Parameters("SHAPES_FMT_DEFAULT")->asInt() )
733 	{
734 	default: SG_Shapes_Set_File_Format_Default(SHAPE_FILE_FORMAT_ESRI      ); break;
735 	case  1: SG_Shapes_Set_File_Format_Default(SHAPE_FILE_FORMAT_GeoPackage); break;
736 	case  2: SG_Shapes_Set_File_Format_Default(SHAPE_FILE_FORMAT_GeoJSON   ); break;
737 	}
738 
739 	m_Numbering	= m_Parameters("NUMBERING")->asInt();
740 
741 	g_pData_Buttons->Update_Buttons();
742 
743 	CWKSP_Base_Manager::Parameters_Changed();
744 }
745 
746 
747 ///////////////////////////////////////////////////////////
748 //														 //
749 ///////////////////////////////////////////////////////////
750 
751 //---------------------------------------------------------
On_Parameter_Changed(CSG_Parameters * pParameters,CSG_Parameter * pParameter,int Flags)752 int CWKSP_Data_Manager::On_Parameter_Changed(CSG_Parameters *pParameters, CSG_Parameter *pParameter, int Flags)
753 {
754 	//-----------------------------------------------------
755 	if( Flags & PARAMETER_CHECK_VALUES )
756 	{
757 	}
758 
759 	//-----------------------------------------------------
760 	if( Flags & PARAMETER_CHECK_ENABLE )
761 	{
762 		if(	pParameter->Cmp_Identifier("GRID_CACHE_MODE") )
763 		{
764 			pParameters->Set_Enabled("GRID_CACHE_THRSHLD", pParameter->asInt() != 0);
765 			pParameters->Set_Enabled("GRID_CACHE_TMPDIR" , pParameter->asInt() != 0);
766 		}
767 
768 		if(	pParameter->Cmp_Identifier("TABLE_FLT_STYLE") )
769 		{
770 			pParameters->Set_Enabled("TABLE_FLT_DECIMALS", pParameter->asInt() == 2);
771 		}
772 	}
773 
774 	//-----------------------------------------------------
775 	return( CWKSP_Base_Manager::On_Parameter_Changed(pParameters, pParameter, Flags) );
776 }
777 
778 
779 ///////////////////////////////////////////////////////////
780 //														 //
781 ///////////////////////////////////////////////////////////
782 
783 //---------------------------------------------------------
Open(const wxString & File,int DataType)784 CWKSP_Base_Item * CWKSP_Data_Manager::Open(const wxString &File, int DataType)
785 {
786 	CSG_Data_Object	*pObject	= NULL;
787 
788 //	SG_Get_Data_Manager().Add(File, DataType);
789 
790 	switch( DataType )
791 	{
792 	case SG_DATAOBJECT_TYPE_Table     :	pObject	= SG_Create_Table     (&File);	break;
793 	case SG_DATAOBJECT_TYPE_Shapes    :	pObject	= SG_Create_Shapes    (&File);	break;
794 	case SG_DATAOBJECT_TYPE_TIN       :	pObject	= SG_Create_TIN       (&File);	break;
795 	case SG_DATAOBJECT_TYPE_PointCloud:	pObject	= SG_Create_PointCloud(&File);	break;
796 	case SG_DATAOBJECT_TYPE_Grid      :	pObject	= SG_Create_Grid      (&File);	break;
797 	case SG_DATAOBJECT_TYPE_Grids     :	pObject	= SG_Create_Grids     (&File);	break;
798 	}
799 
800 	if( pObject )
801 	{
802 		CWKSP_Data_Item	*pItem;
803 
804 		if( pObject->is_Valid() && (pItem = Add(pObject)) != NULL )
805 		{
806 			m_pMenu_Files->Recent_Add(pObject->Get_ObjectType(), File);
807 
808 			SG_Get_Data_Manager().Add(pObject);
809 
810 			return( (CWKSP_Base_Item *)pItem );
811 		}
812 
813 		delete(pObject);
814 	}
815 
816 	m_pMenu_Files->Recent_Del(DataType, File);
817 
818 	return( NULL );
819 }
820 
821 //---------------------------------------------------------
Open(const wxString & File)822 bool CWKSP_Data_Manager::Open(const wxString &File)
823 {
824 	if( SG_File_Cmp_Extension(&File, "sprj") )
825 	{
826 		return( m_pProject->Load(File, false, true) );
827 	}
828 
829 	if( SG_File_Cmp_Extension(&File, "txt"     )
830 	||	SG_File_Cmp_Extension(&File, "csv"     )
831 	||	SG_File_Cmp_Extension(&File, "dbf"     ) )
832 	{
833 		return( Open(File, SG_DATAOBJECT_TYPE_Table     ) != NULL );
834 	}
835 
836 	if( SG_File_Cmp_Extension(&File, "shp"     ) )
837 	{
838 		return( Open(File, SG_DATAOBJECT_TYPE_Shapes    ) != NULL );
839 	}
840 
841 	if( SG_File_Cmp_Extension(&File, "sg-pts-z")
842 	||  SG_File_Cmp_Extension(&File, "sg-pts"  )
843 	||  SG_File_Cmp_Extension(&File, "spc"     ) )
844 	{
845 		return( Open(File, SG_DATAOBJECT_TYPE_PointCloud) != NULL );
846 	}
847 
848 	if(	SG_File_Cmp_Extension(&File, "sg-grd-z")
849 	||	SG_File_Cmp_Extension(&File, "sg-grd"  )
850 	||	SG_File_Cmp_Extension(&File, "sgrd"    )
851 	||  SG_File_Cmp_Extension(&File, "dgm"     )
852 	||	SG_File_Cmp_Extension(&File, "grd"     ) )
853 	{
854 		return( Open(File, SG_DATAOBJECT_TYPE_Grid      ) != NULL );
855 	}
856 
857 	if( SG_File_Cmp_Extension(&File, "sg-gds-z")
858 	||  SG_File_Cmp_Extension(&File, "sg-gds"  ) )
859 	{
860 		return( Open(File, SG_DATAOBJECT_TYPE_Grids     ) != NULL );
861 	}
862 
863 	return( SG_Get_Data_Manager().Add(&File) != NULL );
864 }
865 
866 //---------------------------------------------------------
Open(int DataType)867 bool CWKSP_Data_Manager::Open(int DataType)
868 {
869 	bool	bResult	= false;
870 
871 	int				ID;
872 	wxArrayString	Files;
873 
874 	//-----------------------------------------------------
875 	switch( DataType )
876 	{
877 	case SG_DATAOBJECT_TYPE_Table     : ID = ID_DLG_TABLE_OPEN     ; break;
878 	case SG_DATAOBJECT_TYPE_Shapes    : ID = ID_DLG_SHAPES_OPEN    ; break;
879 	case SG_DATAOBJECT_TYPE_TIN       : ID = ID_DLG_TIN_OPEN       ; break;
880 	case SG_DATAOBJECT_TYPE_PointCloud: ID = ID_DLG_POINTCLOUD_OPEN; break;
881 	case SG_DATAOBJECT_TYPE_Grid      : ID = ID_DLG_GRID_OPEN      ; break;
882 	case SG_DATAOBJECT_TYPE_Grids     : ID = ID_DLG_GRIDS_OPEN     ; break;
883 	default                           : return( false );
884 	}
885 
886 	//-----------------------------------------------------
887 	if( DLG_Open(Files, ID) )
888 	{
889 		MSG_General_Add_Line();
890 
891 		for(size_t i=0; i<Files.GetCount(); i++)
892 		{
893 			if( Open(Files[i], DataType) )
894 			{
895 				bResult	= true;
896 			}
897 		}
898 	}
899 
900 	return( true );
901 }
902 
903 //---------------------------------------------------------
Open_CMD(int Cmd_ID)904 bool CWKSP_Data_Manager::Open_CMD(int Cmd_ID)
905 {
906 	return( m_pMenu_Files->Recent_Open(Cmd_ID) );
907 }
908 
909 
910 ///////////////////////////////////////////////////////////
911 //														 //
912 ///////////////////////////////////////////////////////////
913 
914 //---------------------------------------------------------
Open_Browser(void)915 bool CWKSP_Data_Manager::Open_Browser(void)
916 {
917 	//-----------------------------------------------------
918 	wxString	Directory	= wxDirSelector(_TL("Search for Projects"));
919 
920 	if( Directory.IsEmpty() )
921 	{
922 		return( false );
923 	}
924 
925 	//-----------------------------------------------------
926 	wxArrayString	Projects;
927 
928 	Open_Browser(Projects, Directory);
929 
930 	if( Projects.Count() == 0 )
931 	{
932 		wxMessageBox(_TL("No projects in directory"), _TL("Search for Projects"), wxOK|wxICON_EXCLAMATION);
933 
934 		return( false );
935 	}
936 
937 	//-----------------------------------------------------
938 	wxSingleChoiceDialog	dlg(MDI_Get_Top_Window(), _TL("Open Project"), _TL("Search for Projects"), Projects);
939 
940 	return( dlg.ShowModal() == wxID_OK && Open(dlg.GetStringSelection()) );
941 }
942 
943 //---------------------------------------------------------
944 #include <wx/dir.h>
945 
946 //---------------------------------------------------------
Open_Browser(wxArrayString & Projects,const wxString & Directory)947 bool CWKSP_Data_Manager::Open_Browser(wxArrayString &Projects, const wxString &Directory)
948 {
949 	wxDir	Dir;
950 
951 	if( Dir.Open(Directory) )
952 	{
953 		wxString	FileName;
954 
955 		if( Dir.GetFirst(&FileName, wxEmptyString, wxDIR_FILES) )
956 		{
957 			do
958 			{
959 				wxFileName	fn(Dir.GetName(), FileName);
960 
961 				if( !fn.GetExt().CmpNoCase("sprj") )
962 				{
963 					Projects.Add(fn.GetFullPath());
964 				}
965 			}
966 			while( Dir.GetNext(&FileName) );
967 		}
968 
969 		if( Dir.GetFirst(&FileName, wxEmptyString, wxDIR_DIRS) )
970 		{
971 			do
972 			{
973 				wxFileName	fn(Dir.GetName(), FileName);
974 
975 				Open_Browser(Projects, fn.GetFullPath());
976 			}
977 			while( Dir.GetNext(&FileName) );
978 		}
979 	}
980 
981 	return( Projects.Count() > 0 );
982 }
983 
984 
985 ///////////////////////////////////////////////////////////
986 //														 //
987 ///////////////////////////////////////////////////////////
988 
989 //---------------------------------------------------------
Save_Modified(CWKSP_Base_Item * pItem,bool bSelections)990 bool CWKSP_Data_Manager::Save_Modified(CWKSP_Base_Item *pItem, bool bSelections)
991 {
992 	CSG_Parameters	Parameters(_TL("Save Modified Data"));
993 
994 	Parameters.Add_Bool("", "SAVE_ALL", _TL("Save all"), _TL(""), false);
995 
996 	wxFileName	Directory(m_pProject->Get_File_Name());
997 
998 	if( !Directory.DirExists() )
999 	{
1000 		Directory.AssignDir(wxFileName::GetTempDir() + wxFileName::GetPathSeparator() + "saga");
1001 
1002 		Directory.Mkdir(wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL);
1003 	}
1004 
1005 	_Modified_Get(&Parameters, pItem ? pItem : this, Directory.GetPath(), bSelections);
1006 
1007 	if( Parameters.Get_Count() > 1 )
1008 	{
1009 		Parameters.Set_Callback_On_Parameter_Changed(&_Modified_Changed);
1010 
1011 		if( !DLG_Parameters(&Parameters) )
1012 		{
1013 			return( false );
1014 		}
1015 
1016 		_Modified_Save(&Parameters);
1017 	}
1018 
1019 	return( true );
1020 }
1021 
1022 //---------------------------------------------------------
_Modified_Changed(CSG_Parameter * pParameter,int Flags)1023 int CWKSP_Data_Manager::_Modified_Changed(CSG_Parameter *pParameter, int Flags)
1024 {
1025 	CSG_Parameters	*pParameters	= pParameter ? pParameter->Get_Parameters() : NULL;
1026 
1027 	if( pParameters )
1028 	{
1029 		if( pParameter->Cmp_Identifier("SAVE_ALL") )
1030 		{
1031 			for(int i=0; i<pParameters->Get_Count(); i++)
1032 			{
1033 				CSG_Parameter	*pFile	= pParameters->Get_Parameter(i);
1034 
1035 				if( pFile->Get_Type() == PARAMETER_TYPE_Bool )
1036 				{
1037 					pFile->Set_Value(pParameter->asBool());
1038 
1039 					for(int j=0; j<pFile->Get_Children_Count(); j++)
1040 					{
1041 						pFile->Get_Child(j)->Set_Enabled(pParameter->asBool());
1042 					}
1043 				}
1044 			}
1045 		}
1046 		else if( pParameter->Get_Type() == PARAMETER_TYPE_Bool )
1047 		{
1048 			if( !pParameter->asBool() && pParameters->Get_Parameter("SAVE_ALL") )
1049 			{
1050 				pParameters->Get_Parameter("SAVE_ALL")->Set_Value(0);
1051 			}
1052 
1053 			for(int j=0; j<pParameter->Get_Children_Count(); j++)
1054 			{
1055 				pParameter->Get_Child(j)->Set_Enabled(pParameter->asBool());
1056 			}
1057 		}
1058 
1059 		return( 1 );
1060 	}
1061 
1062 	return( 0 );
1063 }
1064 
1065 //---------------------------------------------------------
_Modified_Get(CSG_Parameters * pParameters,CWKSP_Base_Item * pItem,const wxString & Directory,bool bSelections)1066 bool CWKSP_Data_Manager::_Modified_Get(CSG_Parameters *pParameters, CWKSP_Base_Item *pItem, const wxString &Directory, bool bSelections)
1067 {
1068 	int		i;
1069 
1070 	if( pItem && pParameters )
1071 	{
1072 		switch( pItem->Get_Type() )
1073 		{
1074 		default:
1075 			break;
1076 
1077 		//-------------------------------------------------
1078 		case WKSP_ITEM_Data_Manager      :
1079 		case WKSP_ITEM_Table_Manager     :
1080 		case WKSP_ITEM_Shapes_Manager    :
1081 		case WKSP_ITEM_Shapes_Type       :
1082 		case WKSP_ITEM_TIN_Manager       :
1083 		case WKSP_ITEM_PointCloud_Manager:
1084 		case WKSP_ITEM_Grid_Manager      :
1085 		case WKSP_ITEM_Grid_System       :
1086 			for(i=0; i<((CWKSP_Base_Manager *)pItem)->Get_Count(); i++)
1087 			{
1088 				_Modified_Get(pParameters, ((CWKSP_Base_Manager *)pItem)->Get_Item(i), Directory, bSelections && !pItem->is_Selected());
1089 			}
1090 			break;
1091 
1092 		//-------------------------------------------------
1093 		case WKSP_ITEM_Table:
1094 			if( !bSelections || pItem->is_Selected() )
1095 			{
1096 				_Modified_Get(pParameters, pItem, Directory, ((CWKSP_Table *)pItem)->Get_Table() );
1097 			}
1098 			break;
1099 
1100 		case WKSP_ITEM_Shapes    :
1101 		case WKSP_ITEM_TIN       :
1102 		case WKSP_ITEM_PointCloud:
1103 		case WKSP_ITEM_Grid      :
1104 		case WKSP_ITEM_Grids     :
1105 			if( !bSelections || pItem->is_Selected() )
1106 			{
1107 				_Modified_Get(pParameters, pItem, Directory, ((CWKSP_Layer *)pItem)->Get_Object());
1108 			}
1109 			break;
1110 		}
1111 	}
1112 
1113 	return( true );
1114 }
1115 
1116 //---------------------------------------------------------
_Modified_Get(CSG_Parameters * pParameters,CWKSP_Base_Item * pItem,const wxString & Directory,CSG_Data_Object * pObject)1117 bool CWKSP_Data_Manager::_Modified_Get(CSG_Parameters *pParameters, CWKSP_Base_Item *pItem, const wxString &Directory, CSG_Data_Object *pObject)
1118 {
1119 	if( !pObject->is_Modified() )
1120 	{
1121 		return( false );
1122 	}
1123 
1124 	//-----------------------------------------------------
1125 	wxString	Filter, Extension;
1126 
1127 	switch( pItem->Get_Type() )
1128 	{
1129 	case WKSP_ITEM_Table     : Filter = DLG_Get_FILE_Filter(ID_DLG_TABLE_SAVE     ); Extension = "txt"     ; break;
1130 	case WKSP_ITEM_Shapes    : Filter = DLG_Get_FILE_Filter(ID_DLG_SHAPES_SAVE    ); Extension = SG_Shapes_Get_File_Extension_Default().c_str(); break;
1131 	case WKSP_ITEM_TIN       : Filter = DLG_Get_FILE_Filter(ID_DLG_TIN_SAVE       ); Extension = SG_Shapes_Get_File_Extension_Default().c_str(); break;
1132 	case WKSP_ITEM_PointCloud: Filter = DLG_Get_FILE_Filter(ID_DLG_POINTCLOUD_SAVE); Extension = "sg-pts-z"; break;
1133 	case WKSP_ITEM_Grid      : Filter = DLG_Get_FILE_Filter(ID_DLG_GRID_SAVE      ); Extension = SG_Grid_Get_File_Extension_Default().c_str(); break;
1134 	case WKSP_ITEM_Grids     : Filter = DLG_Get_FILE_Filter(ID_DLG_GRIDS_SAVE     ); Extension = "sg-gds-z"; break;
1135 	default:	return( false );
1136 	}
1137 
1138 	//-----------------------------------------------------
1139 	wxFileName	Path(pObject->Get_File_Name());
1140 
1141 	if( !Path.FileExists() )
1142 	{
1143 		wxString	Name(pObject->Get_Name());
1144 
1145 		Name.Replace(".", "-");
1146 		Name.Replace(":", "-");
1147 
1148 		Path.SetPath(Directory);
1149 		Path.SetExt (Extension);
1150 
1151 		for(int i=0, bOkay=false; !bOkay; i++)
1152 		{
1153 			if( i == 0 )
1154 			{
1155 				Path.SetName(Name);
1156 			}
1157 			else
1158 			{
1159 				Path.SetName(Name + wxString::Format("_%d", i));
1160 			}
1161 
1162 			bOkay	= !Path.FileExists();
1163 
1164 			for(int j=0; bOkay && j<pParameters->Get_Count(); j++)
1165 			{
1166 				CSG_Parameter	*p	= pParameters->Get_Parameter(j);
1167 
1168 				if( p->Get_Type() == PARAMETER_TYPE_FilePath && Path == p->asString() )
1169 				{
1170 					bOkay	= false;
1171 				}
1172 			}
1173 		}
1174 	}
1175 
1176 	//-----------------------------------------------------
1177 	CSG_String	Manager, Object;
1178 
1179 	Manager.Printf("%p", pItem->Get_Manager());
1180 
1181 	if( pParameters->Get_Parameter(Manager) == NULL )
1182 	{
1183 		pParameters->Add_Node("", Manager, pItem->Get_Manager()->Get_Name().wx_str(), "");
1184 	}
1185 
1186 	Object.Printf("%p", pObject);
1187 
1188 	pParameters->Add_Bool(Manager, Object, pItem->Get_Name().wx_str(), "", false);
1189 	pParameters->Add_FilePath(Object, Object + "FILE", _TL("File"), "", Filter, Path.GetFullPath(), true);
1190 
1191 	return( true );
1192 }
1193 
1194 //---------------------------------------------------------
_Modified_Save(CSG_Parameters * pParameters)1195 bool CWKSP_Data_Manager::_Modified_Save(CSG_Parameters *pParameters)
1196 {
1197 	for(int i=0; i<pParameters->Get_Count(); i++)
1198 	{
1199 		void			*Pointer;
1200 		CSG_Data_Object	*pObject;
1201 		CSG_Parameter	*pParameter	= pParameters->Get_Parameter(i);
1202 
1203 		if(	pParameter->Get_Type() == PARAMETER_TYPE_Bool && pParameter->asBool()
1204 		&&  SG_SSCANF(pParameter->Get_Identifier(), SG_T("%p"), &Pointer) == 1
1205 		&&  SG_Get_Data_Manager().Exists(pObject = (CSG_Data_Object *)Pointer) )
1206 		{
1207 			pParameter	= pParameters->Get_Parameter(CSG_String::Format("%pFILE", pObject));
1208 
1209 			if(	pParameter && pParameter->asString() && pParameter->asString()[0] )
1210 			{
1211 				pObject->Save(pParameter->asString());
1212 			}
1213 		}
1214 	}
1215 
1216 	return( true );
1217 }
1218 
1219 //---------------------------------------------------------
Save_Modified_Sel(void)1220 bool CWKSP_Data_Manager::Save_Modified_Sel(void)
1221 {
1222 	return( Save_Modified(this, true) );
1223 }
1224 
1225 //---------------------------------------------------------
Close(bool bSilent)1226 bool CWKSP_Data_Manager::Close(bool bSilent)
1227 {
1228 	if( Get_Count() == 0 || ((bSilent || DLG_Message_Confirm(_TL("Close all data sets"), _TL("Close"))) && Save_Modified(this)) )
1229 	{
1230 		m_pProject->Clr_File_Name();
1231 
1232 		g_pActive->Get_Parameters()->Restore_Parameters();
1233 
1234 		g_pSAGA_Frame->Close_Children();
1235 
1236 		g_pMaps->Close(true);
1237 
1238 		g_pData_Ctrl->Close(true);
1239 
1240 		return( true );
1241 	}
1242 
1243 	return( false );
1244 }
1245 
1246 
1247 ///////////////////////////////////////////////////////////
1248 //														 //
1249 ///////////////////////////////////////////////////////////
1250 
1251 //---------------------------------------------------------
Get_Manager(TSG_Data_Object_Type Type,bool bAdd)1252 CWKSP_Base_Manager * CWKSP_Data_Manager::Get_Manager(TSG_Data_Object_Type Type, bool bAdd)
1253 {
1254 	#define GET_MANAGER(pManager, Class)	if( !pManager && bAdd ) Add_Item(pManager = new Class); return( pManager );
1255 
1256 	switch( Type )
1257 	{
1258 	case SG_DATAOBJECT_TYPE_Table     : GET_MANAGER(m_pTables     , CWKSP_Table_Manager     );
1259 	case SG_DATAOBJECT_TYPE_TIN       : GET_MANAGER(m_pTINs       , CWKSP_TIN_Manager       );
1260 	case SG_DATAOBJECT_TYPE_PointCloud: GET_MANAGER(m_pPointClouds, CWKSP_PointCloud_Manager);
1261 	case SG_DATAOBJECT_TYPE_Shapes    : GET_MANAGER(m_pShapes     , CWKSP_Shapes_Manager    );
1262 	case SG_DATAOBJECT_TYPE_Grid      : GET_MANAGER(m_pGrids      , CWKSP_Grid_Manager      );
1263 	case SG_DATAOBJECT_TYPE_Grids     : GET_MANAGER(m_pGrids      , CWKSP_Grid_Manager      );
1264 	default:	break;
1265 	}
1266 
1267 	return( NULL );
1268 }
1269 
1270 //---------------------------------------------------------
Get(CSG_Data_Object * pObject)1271 CWKSP_Data_Item * CWKSP_Data_Manager::Get(CSG_Data_Object *pObject)
1272 {
1273 	if( pObject && pObject != DATAOBJECT_CREATE && Get_Manager(pObject->Get_ObjectType()) )
1274 	{
1275 		switch( pObject->Get_ObjectType() )
1276 		{
1277 		case SG_DATAOBJECT_TYPE_Table     : return( (CWKSP_Data_Item *)m_pTables     ->Get_Data((CSG_Table      *)pObject) );
1278 		case SG_DATAOBJECT_TYPE_TIN       : return( (CWKSP_Data_Item *)m_pTINs       ->Get_Data((CSG_TIN        *)pObject) );
1279 		case SG_DATAOBJECT_TYPE_PointCloud: return( (CWKSP_Data_Item *)m_pPointClouds->Get_Data((CSG_PointCloud *)pObject) );
1280 		case SG_DATAOBJECT_TYPE_Shapes    : return( (CWKSP_Data_Item *)m_pShapes     ->Get_Data((CSG_Shapes     *)pObject) );
1281 		case SG_DATAOBJECT_TYPE_Grid      : return( (CWKSP_Data_Item *)m_pGrids      ->Get_Data((CSG_Grid       *)pObject) );
1282 		case SG_DATAOBJECT_TYPE_Grids     : return( (CWKSP_Data_Item *)m_pGrids      ->Get_Data((CSG_Grids      *)pObject) );
1283 		default:	break;
1284 		}
1285 	}
1286 
1287 	return( NULL );
1288 }
1289 
1290 //---------------------------------------------------------
Add(CSG_Data_Object * pObject)1291 CWKSP_Data_Item * CWKSP_Data_Manager::Add(CSG_Data_Object *pObject)
1292 {
1293 	if( SG_Get_Data_Manager().Add(pObject) && Get_Manager(pObject->Get_ObjectType(), true) )
1294 	{
1295 		switch( pObject->Get_ObjectType() )
1296 		{
1297 		case SG_DATAOBJECT_TYPE_Table     : return( (CWKSP_Data_Item *)m_pTables     ->Add_Data((CSG_Table      *)pObject) );
1298 		case SG_DATAOBJECT_TYPE_TIN       : return( (CWKSP_Data_Item *)m_pTINs       ->Add_Data((CSG_TIN        *)pObject) );
1299 		case SG_DATAOBJECT_TYPE_PointCloud: return( (CWKSP_Data_Item *)m_pPointClouds->Add_Data((CSG_PointCloud *)pObject) );
1300 		case SG_DATAOBJECT_TYPE_Shapes    : return( (CWKSP_Data_Item *)m_pShapes     ->Add_Data((CSG_Shapes     *)pObject) );
1301 		case SG_DATAOBJECT_TYPE_Grid      : return( (CWKSP_Data_Item *)m_pGrids      ->Add_Data((CSG_Grid       *)pObject) );
1302 		case SG_DATAOBJECT_TYPE_Grids     : return( (CWKSP_Data_Item *)m_pGrids      ->Add_Data((CSG_Grids      *)pObject) );
1303 		default:	break;
1304 		}
1305 	}
1306 
1307 	return( NULL );
1308 }
1309 
1310 //---------------------------------------------------------
Get_Layer(CSG_Data_Object * pObject)1311 CWKSP_Layer * CWKSP_Data_Manager::Get_Layer(CSG_Data_Object *pObject)
1312 {
1313 	if( pObject && pObject != DATAOBJECT_CREATE && Get_Manager(pObject->Get_ObjectType()) )
1314 	{
1315 		switch( pObject->Get_ObjectType() )
1316 		{
1317 		case SG_DATAOBJECT_TYPE_TIN       : return( (CWKSP_Layer *)m_pTINs       ->Get_Data((CSG_TIN        *)pObject) );
1318 		case SG_DATAOBJECT_TYPE_PointCloud: return( (CWKSP_Layer *)m_pPointClouds->Get_Data((CSG_PointCloud *)pObject) );
1319 		case SG_DATAOBJECT_TYPE_Shapes    : return( (CWKSP_Layer *)m_pShapes     ->Get_Data((CSG_Shapes     *)pObject) );
1320 		case SG_DATAOBJECT_TYPE_Grid      : return( (CWKSP_Layer *)m_pGrids      ->Get_Data((CSG_Grid       *)pObject) );
1321 		case SG_DATAOBJECT_TYPE_Grids     : return( (CWKSP_Layer *)m_pGrids      ->Get_Data((CSG_Grids      *)pObject) );
1322 		default:	break;
1323 		}
1324 	}
1325 
1326 	return( NULL );
1327 }
1328 
1329 //---------------------------------------------------------
Del_Manager(CWKSP_Base_Item * pItem)1330 void CWKSP_Data_Manager::Del_Manager(CWKSP_Base_Item *pItem)
1331 {
1332 	if( pItem == m_pTables      )	m_pTables		= NULL;
1333 	if( pItem == m_pTINs        )	m_pTINs			= NULL;
1334 	if( pItem == m_pPointClouds )	m_pPointClouds	= NULL;
1335 	if( pItem == m_pShapes      )	m_pShapes		= NULL;
1336 	if( pItem == m_pGrids       )	m_pGrids		= NULL;
1337 
1338 	if( Get_Count() == 0 )
1339 	{
1340 		m_pProject->Clr_File_Name();
1341 	}
1342 }
1343 
1344 
1345 ///////////////////////////////////////////////////////////
1346 //														 //
1347 ///////////////////////////////////////////////////////////
1348 
1349 //---------------------------------------------------------
Update(CSG_Data_Object * pObject,CSG_Parameters * pParameters)1350 bool CWKSP_Data_Manager::Update(CSG_Data_Object *pObject, CSG_Parameters *pParameters)
1351 {
1352 	CWKSP_Data_Item	*pItem	= Get(pObject);
1353 
1354 	if( !pItem )
1355 	{
1356 		return( false );
1357 	}
1358 
1359 	if( SG_Get_Data_Manager().Exists(pObject) )
1360 	{
1361 		pItem->Get_Parameters()->Assign_Values(pParameters);
1362 
1363 		return( pItem->DataObject_Changed() );
1364 	}
1365 
1366 	Get_Control()->Del_Item(pItem, true);
1367 
1368 	return( true );
1369 }
1370 
1371 //---------------------------------------------------------
Update_Views(CSG_Data_Object * pObject)1372 bool CWKSP_Data_Manager::Update_Views(CSG_Data_Object *pObject)
1373 {
1374 	CWKSP_Data_Item	*pItem	= Get(pObject);
1375 
1376 	return( pItem && pItem->Update_Views() );
1377 }
1378 
1379 //---------------------------------------------------------
Show(CSG_Data_Object * pObject,int Flags)1380 bool CWKSP_Data_Manager::Show(CSG_Data_Object *pObject, int Flags)
1381 {
1382 	CWKSP_Data_Item	*pItem	= Get(pObject);
1383 
1384 	return( pItem && pItem->Show(Flags) );
1385 }
1386 
1387 //---------------------------------------------------------
asImage(CSG_Data_Object * pObject,CSG_Grid * pImage)1388 bool CWKSP_Data_Manager::asImage(CSG_Data_Object *pObject, CSG_Grid *pImage)
1389 {
1390 	CWKSP_Layer	*pLayer	= Get_Layer(pObject);
1391 
1392 	return( pLayer && pLayer->asImage(pImage) );
1393 }
1394 
1395 //---------------------------------------------------------
Get_Colors(CSG_Data_Object * pObject,CSG_Colors * pColors)1396 bool CWKSP_Data_Manager::Get_Colors(CSG_Data_Object *pObject, CSG_Colors *pColors)
1397 {
1398 	CWKSP_Layer	*pLayer	= Get_Layer(pObject);
1399 
1400 	return( pLayer && pLayer->Get_Colors(pColors) );
1401 }
1402 
1403 //---------------------------------------------------------
Set_Colors(CSG_Data_Object * pObject,CSG_Colors * pColors)1404 bool CWKSP_Data_Manager::Set_Colors(CSG_Data_Object *pObject, CSG_Colors *pColors)
1405 {
1406 	if( m_Parameters("COLORS_FROM_TOOL")->asBool() == false )
1407 	{
1408 		return( true );
1409 	}
1410 
1411 	CWKSP_Layer	*pLayer	= Get_Layer(pObject);
1412 
1413 	return( pLayer && pLayer->Set_Colors(pColors) );
1414 }
1415 
1416 //---------------------------------------------------------
Get_Parameters(CSG_Data_Object * pObject,CSG_Parameters * pParameters)1417 bool CWKSP_Data_Manager::Get_Parameters(CSG_Data_Object *pObject, CSG_Parameters *pParameters)
1418 {
1419 	CWKSP_Data_Item	*pItem	= pParameters ? Get(pObject) : NULL;
1420 
1421 	return( pItem && pParameters->Assign(pItem->Get_Parameters()) );
1422 }
1423 
1424 //---------------------------------------------------------
Set_Parameters(CSG_Data_Object * pObject,CSG_Parameters * pParameters)1425 bool CWKSP_Data_Manager::Set_Parameters(CSG_Data_Object *pObject, CSG_Parameters *pParameters)
1426 {
1427 	CWKSP_Data_Item	*pItem	= pParameters ? Get(pObject) : NULL;
1428 
1429 	if( pItem && pItem->Get_Parameters()->Assign_Values(pParameters) )
1430 	{
1431 		pItem->Parameters_Changed();
1432 
1433 		return( true );
1434 	}
1435 
1436 	return( false );
1437 }
1438 
1439 
1440 ///////////////////////////////////////////////////////////
1441 //														 //
1442 ///////////////////////////////////////////////////////////
1443 
1444 //---------------------------------------------------------
MultiSelect_Count(void)1445 size_t CWKSP_Data_Manager::MultiSelect_Count(void)
1446 {
1447 	return( m_Sel_Items.Count() );
1448 }
1449 
1450 //---------------------------------------------------------
MultiSelect_Check(void)1451 bool CWKSP_Data_Manager::MultiSelect_Check(void)
1452 {
1453 	enum
1454 	{
1455 		TYPE_Table,
1456 		TYPE_Shapes_Point,
1457 		TYPE_Shapes_Points,
1458 		TYPE_Shapes_Line,
1459 		TYPE_Shapes_Polygon,
1460 		TYPE_TIN,
1461 		TYPE_PointCloud,
1462 		TYPE_Grid,
1463 		TYPE_Grids,
1464 		TYPE_Undefined
1465 	};
1466 
1467 	//-----------------------------------------------------
1468 	wxArrayTreeItemIds	IDs;
1469 
1470 	if( Get_Control()->GetSelections(IDs) > 1 )
1471 	{
1472 		int	iType, Type	= TYPE_Undefined;
1473 
1474 		for(size_t iID=0; iID<IDs.Count(); iID++)
1475 		{
1476 			CWKSP_Base_Item	*pItem	= (CWKSP_Base_Item *)Get_Control()->GetItemData(IDs[iID]);
1477 
1478 			switch( pItem->Get_Type() )
1479 			{
1480 			default                    :	iType	= TYPE_Undefined     ;	break;
1481 			case WKSP_ITEM_Table       :	iType	= TYPE_Table         ;	break;
1482 			case WKSP_ITEM_TIN         :	iType	= TYPE_TIN           ;	break;
1483 			case WKSP_ITEM_PointCloud  :	iType	= TYPE_PointCloud    ;	break;
1484 			case WKSP_ITEM_Grid        :	iType	= TYPE_Grid          ;	break;
1485 			case WKSP_ITEM_Grids       :	iType	= TYPE_Grids         ;	break;
1486 			case WKSP_ITEM_Shapes      :	switch( ((CWKSP_Shapes *)pItem)->Get_Shapes()->Get_Type() )
1487 				{
1488 				default                :	iType	= TYPE_Undefined     ;	break;
1489 				case SHAPE_TYPE_Point  :	iType	= TYPE_Shapes_Point  ;	break;
1490 				case SHAPE_TYPE_Points :	iType	= TYPE_Shapes_Points ;	break;
1491 				case SHAPE_TYPE_Line   :	iType	= TYPE_Shapes_Line   ;	break;
1492 				case SHAPE_TYPE_Polygon:	iType	= TYPE_Shapes_Polygon;	break;
1493 				}
1494 				break;
1495 			}
1496 
1497 			//---------------------------------------------
1498 			if( iType != TYPE_Undefined )
1499 			{
1500 				if( Type == TYPE_Undefined )
1501 				{
1502 					Type	= iType;
1503 
1504 					m_Sel_Parms[0].Assign(pItem->Get_Parameters());
1505 
1506 					m_Sel_Items.Clear();
1507 
1508 					m_Sel_Items.Add(IDs[iID]);
1509 				}
1510 				else if( Type == iType )
1511 				{
1512 					m_Sel_Parms[0].Set_Callback(false);
1513 
1514 					m_Sel_Items.Add(IDs[iID]);
1515 
1516 					for(int i=0; i<m_Sel_Parms[0].Get_Count(); i++)
1517 					{
1518 						CSG_Parameter	&Parameter	= m_Sel_Parms[0][i];
1519 
1520 						CSG_Parameter	*pParameter	= pItem->Get_Parameters()->Get_Parameter(Parameter.Get_Identifier());
1521 
1522 						if( !Parameter.is_Compatible(pParameter) )
1523 						{
1524 							m_Sel_Parms[0].Del_Parameter(i--);
1525 						}
1526 						else if( !Parameter.is_Value_Equal(pParameter) )
1527 						{
1528 							if( Parameter.is_DataObject() )
1529 							{
1530 								Parameter.Set_Value(DATAOBJECT_NOTSET);
1531 							}
1532 							else if( Parameter.is_DataObject_List() )
1533 							{
1534 								Parameter.asList()->Del_Items();
1535 							}
1536 							else switch( Parameter.Get_Type() )
1537 							{
1538 							default:
1539 								Parameter.Restore_Default();
1540 								break;
1541 
1542 							case PARAMETER_TYPE_Bool       :
1543 							case PARAMETER_TYPE_Int        :
1544 							case PARAMETER_TYPE_Double     :
1545 							case PARAMETER_TYPE_Degree     :
1546 							case PARAMETER_TYPE_Color      :
1547 							case PARAMETER_TYPE_Table_Field:
1548 							case PARAMETER_TYPE_Choice     :	Parameter.Set_Value(0.0);	break;
1549 
1550 							case PARAMETER_TYPE_Choices    :
1551 							case PARAMETER_TYPE_String     :
1552 							case PARAMETER_TYPE_Text       :
1553 							case PARAMETER_TYPE_FilePath   :	Parameter.Set_Value("");	break;
1554 							}
1555 						}
1556 					}
1557 
1558 					m_Sel_Parms[0].Set_Callback(true);
1559 				}
1560 				else //  Type != iType
1561 				{
1562 					IDs.Clear();
1563 				}
1564 			}
1565 		}
1566 
1567 		//-------------------------------------------------
1568 		if( IDs.Count() > 0 )
1569 		{
1570 			m_Sel_Parms[1]	= m_Sel_Parms[0];
1571 
1572 			if( g_pActive->Get_Active() == this )
1573 			{
1574 				g_pActive->Get_Parameters()->Update_Parameters(&m_Sel_Parms[0], false);
1575 			}
1576 
1577 			return( true );
1578 		}
1579 	}
1580 
1581 	//-----------------------------------------------------
1582 	m_Sel_Items.Clear();
1583 
1584 	m_Sel_Parms[0].Destroy();
1585 	m_Sel_Parms[1].Destroy();
1586 
1587 	return( false );
1588 }
1589 
1590 //---------------------------------------------------------
MultiSelect_Update(void)1591 bool CWKSP_Data_Manager::MultiSelect_Update(void)
1592 {
1593 	if( m_Sel_Items.Count() == 0 )
1594 	{
1595 		return( false );
1596 	}
1597 
1598 	CSG_Parameters	Changed;
1599 
1600 	for(int i=0; i<m_Sel_Parms[0].Get_Count(); i++)		// compare to backup list [1] to detect changed parameters
1601 	{
1602 		if( !m_Sel_Parms[0][i].is_Value_Equal(&m_Sel_Parms[1][i]) )
1603 		{
1604 			Changed.Add_Parameter(&m_Sel_Parms[0][i]);
1605 		}
1606 	}
1607 
1608 	for(size_t iID=0; iID<m_Sel_Items.Count(); iID++)	// assign changed values to selected data set parameters
1609 	{
1610 		CWKSP_Data_Item	*pItem	= (CWKSP_Data_Item *)Get_Control()->GetItemData(m_Sel_Items[iID]);
1611 
1612 		pItem->Get_Parameters()->Assign_Values(&Changed);
1613 
1614 		pItem->Parameters_Changed();
1615 	}
1616 
1617 	m_Sel_Parms[1].Assign_Values(&m_Sel_Parms[0]);		// update backup list with changed values
1618 
1619 	return( true );
1620 }
1621 
1622 
1623 ///////////////////////////////////////////////////////////
1624 //														 //
1625 //														 //
1626 //														 //
1627 ///////////////////////////////////////////////////////////
1628 
1629 //---------------------------------------------------------
1630