SAGA API v9.10
Loading...
Searching...
No Matches
tool_chain.cpp
Go to the documentation of this file.
1
3// //
4// SAGA //
5// //
6// System for Automated Geoscientific Analyses //
7// //
8// Application Programming Interface //
9// //
10// Library: SAGA_API //
11// //
12//-------------------------------------------------------//
13// //
14// tool_chain.cpp //
15// //
16// Copyright (C) 2014 by Olaf Conrad //
17// //
18//-------------------------------------------------------//
19// //
20// This file is part of 'SAGA - System for Automated //
21// Geoscientific Analyses'. //
22// //
23// This library is free software; you can redistribute //
24// it and/or modify it under the terms of the GNU Lesser //
25// General Public License as published by the Free //
26// Software Foundation, either version 2.1 of the //
27// License, or (at your option) any later version. //
28// //
29// This library is distributed in the hope that it will //
30// be useful, but WITHOUT ANY WARRANTY; without even the //
31// implied warranty of MERCHANTABILITY or FITNESS FOR A //
32// PARTICULAR PURPOSE. See the GNU Lesser General Public //
33// License for more details. //
34// //
35// You should have received a copy of the GNU Lesser //
36// General Public License along with this program; if //
37// not, see <http://www.gnu.org/licenses/>. //
38// //
39//-------------------------------------------------------//
40// //
41// contact: Olaf Conrad //
42// Institute of Geography //
43// University of Hamburg //
44// Germany //
45// //
46// e-mail: oconrad@saga-gis.org //
47// //
49
50//---------------------------------------------------------
51#include "saga_api.h"
52
53#include "tool_chain.h"
54
55
57// //
58// //
59// //
61
62//---------------------------------------------------------
63#define GET_XML_CONTENT(XML, ID, DEFAULT, TRANSLATE) (!XML(ID) ? CSG_String(DEFAULT) : !TRANSLATE ? XML[ID].Get_Content() : CSG_String(SG_Translate(XML[ID].Get_Content())))
64
65#define IS_TRUE_STRING(String) (!String.CmpNoCase("true") || !String.CmpNoCase("1"))
66#define IS_TRUE_PROPERTY(Item, Property) (Item.Cmp_Property(Property, "true", true) || Item.Cmp_Property(Property, "1"))
67
68#define Get_List_Count(p) (p->asGridList() ? p->asGridList()->Get_Grid_Count() : p->asList() ? p->asList()->Get_Item_Count() : 0)
69#define Get_List_Item(p, i) (p->asGridList() ? p->asGridList()->Get_Grid (i) : p->asList() ? p->asList()->Get_Item (i) : NULL)
70
71
73// //
74// //
75// //
77
78//---------------------------------------------------------
80{
81 // nop
82}
83
84//---------------------------------------------------------
85CSG_Tool_Chain::CSG_Tool_Chain(const CSG_Tool_Chain &Tool, bool bWithGUI, bool bWithCMD)
86{
87 Create(Tool, bWithGUI, bWithCMD);
88}
89
90//---------------------------------------------------------
92{
93 Create(File);
94}
95
96//---------------------------------------------------------
101
102//---------------------------------------------------------
104{
105 Reset();
106}
107
108//---------------------------------------------------------
109void CSG_Tool_Chain::Reset(void)
110{
113
114 m_Chain.Destroy();
115
116 m_Conditions.Destroy();
117
118 m_Menu.Clear();
119}
120
121//---------------------------------------------------------
123{
124 m_Library_Menu = Menu;
125}
126
127
129// //
131
132//---------------------------------------------------------
133bool CSG_Tool_Chain::Create(const CSG_Tool_Chain &Tool, bool bWithGUI, bool bWithCMD)
134{
135 if( !Create(Tool.m_Chain) )
136 {
137 return( false );
138 }
139
140 m_ID = Tool.m_ID;
141 m_Library = Tool.m_Library;
142 m_Library_Menu = Tool.m_Library_Menu;
143 m_File_Name = Tool.m_File_Name;
144 m_bGUI = bWithGUI && m_bGUI;
145 m_bCMD = bWithCMD && m_bCMD;
146
147 return( true );
148}
149
150//---------------------------------------------------------
152{
153 if( !SG_File_Cmp_Extension(File, "xml") )
154 {
155 return( false );
156 }
157
158 if( File.Right(sizeof(".pyt.xml")).Make_Lower().Find(".pyt.xml") >= 0 )
159 {
160 return( false );
161 }
162
164
165 if( !Chain.Load(File) )
166 {
167 Error_Fmt("%s: %s", _TL("failed to load or parse xml file"), File.c_str());
168
169 return( false );
170 }
171
172 if( Chain.Cmp_Name("toolchains") ) // don't report any error, this xml-file provides info for a category of tool chains
173 {
174 return( false );
175 }
176
177 if( !Chain.Cmp_Name("toolchain") || !Chain("identifier") || !Chain("parameters") )
178 {
179 Error_Fmt("%s: %s", _TL("xml file is not a valid tool chain"), File.c_str());
180
181 return( false );
182 }
183
184 //-----------------------------------------------------
185 SG_UI_Msg_Add(CSG_String::Format("%s: %s...", File.Cmp(m_File_Name) ? _TL("Loading tool chain") : _TL("Reloading tool chain"), File.c_str()), true);
186
187 if( Create(Chain) )
188 {
189 m_File_Name = File;
190
192
193 return( true );
194 }
195
196 m_File_Name.Clear(); Reset();
197
198 SG_UI_Msg_Add(_TL("failed"), false, SG_UI_MSG_STYLE_FAILURE);
199
200 return( false );
201}
202
203//---------------------------------------------------------
205{
206 if( !Chain.Cmp_Name("toolchain") || !Chain("identifier") || !Chain("parameters") || !Chain("tools") )
207 {
208 return( false );
209 }
210
211 if( SG_Compare_Version(Chain.Get_Property("saga-version"), "2.1.3") < 0 )
212 {
213 Error_Fmt("%s %s: %s", _TL("Warning"), _TL("unsupported tool chain version"), Chain.Get_Property("saga-version"));
214 }
215
216 //-----------------------------------------------------
217 Reset();
218
219 m_Chain = Chain;
220 m_ID = GET_XML_CONTENT(m_Chain, "identifier" , "" , false) ;
221 m_Library = GET_XML_CONTENT(m_Chain, "group" , "toolchains" , false) ;
222 m_Menu = GET_XML_CONTENT(m_Chain, "menu" , "" , true) ;
223 Set_Name (GET_XML_CONTENT(m_Chain, "name" , _TL("Not Named" ), true));
224 Set_Author (GET_XML_CONTENT(m_Chain, "author" , _TL("unknown" ), false));
225 Set_Description (GET_XML_CONTENT(m_Chain, "description", _TL("no description"), true));
226
227 if( m_Library.is_Empty() )
228 {
229 m_Library = "toolchains";
230 }
231
232 Add_References();
233
234 CSG_String Description = Get_Description();
235 Description.Replace("[[", "<"); // support for xml/html tags
236 Description.Replace("]]", ">");
237 Set_Description(Description);
238
239 if( !m_Menu.is_Empty() && (m_Menu.Length() < 2 || m_Menu[1] != ':') )
240 {
241 if( IS_TRUE_PROPERTY(m_Chain["menu"], "absolute") )
242 m_Menu.Prepend("A:"); // absolute path
243 else
244 m_Menu.Prepend("R:"); // relative path
245 }
246
247 m_bAddHistory = IS_TRUE_PROPERTY(m_Chain["tools"], "history");
248
249 //-----------------------------------------------------
250 for(int i=0; i<m_Chain["parameters"].Get_Children_Count(); i++)
251 {
252 const CSG_MetaData &Parameter = m_Chain["parameters"][i];
253
254 CSG_String ID = Parameter.Get_Property("varname");
255
256 if( ID.is_Empty() || Parameters(ID) )
257 {
258 continue;
259 }
260
261 if( Parameter.Get_Property("with_gui") && !IS_TRUE_PROPERTY(Parameter, "with_gui") && has_GUI() == false )
262 {
263 continue;
264 }
265
266 if( Parameter.Get_Property("with_cmd") && !IS_TRUE_PROPERTY(Parameter, "with_cmd") && has_GUI() != false )
267 {
268 continue;
269 }
270
271 //-------------------------------------------------
272 int Constraint = 0;
273 CSG_String Value;
274 bool bMin = false, bMax = false;
275 double Min = 0. , Max = 0.;
276
277 if( Parameter.Cmp_Name("input") )
278 {
279 Constraint = IS_TRUE_PROPERTY(Parameter, "optional") ? PARAMETER_INPUT_OPTIONAL : PARAMETER_INPUT;
280 }
281 else if( Parameter.Cmp_Name("output") )
282 {
283 Constraint = IS_TRUE_PROPERTY(Parameter, "optional") ? PARAMETER_OUTPUT_OPTIONAL : PARAMETER_OUTPUT;
284 }
285 else if( Parameter.Cmp_Name("option") && Parameter("value") )
286 {
287 Value = Parameter.Get_Content("value");
288
289 bMin = Parameter["value"].Get_Property("min", Min);
290 bMax = Parameter["value"].Get_Property("max", Max);
291 }
292
293 //-------------------------------------------------
294 if( Parameter("condition") )
295 {
296 CSG_MetaData &Conditions = *m_Conditions.Add_Child(ID);
297
298 for(int j=0; j<Parameter.Get_Children_Count(); j++) // there might be more than one condition to be checked
299 {
300 if( Parameter[j].Cmp_Name("condition") )
301 {
302 Conditions.Add_Child(Parameter[j]);
303 }
304 }
305 }
306
307 //-------------------------------------------------
308 CSG_String Name = SG_Translate(Parameter.Get_Content("name" ));
309 CSG_String Desc = SG_Translate(Parameter.Get_Content("description"));
310
311 CSG_Parameter *pParent = Parameters(Parameter.Get_Property("parent"));
312 CSG_String ParentID(pParent ? pParent->Get_Identifier() : SG_T(""));
313
314 //-------------------------------------------------
315 switch( SG_Parameter_Type_Get_Type(Parameter.Get_Property("type")) )
316 {
317 case PARAMETER_TYPE_Node : Parameters.Add_Node (ParentID, ID, Name, Desc); break;
318
319 case PARAMETER_TYPE_Bool : Parameters.Add_Bool (ParentID, ID, Name, Desc, IS_TRUE_STRING(Value)); break;
320 case PARAMETER_TYPE_Int : Parameters.Add_Int (ParentID, ID, Name, Desc, Value.asInt (), (int)Min, bMin, (int)Max, bMax); break;
321 case PARAMETER_TYPE_Double : Parameters.Add_Double (ParentID, ID, Name, Desc, Value.asDouble(), Min, bMin, Max, bMax); break;
322 case PARAMETER_TYPE_Degree : Parameters.Add_Degree (ParentID, ID, Name, Desc, Value.asDouble(), Min, bMin, Max, bMax); break;
323
324 case PARAMETER_TYPE_Date : Parameters.Add_Date (ParentID, ID, Name, Desc, 0.)->Set_Value(Value); break;
325
326 case PARAMETER_TYPE_Range : Parameters.Add_Range (ParentID, ID, Name, Desc, Value.BeforeFirst(';').asDouble(), Value.AfterFirst(';').asDouble(), Min, bMin, Max, bMax); break;
328 case PARAMETER_TYPE_Choice : Parameters.Add_Choice (ParentID, ID, Name, Desc, Parameter.Get_Content("choices"))->Set_Value(Value); break;
329 case PARAMETER_TYPE_Choices : Parameters.Add_Choices (ParentID, ID, Name, Desc, Parameter.Get_Content("choices"))->Set_Value(Value); break;
330
331 case PARAMETER_TYPE_String : Parameters.Add_String (ParentID, ID, Name, Desc, Value, false); break;
332 case PARAMETER_TYPE_Text : Parameters.Add_String (ParentID, ID, Name, Desc, Value, true); break;
333
334 case PARAMETER_TYPE_FilePath : Parameters.Add_FilePath (ParentID, ID, Name, Desc, Parameter.Get_Content("filter"), Value,
335 IS_TRUE_PROPERTY(Parameter, "save" ),
336 IS_TRUE_PROPERTY(Parameter, "directory"),
337 IS_TRUE_PROPERTY(Parameter, "multiple" )
338 ); break;
339
340 case PARAMETER_TYPE_Font : break;
341 case PARAMETER_TYPE_Color : Parameters.Add_Color (ParentID, ID, Name, Desc, Value.asInt()); break;
342 case PARAMETER_TYPE_Colors : Parameters.Add_Colors (ParentID, ID, Name, Desc); break;
343 case PARAMETER_TYPE_FixedTable : Parameters.Add_FixedTable (ParentID, ID, Name, Desc)->Serialize(*Parameter("option"), false); break;
344
345 case PARAMETER_TYPE_Grid_System : Parameters.Add_Grid_System (ParentID, ID, Name, Desc); break;
346
347 case PARAMETER_TYPE_Table_Field : Parameters.Add_Table_Field (ParentID, ID, Name, Desc, (!Value.CmpNoCase("true") || !Value.CmpNoCase("1"))); break;
348 case PARAMETER_TYPE_Table_Fields : Parameters.Add_Table_Fields (ParentID, ID, Name, Desc); break;
349
350 case PARAMETER_TYPE_Grid : Parameter.Cmp_Property("target", "none")
351 ? Parameters.Add_Grid_Output ( "", ID, Name, Desc)
352 : Parameters.Add_Grid (ParentID, ID, Name, Desc, Constraint); break;
353
354 case PARAMETER_TYPE_Grids : Parameter.Cmp_Property("target", "none")
355 ? Parameters.Add_Grids_Output ( "", ID, Name, Desc)
356 : Parameters.Add_Grids (ParentID, ID, Name, Desc, Constraint); break;
357
358 case PARAMETER_TYPE_Table : Parameters.Add_Table (ParentID, ID, Name, Desc, Constraint); break;
359
360 case PARAMETER_TYPE_Shapes : Parameters.Add_Shapes (ParentID, ID, Name, Desc, Constraint,
361 Parameter.Cmp_Property("feature_type", "point" ) ? SHAPE_TYPE_Point :
362 Parameter.Cmp_Property("feature_type", "points" ) ? SHAPE_TYPE_Points :
363 Parameter.Cmp_Property("feature_type", "line" ) ? SHAPE_TYPE_Line :
364 Parameter.Cmp_Property("feature_type", "polygon") ? SHAPE_TYPE_Polygon : SHAPE_TYPE_Undefined
365 ); break;
366
367 case PARAMETER_TYPE_TIN : Parameters.Add_TIN (ParentID, ID, Name, Desc, Constraint); break;
368 case PARAMETER_TYPE_PointCloud : Parameters.Add_PointCloud (ParentID, ID, Name, Desc, Constraint); break;
369
370 case PARAMETER_TYPE_Grid_List : Parameters.Add_Grid_List (ParentID, ID, Name, Desc, Constraint, !IS_TRUE_PROPERTY(Parameter, "no_system")); break;
371 case PARAMETER_TYPE_Grids_List : Parameters.Add_Grids_List (ParentID, ID, Name, Desc, Constraint, !IS_TRUE_PROPERTY(Parameter, "no_system")); break;
372 case PARAMETER_TYPE_Table_List : Parameters.Add_Table_List (ParentID, ID, Name, Desc, Constraint); break;
373 case PARAMETER_TYPE_Shapes_List : Parameters.Add_Shapes_List (ParentID, ID, Name, Desc, Constraint); break;
374 case PARAMETER_TYPE_TIN_List : Parameters.Add_TIN_List (ParentID, ID, Name, Desc, Constraint); break;
375 case PARAMETER_TYPE_PointCloud_List : Parameters.Add_PointCloud_List(ParentID, ID, Name, Desc, Constraint); break;
376
378 case PARAMETER_TYPE_Parameters : break; // to do ?
379
380 default: break;
381 }
382 }
383
384 //-----------------------------------------------------
385 return( is_Okay() );
386}
387
388
390// //
392
393//---------------------------------------------------------
395{
396 return( !m_Chain("CRS_SYNC") || IS_TRUE_STRING(m_Chain["CRS_SYNC"].Get_Content()) );
397}
398
399//---------------------------------------------------------
400void CSG_Tool_Chain::Add_References(void)
401{
402 for(int i=0; i<m_Chain.Get_Children_Count(); i++)
403 {
404 if( !m_Chain[i].Get_Name().CmpNoCase("REFERENCE") )
405 {
406 CSG_String Authors, Year, Title, Where, Link, Link_Text, DOI;
407
408 if( m_Chain[i]("AUTHORS" ) ) Authors = m_Chain[i].Get_Content("AUTHORS" );
409 if( m_Chain[i]("YEAR" ) ) Year = m_Chain[i].Get_Content("YEAR" );
410 if( m_Chain[i]("TITLE" ) ) Title = m_Chain[i].Get_Content("TITLE" );
411 if( m_Chain[i]("WHERE" ) ) Where = m_Chain[i].Get_Content("WHERE" );
412 if( m_Chain[i]("LINK" ) ) Link = m_Chain[i].Get_Content("LINK" );
413 if( m_Chain[i]("LINK_TEXT") ) Link_Text = m_Chain[i].Get_Content("LINK_TEXT");
414 if( m_Chain[i]("DOI" ) ) DOI = m_Chain[i].Get_Content("DOI" );
415
416 if( !DOI.is_Empty() )
417 {
418 Link = "https://doi.org/" + DOI; Link_Text = "doi:" + DOI;
419 }
420
421 if( !Authors.is_Empty() && !Year.is_Empty() && !Title.is_Empty() )
422 {
423 Add_Reference(Authors, Year, Title, Where, Link.c_str(), Link_Text.c_str());
424 }
425 else if( !Link.is_Empty() )
426 {
427 Add_Reference(Link, Link_Text.c_str());
428 }
429 }
430 }
431}
432
433
435// //
437
438//---------------------------------------------------------
440{
441 for(int iParameter=0; iParameter<m_Conditions.Get_Children_Count(); iParameter++)
442 {
443 const CSG_MetaData &Conditions = m_Conditions[iParameter];
444
445 if( (*pParameters)(Conditions.Get_Name()) )
446 {
447 bool bEnable = true;
448
449 for(int iCondition=0; bEnable && iCondition<Conditions.Get_Children_Count(); iCondition++)
450 {
451 bEnable = Check_Condition(Conditions[iCondition], pParameters);
452 }
453
454 (*pParameters)(Conditions.Get_Name())->Set_Enabled(bEnable);
455 }
456 }
457
458 return( CSG_Tool::On_Parameters_Enable(pParameters, pParameter) );
459}
460
461
463// //
465
466//---------------------------------------------------------
468{
469 bool bResult = Data_Initialize();
470
471 if( !bResult )
472 {
473 Error_Set(_TL("no data objects"));
474 }
475
476 for(int i=0; bResult && i<m_Chain["tools"].Get_Children_Count(); i++)
477 {
478 bResult = Tool_Run(m_Chain["tools"][i]);
479 }
480
481 Data_Finalize();
482
483 return( bResult );
484}
485
486
488// //
490
491//---------------------------------------------------------
492bool CSG_Tool_Chain::Data_Add(const CSG_String &ID, CSG_Parameter *pData)
493{
494 if( !pData )
495 {
496 return( false );
497 }
498
499 CSG_Parameter *pParameter = m_Data(ID); // check if the local data manager already has a parameter with this identifier
500
501 if( pParameter ) // it has, so don't add twice!
502 {
503 if( pParameter->is_Input() && pParameter->Get_Type() != pData->Get_Type() ) // don't allow to change parameter's data object type!
504 {
505 Error_Fmt("%s\n[%s] %s <> %s", _TL("Tool chain uses same variable name for different data object types."),
506 ID.c_str(), pParameter->Get_Type_Identifier().c_str(), pData->Get_Type_Identifier().c_str()
507 );
508
509 return( false );
510 }
511 }
512
513 //-----------------------------------------------------
514 else switch( pData->Get_Type() )
515 {
516 case PARAMETER_TYPE_PointCloud : pParameter = m_Data.Add_PointCloud ("", ID, "", "", 0 ); break;
517 case PARAMETER_TYPE_Grid : pParameter = m_Data.Add_Grid ("", ID, "", "", 0 ); break;
518 case PARAMETER_TYPE_Grids : pParameter = m_Data.Add_Grids ("", ID, "", "", 0 ); break;
519 case PARAMETER_TYPE_Table : pParameter = m_Data.Add_Table ("", ID, "", "", 0 ); break;
520 case PARAMETER_TYPE_Shapes : pParameter = m_Data.Add_Shapes ("", ID, "", "", 0 ); break;
521 case PARAMETER_TYPE_TIN : pParameter = m_Data.Add_TIN ("", ID, "", "", 0 ); break;
522
523 case PARAMETER_TYPE_PointCloud_List: pParameter = m_Data.Add_PointCloud_List("", ID, "", "", 0 ); break;
524 case PARAMETER_TYPE_Grid_List : pParameter = m_Data.Add_Grid_List ("", ID, "", "", 0, false); break;
525 case PARAMETER_TYPE_Grids_List : pParameter = m_Data.Add_Grids_List ("", ID, "", "", 0, false); break;
526 case PARAMETER_TYPE_Table_List : pParameter = m_Data.Add_Table_List ("", ID, "", "", 0 ); break;
527 case PARAMETER_TYPE_Shapes_List : pParameter = m_Data.Add_Shapes_List ("", ID, "", "", 0 ); break;
528 case PARAMETER_TYPE_TIN_List : pParameter = m_Data.Add_TIN_List ("", ID, "", "", 0 ); break;
529
531 switch( pData->Get_DataObject_Type() )
532 {
533 case SG_DATAOBJECT_TYPE_PointCloud: pParameter = m_Data.Add_PointCloud ("", ID, "", "", 0 ); break;
534 case SG_DATAOBJECT_TYPE_Grid : pParameter = m_Data.Add_Grid ("", ID, "", "", 0 ); break;
535 case SG_DATAOBJECT_TYPE_Grids : pParameter = m_Data.Add_Grids ("", ID, "", "", 0 ); break;
536 case SG_DATAOBJECT_TYPE_Table : pParameter = m_Data.Add_Table ("", ID, "", "", 0 ); break;
537 case SG_DATAOBJECT_TYPE_Shapes : pParameter = m_Data.Add_Shapes ("", ID, "", "", 0 ); break;
538 case SG_DATAOBJECT_TYPE_TIN : pParameter = m_Data.Add_TIN ("", ID, "", "", 0 ); break;
539 default:
540 return( true );
541 }
542 break;
543
544 default:
545 return( true );
546 }
547
548 //-----------------------------------------------------
549 if( pData->is_DataObject() )
550 {
551 if( pParameter->is_DataObject() )
552 {
553 pParameter->Set_Value(pData->asDataObject());
554 }
555 else
556 {
557 pParameter->asList()->Add_Item(pData->asDataObject());
558 }
559
560 m_Data_Manager.Add(pData->asDataObject());
561 }
562 else if( pData->is_DataObject_List() && pParameter->is_DataObject_List() )
563 {
564 for(int i=0; i<Get_List_Count(pData); i++)
565 {
566 pParameter->asList()->Add_Item(Get_List_Item(pData, i));
567 m_Data_Manager.Add (Get_List_Item(pData, i));
568 }
569 }
570
571 return( true );
572}
573
574//---------------------------------------------------------
575bool CSG_Tool_Chain::Data_Add_TempList(const CSG_String &ID, const CSG_String &Type)
576{
577 if( !m_Data(ID) )
578 {
579 switch( SG_Parameter_Type_Get_Type(Type) )
580 {
581 case PARAMETER_TYPE_PointCloud_List: m_Data.Add_PointCloud_List("", ID, "", "", 0 ); break;
582 case PARAMETER_TYPE_Grid_List : m_Data.Add_Grid_List ("", ID, "", "", 0, false); break;
583 case PARAMETER_TYPE_Grids_List : m_Data.Add_Grids_List ("", ID, "", "", 0, false); break;
584 case PARAMETER_TYPE_Table_List : m_Data.Add_Table_List ("", ID, "", "", 0 ); break;
585 case PARAMETER_TYPE_Shapes_List : m_Data.Add_Shapes_List ("", ID, "", "", 0 ); break;
586 case PARAMETER_TYPE_TIN_List : m_Data.Add_TIN_List ("", ID, "", "", 0 ); break;
587
588 default:
589 Error_Fmt("%s: %s [%s|%s]", SG_T("datalist"), _TL("unsupported data list type"), ID.c_str(), Type.c_str());
590
591 return( false );
592 }
593 }
594
595 return( true );
596}
597
598//---------------------------------------------------------
599bool CSG_Tool_Chain::Data_Del_Temp(const CSG_String &ID, bool bData)
600{
601 CSG_Parameter *pData = m_Data(ID);
602
603 if( pData )
604 {
605 if( bData )
606 {
607 if( pData->is_DataObject() )
608 {
609 m_Data_Manager.Delete(pData->asDataObject());
610 }
611 else if( pData->is_DataObject_List() )
612 {
613 for(int i=0; i<Get_List_Count(pData); i++)
614 {
615 m_Data_Manager.Delete(Get_List_Item(pData, i));
616 }
617 }
618 }
619
620 m_Data.Del_Parameter(ID);
621 }
622
623 return( true );
624}
625
626//---------------------------------------------------------
627bool CSG_Tool_Chain::Data_Update(const CSG_String &ID, bool bShow)
628{
629 CSG_Parameter *pData = m_Data(ID);
630
631 if( pData && pData->asDataObject() && pData->asDataObject()->is_Valid() )
632 {
634 }
635
636 return( true );
637}
638
639
641// //
643
644//---------------------------------------------------------
645bool CSG_Tool_Chain::Data_Exists(CSG_Data_Object *pData)
646{
647 for(int i=0; i<m_Data.Get_Count(); i++)
648 {
649 if( m_Data(i)->is_DataObject() )
650 {
651 if( pData == m_Data(i)->asDataObject() )
652 {
653 return( true );
654 }
655 }
656 else if( m_Data(i)->is_DataObject_List() )
657 {
658 for(int j=0; j<Get_List_Count(m_Data(i)); j++)
659 {
660 if( pData == Get_List_Item(m_Data(i), j) )
661 {
662 return( true );
663 }
664 }
665 }
666 }
667
668 return( false );
669}
670
671//---------------------------------------------------------
672bool CSG_Tool_Chain::Data_Initialize(void)
673{
674 m_Data.Set_Manager(NULL);
675
676 for(int i=0; i<Parameters.Get_Count(); i++)
677 {
678 CSG_Parameter &P = Parameters[i];
679
680 if( !(P.is_DataObject() && !P.asDataObject()) )
681 {
682 if( !Data_Add(P.Get_Identifier(), &P) )
683 {
684 return( false );
685 }
686 }
687 }
688
689 return( true );
690}
691
692//---------------------------------------------------------
693bool CSG_Tool_Chain::Data_Finalize(void)
694{
695 for(int i=0; i<Parameters.Get_Count(); i++) // detach non temporary data before freeing the local data manager !!!
696 {
697 CSG_Parameter &P = Parameters[i];
698
699 if( P.is_DataObject() )
700 {
701 if( m_Data(P.Get_Identifier()) )
702 {
704 {
705 P.Set_Value(m_Data(P.Get_Identifier())->asDataObject());
706 }
707 }
708
709 m_Data_Manager.Delete(P.asDataObject(), true);
710 }
711 else if( P.is_DataObject_List() )
712 {
713 if( P.is_Output() && m_Data(P.Get_Identifier()) ) // output lists cannot be up-to-date yet
714 {
715 CSG_Parameter *pData = m_Data(P.Get_Identifier());
716
717 for(int j=0; j<Get_List_Count(pData); j++) // csg_parameter::assign() will not work, if parameters data manager is the standard data manager because it checks for existing data sets
718 {
719 P.asList()->Add_Item(Get_List_Item(pData, j));
720 }
721 }
722
723 for(int j=0; j<Get_List_Count(Parameters(i)); j++)
724 {
725 m_Data_Manager.Delete(Get_List_Item(Parameters(i), j), true);
726 }
727 }
728 }
729
730 m_Data_Manager.Delete();
731
732 m_Data.Destroy();
733
734 //-----------------------------------------------------
735 for(int i=0; i<m_Chain["parameters"].Get_Children_Count(); i++)
736 {
737 const CSG_MetaData &Parameter = m_Chain["parameters"][i];
738
739 if( Parameter.Cmp_Name("output") )
740 {
741 CSG_Parameter *pParameter = Parameters(Parameter.Get_Property("varname"));
742
743 if( pParameter && pParameter->is_DataObject() && pParameter->asDataObject() && pParameter->asDataObject() != DATAOBJECT_CREATE )
744 {
745 if( Parameter("colours") )
746 {
747 DataObject_Set_Colors(pParameter->asDataObject(), Parameter["colours"].Get_Content(), 0, IS_TRUE_PROPERTY(Parameter["colours"], "revert"));
748 }
749
750 if( Parameter("output_name") )
751 {
752 if( IS_TRUE_PROPERTY(Parameter["output_name"], "input") )
753 {
754 CSG_Parameter *pInput = Parameters(Parameter["output_name"].Get_Content());
755
756 if( pInput && pInput->is_DataObject() && pInput->asDataObject() )
757 {
758 CSG_String Suffix;
759
760 if( Parameter["output_name"].Get_Property("suffix", Suffix) && !Suffix.is_Empty() )
761 {
762 Suffix = " [" + Suffix + "]";
763 }
764
765 pParameter->asDataObject()->Set_Name(pInput->asDataObject()->Get_Name() + Suffix);
766 }
767 }
768 else if( !Parameter["output_name"].Get_Content().is_Empty() )
769 {
770 pParameter->asDataObject()->Set_Name(Parameter["output_name"].Get_Content());
771 }
772 }
773 }
774 }
775 }
776
777 //-----------------------------------------------------
778 return( true );
779}
780
781
783// //
785
786//---------------------------------------------------------
787bool CSG_Tool_Chain::Parameter_isCompatible(TSG_Parameter_Type A, TSG_Parameter_Type B)
788{
789 if( A == B )
790 {
791 return( true );
792 }
793
794 switch( A )
795 {
796 default:
797 return( false );
798
800 return( B == PARAMETER_TYPE_Shapes
802 || B == PARAMETER_TYPE_TIN );
803
805 return( B == PARAMETER_TYPE_PointCloud );
806 }
807}
808
809
811// //
813
814//---------------------------------------------------------
815bool CSG_Tool_Chain::Message(const CSG_MetaData &Message)
816{
817 if( Message.Cmp_Name("message") )
818 {
819 if( IS_TRUE_PROPERTY(Message, "dialog") )
820 {
821 Message_Dlg(Message.Get_Content());
822 }
823
824 Message_Fmt("\n%s", Message.Get_Content().c_str());
825 }
826
827 return( true );
828}
829
830
832// //
834
835//---------------------------------------------------------
836bool CSG_Tool_Chain::Check_Condition(const CSG_MetaData &Condition, CSG_Parameters *pData)
837{
838 CSG_String Type;
839
840 if( !Condition.Cmp_Name("condition") || !Condition.Get_Property("type", Type) )
841 {
842 return( true );
843 }
844
845 //-----------------------------------------------------
846 CSG_String Variable;
847
848 if( !Condition.Get_Property("varname", Variable) && !Condition.Get_Property("variable", Variable) )
849 {
850 Variable = Condition.Get_Content();
851 }
852
853 //-----------------------------------------------------
854 if( !Type.CmpNoCase("has_gui" ) ) // executed from saga_gui ? (tool might offer different parameters if called from saga_cmd, python etc.)
855 {
856 return( IS_TRUE_STRING(Variable) ? has_GUI() != false : has_GUI() == false );
857 }
858
859 //-----------------------------------------------------
860 if( !Type.CmpNoCase("exists" ) ) // data object exists
861 {
862 CSG_Parameter *pParameter = (*pData)(Variable);
863
864 return( pParameter && ((pParameter->is_DataObject() && pParameter->asDataObject()) || (pParameter->is_DataObject_List() && pParameter->asList()->Get_Item_Count())) );
865 }
866
867 if( !Type.CmpNoCase("not_exists") ) // data object does not exist
868 {
869 return( (*pData)(Variable) == NULL || (*pData)(Variable)->asDataObject() == NULL );
870 }
871
872 //-----------------------------------------------------
873 CSG_Parameter *pOption = (*pData)(Variable);
874
875 if( pOption == NULL )
876 {
877 return( true );
878 }
879
880 switch( pOption->Get_Type() )
881 {
882 //-----------------------------------------------------
884 {
885 CSG_String Value;
886
887 if( Condition.Get_Property("value", Value) )
888 {
889 if( !Type.CmpNoCase("=") || !Type.CmpNoCase("equal" ) ) { return( (IS_TRUE_STRING(Value) ? pOption->asBool() : !pOption->asBool()) ); }
890 else if( !Type.CmpNoCase("!") || !Type.CmpNoCase("not_equal") ) { return( (IS_TRUE_STRING(Value) ? !pOption->asBool() : pOption->asBool()) ); }
891 }
892 }
893 break;
894
895 //-----------------------------------------------------
896 case PARAMETER_TYPE_Int :
900 {
901 int Value;
902
903 if( Condition.Get_Property("value", Value) )
904 {
905 if( !Type.CmpNoCase("=") || !Type.CmpNoCase("equal" ) ) { if( Value != pOption->asInt() ) { return( false ); } }
906 else if( !Type.CmpNoCase("!") || !Type.CmpNoCase("not_equal") ) { if( Value == pOption->asInt() ) { return( false ); } }
907 else if( !Type.CmpNoCase("<") || !Type.CmpNoCase("less" ) ) { if( Value >= pOption->asInt() ) { return( false ); } }
908 else if( !Type.CmpNoCase(">") || !Type.CmpNoCase("greater" ) ) { if( Value <= pOption->asInt() ) { return( false ); } }
909 }
910 }
911 break;
912
913 //-----------------------------------------------------
916 {
917 double Value;
918
919 if( Condition.Get_Property("value", Value) )
920 {
921 if( !Type.CmpNoCase("=") || !Type.CmpNoCase("equal" ) ) { if( Value != pOption->asDouble() ) { return( false ); } }
922 else if( !Type.CmpNoCase("!") || !Type.CmpNoCase("not_equal") ) { if( Value == pOption->asDouble() ) { return( false ); } }
923 else if( !Type.CmpNoCase("<") || !Type.CmpNoCase("less" ) ) { if( Value >= pOption->asDouble() ) { return( false ); } }
924 else if( !Type.CmpNoCase(">") || !Type.CmpNoCase("greater" ) ) { if( Value <= pOption->asDouble() ) { return( false ); } }
925 }
926 }
927 break;
928
929 //-----------------------------------------------------
933 {
934 CSG_String Value;
935
936 Condition.Get_Property("value", Value); // no 'if', bcos empty string would return false !!
937
938 {
939 if( !Type.CmpNoCase("=") || !Type.CmpNoCase("equal" ) ) { if( Value.Cmp(pOption->asString()) != 0 ) { return( false ); } }
940 else if( !Type.CmpNoCase("!") || !Type.CmpNoCase("not_equal") ) { if( Value.Cmp(pOption->asString()) == 0 ) { return( false ); } }
941 else if( !Type.CmpNoCase("<") || !Type.CmpNoCase("less" ) ) { if( Value.Cmp(pOption->asString()) >= 0 ) { return( false ); } }
942 else if( !Type.CmpNoCase(">") || !Type.CmpNoCase("greater" ) ) { if( Value.Cmp(pOption->asString()) <= 0 ) { return( false ); } }
943 }
944 }
945 break;
946
947 //-----------------------------------------------------
949 {
950 CSG_String Value;
951
952 if( Condition.Get_Property("value", Value) )
953 {
954 bool bValid = pOption->asGrid_System()->is_Valid();
955
956 if( !Type.CmpNoCase("=") || !Type.CmpNoCase("equal" ) ) { return( (IS_TRUE_STRING(Value) ? bValid : !bValid) ); }
957 else if( !Type.CmpNoCase("!") || !Type.CmpNoCase("not_equal") ) { return( (IS_TRUE_STRING(Value) ? !bValid : bValid) ); }
958 }
959 }
960 break;
961
962 //-----------------------------------------------------
963 default:
964 // nop
965 break;
966 }
967
968 return( true );
969}
970
971
973// //
975
976//---------------------------------------------------------
977bool CSG_Tool_Chain::ForEach(const CSG_MetaData &Commands)
978{
979 for(int i=0; i<Commands.Get_Children_Count(); i++) // add internal target lists, if any..
980 {
981 if( Commands[i].Cmp_Name("output") || Commands[i].Cmp_Name("datalist") )
982 {
983 Data_Add_TempList(Commands[i].Get_Content(), Commands[i].Get_Property("type"));
984 }
985 }
986
987 //-----------------------------------------------------
988 bool bIgnoreErrors = IS_TRUE_PROPERTY(Commands, "ignore_errors");
989
990 CSG_String VarName;
991
992 if( Commands.Get_Property("varname", VarName) )
993 {
994 return( ForEach_Iterator(Commands, VarName, bIgnoreErrors) );
995 }
996
997 if( Commands.Get_Property("input", VarName) )
998 {
999 return( ForEach_Object (Commands, VarName, bIgnoreErrors)
1000 || ForEach_File (Commands, VarName, bIgnoreErrors) );
1001 }
1002
1003 Error_Set("foreach statement misses iterator or input list definition");
1004
1005 return( false );
1006}
1007
1008//---------------------------------------------------------
1009bool CSG_Tool_Chain::ForEach_Iterator(const CSG_MetaData &Commands, const CSG_String &VarName, bool bIgnoreErrors)
1010{
1011 CSG_Parameter *pIterator = Parameters(VarName);
1012
1013 if( pIterator )
1014 {
1015 Error_Set("foreach statement iterator variable name is already in use");
1016
1017 return( false );
1018 }
1019
1020 //-----------------------------------------------------
1021 CSG_String s;
1022
1023 double begin = Commands.Get_Property("begin", s) ? (Parameters(s) ? Parameters[s].asDouble() : s.asDouble()) : 0.;
1024 double end = Commands.Get_Property("end" , s) ? (Parameters(s) ? Parameters[s].asDouble() : s.asDouble()) : 0.;
1025
1026 if( begin >= end )
1027 {
1028 Error_Set("foreach iterator statement with invalid range (define begin < end)");
1029
1030 return( false );
1031 }
1032
1033 double step = 1.;
1034
1035 if( Commands.Get_Property("steps", s) )
1036 {
1037 double steps = Parameters(s) ? Parameters[s].asDouble() : s.asDouble();
1038
1039 if( steps > 0 )
1040 {
1041 step = (end - begin) / steps;
1042 }
1043 }
1044 else if( Commands.Get_Property("step", s) )
1045 {
1046 step = Parameters(s) ? Parameters[s].asDouble() : s.asDouble();
1047 }
1048
1049 if( step <= 0. )
1050 {
1051 Error_Set("foreach iterator statement with invalid step size (define step > 0 or steps > 0)");
1052
1053 return( false );
1054 }
1055
1056 Message_Fmt("\nfor i = %f to %f step %f (%d steps)", begin, end, step, (int)((end - begin) / step));
1057
1058 //-----------------------------------------------------
1059 bool bResult = true;
1060
1061 pIterator = Parameters.Add_Double("", VarName, "Iterator", "");
1062
1063 for(double i=begin; bResult && i<=end; i+=step)
1064 {
1065 Message_Fmt("\nfor step: %f", i);
1066
1067 pIterator->Set_Value(i);
1068
1069 for(int iTool=0; bResult && iTool<Commands.Get_Children_Count(); iTool++)
1070 {
1071 const CSG_MetaData &Tool = Commands[iTool];
1072
1073 if( Tool.Cmp_Name("tool") )
1074 {
1075 bResult = Tool_Run(Tool, bIgnoreErrors);
1076
1077 if( !bResult && bIgnoreErrors )
1078 {
1079 bResult = true;
1080 }
1081 }
1082 }
1083 }
1084
1085 Parameters.Del_Parameter(VarName);
1086
1087 return( bResult );
1088}
1089
1090//---------------------------------------------------------
1091bool CSG_Tool_Chain::ForEach_Object(const CSG_MetaData &Commands, const CSG_String &ListVarName, bool bIgnoreErrors)
1092{
1093 CSG_Parameter *pList = m_Data(ListVarName);
1094
1095 if( !pList )
1096 {
1097 return( false );
1098 }
1099
1100 //-----------------------------------------------------
1101 bool bResult = true;
1102
1103 if( pList->is_DataObject_List() )
1104 {
1105 for(int iObject=0; bResult && iObject<Get_List_Count(pList->asList()); iObject++)
1106 {
1107 for(int iTool=0; bResult && iTool<Commands.Get_Children_Count(); iTool++)
1108 {
1109 const CSG_MetaData &Tool = Commands[iTool];
1110
1111 if( Tool.Cmp_Name("tool") )
1112 {
1113 for(int j=0; j<Tool.Get_Children_Count(); j++)
1114 {
1115 if( Tool[j].Cmp_Name("input") && Tool[j].Get_Content().Find(ListVarName) == 0 )
1116 {
1117 Tool(j)->Set_Content(ListVarName + CSG_String::Format("[%d]", iObject));
1118 }
1119 }
1120 }
1121
1122 bResult = Tool_Run(Tool, bIgnoreErrors);
1123 }
1124
1125 if( !bResult && bIgnoreErrors )
1126 {
1127 bResult = true;
1128 }
1129 }
1130 }
1131
1132 //-----------------------------------------------------
1133 else if( pList->Get_Type() == PARAMETER_TYPE_Grids )
1134 {
1135 for(int iObject=0; bResult && iObject<pList->asGrids()->Get_Grid_Count(); iObject++)
1136 {
1137 for(int iTool=0; bResult && iTool<Commands.Get_Children_Count(); iTool++)
1138 {
1139 const CSG_MetaData &Tool = Commands[iTool];
1140
1141 if( Tool.Cmp_Name("tool") )
1142 {
1143 for(int j=0; j<Tool.Get_Children_Count(); j++)
1144 {
1145 if( Tool[j].Cmp_Name("input") && Tool[j].Get_Content().Find(ListVarName) == 0 )
1146 {
1147 Tool(j)->Set_Content(ListVarName + CSG_String::Format("[%d]", iObject));
1148 }
1149 }
1150 }
1151
1152 bResult = Tool_Run(Tool, bIgnoreErrors);
1153 }
1154
1155 if( !bResult && bIgnoreErrors )
1156 {
1157 bResult = true;
1158 }
1159 }
1160 }
1161
1162 return( bResult );
1163}
1164
1165//---------------------------------------------------------
1166bool CSG_Tool_Chain::ForEach_File(const CSG_MetaData &Commands, const CSG_String &ListVarName, bool bIgnoreErrors)
1167{
1168 CSG_Parameter *pList = Parameters(ListVarName);
1169
1170 if( !pList || pList->Get_Type() != PARAMETER_TYPE_FilePath )
1171 {
1172 return( false );
1173 }
1174
1175 CSG_Strings Files;
1176
1177 pList->asFilePath()->Get_FilePaths(Files);
1178
1179 //-----------------------------------------------------
1180 bool bResult = true;
1181
1182 for(int iFile=0; bResult && iFile<Files.Get_Count(); iFile++)
1183 {
1184 for(int iTool=0; bResult && iTool<Commands.Get_Children_Count(); iTool++)
1185 {
1186 const CSG_MetaData &Tool = Commands[iTool];
1187
1188 if( Tool.Cmp_Name("tool") )
1189 {
1190 CSG_Array_Int Input;
1191
1192 for(int j=0; j<Tool.Get_Children_Count(); j++)
1193 {
1194 if( Tool[j].Cmp_Name("option") && Tool[j].Get_Content().Find(ListVarName) == 0 && IS_TRUE_PROPERTY(Tool[j], "varname") )
1195 {
1196 Tool(j)->Set_Content(Files[iFile]);
1197 Tool(j)->Set_Property("varname", "false");
1198
1199 Input += j;
1200 }
1201 }
1202
1203 bResult = Tool_Run(Tool, bIgnoreErrors);
1204
1205 for(size_t i=0; i<Input.Get_uSize(); i++)
1206 {
1207 Tool(Input[i])->Set_Content(ListVarName);
1208 Tool(Input[i])->Set_Property("varname", "true");
1209 }
1210 }
1211 else
1212 {
1213 bResult = Tool_Run(Tool, bIgnoreErrors);
1214 }
1215
1216 if( !bResult && bIgnoreErrors )
1217 {
1218 bResult = true;
1219 }
1220 }
1221 }
1222
1223 return( bResult );
1224}
1225
1226
1228// //
1230
1231//---------------------------------------------------------
1232bool CSG_Tool_Chain::Tool_Run(const CSG_MetaData &Tool, bool bShowError)
1233{
1234 if( Tool.Cmp_Name("message") )
1235 {
1236 Message(Tool);
1237
1238 return( true );
1239 }
1240
1241 //-----------------------------------------------------
1242 if( Tool.Cmp_Name("comment") )
1243 {
1244 return( true );
1245 }
1246
1247 //-----------------------------------------------------
1248 if( Tool.Cmp_Name("datalist") )
1249 {
1250 return( Data_Add_TempList(Tool.Get_Content(), Tool.Get_Property("type")) );
1251 }
1252
1253 if( Tool.Cmp_Name("delete") )
1254 {
1255 return( Data_Del_Temp(Tool.Get_Content(), IS_TRUE_PROPERTY(Tool, "data")) );
1256 }
1257
1258 if( Tool.Cmp_Name("update") )
1259 {
1260 return( Data_Update(Tool.Get_Content(), IS_TRUE_PROPERTY(Tool, "show")) );
1261 }
1262
1263 //-----------------------------------------------------
1264 if( Tool.Cmp_Name("condition") )
1265 {
1266 const CSG_MetaData *pTools = (!Check_Condition(Tool, &m_Data) || !Check_Condition(Tool, &Parameters))
1267 ? Tool("else") : (Tool("if") ? Tool("if") : &Tool);
1268
1269 for(int i=0; pTools && i<pTools->Get_Children_Count(); i++)
1270 {
1271 if( !Tool_Run((*pTools)[i]) )
1272 {
1273 return( false );
1274 }
1275 }
1276
1277 return( true );
1278 }
1279
1280 //-----------------------------------------------------
1281 if( Tool.Cmp_Name("foreach") )
1282 {
1283 return( ForEach(Tool) );
1284 }
1285
1286 //-----------------------------------------------------
1287 if( !Tool.Cmp_Name("tool") )
1288 {
1289 return( true ); // only proceed, if it is tagged as tool...
1290 }
1291
1292 if( !Tool.Get_Property("library") || !(Tool.Get_Property("tool") || Tool.Get_Property("module")) )
1293 {
1294 if( bShowError ) Error_Set(_TL("invalid tool definition"));
1295
1296 return( false );
1297 }
1298
1299 //-----------------------------------------------------
1300 const SG_Char *Name = Tool.Get_Property("tool") ? Tool.Get_Property("tool") : Tool.Get_Property("module");
1301
1302 CSG_Tool *pTool = SG_Get_Tool_Library_Manager().Create_Tool(Tool.Get_Property("library"), Name,
1303 IS_TRUE_PROPERTY(Tool, "with_gui") // this option allows to run a tool in 'gui-mode', e.g. to popup variogram dialogs for kriging interpolation
1304 );
1305
1306 if( !pTool )
1307 {
1308 if( bShowError ) Error_Fmt("%s [%s].[%s]", _TL("could not find tool"), Tool.Get_Property("library"), Name);
1309
1310 return( false );
1311 }
1312
1313 //-----------------------------------------------------
1314 Process_Set_Text(pTool->Get_Name());
1315
1316 pTool->Settings_Push(&m_Data_Manager);
1317
1318 bool bResult = false;
1319
1320 if( !pTool->On_Before_Execution() )
1321 {
1322 if( bShowError ) Error_Fmt("%s [%s].[%s]", _TL("before tool execution check failed"), pTool->Get_Library().c_str(), pTool->Get_Name().c_str());
1323 }
1324 else if( !Tool_Initialize(Tool, pTool) )
1325 {
1326 if( bShowError ) Error_Fmt("%s [%s].[%s]", _TL("tool initialization failed" ), pTool->Get_Library().c_str(), pTool->Get_Name().c_str());
1327 }
1328 else if( !(bResult = pTool->Execute(m_bAddHistory)) )
1329 {
1330 Message_Fmt ("%s [%s].[%s]", _TL("tool execution failed" ), pTool->Get_Library().c_str(), pTool->Get_Name().c_str());
1331 }
1332
1333 if( bResult )
1334 {
1335 pTool->On_After_Execution();
1336 }
1337
1338 Tool_Finalize(Tool, pTool);
1339
1340 pTool->Settings_Pop();
1341
1343
1344 return( bResult );
1345}
1346
1347
1349// //
1351
1352//---------------------------------------------------------
1353bool CSG_Tool_Chain::Tool_Check_Condition(const CSG_MetaData &Tool)
1354{
1355 if( Tool("condition") )
1356 {
1357 for(int i=0; i<Tool.Get_Children_Count(); i++) // there might be more than one condition to be checked
1358 {
1359 if( !Check_Condition(Tool[i], &m_Data) )
1360 {
1361 return( false );
1362 }
1363 }
1364 }
1365
1366 return( true );
1367}
1368
1369
1371// //
1373
1374//---------------------------------------------------------
1375bool CSG_Tool_Chain::Tool_Get_Parameter(CSG_String ID, CSG_Parameters *pParameters, CSG_Parameter **ppParameter, CSG_Parameter **ppOwner)
1376{
1377 CSG_Parameter *pParameter = (*pParameters)(ID.BeforeFirst('.'));
1378
1379 if( pParameter )
1380 {
1381 switch( pParameter->Get_Type() )
1382 {
1383 default:
1384 *ppParameter = pParameter;
1385
1386 return( true );
1387
1389 *ppOwner = pParameter;
1390
1391 return( Tool_Get_Parameter(ID.AfterFirst('.'), pParameter->asParameters(), ppParameter, ppOwner) );
1392
1394 if( !ID.AfterFirst('.').CmpNoCase("min") || !ID.AfterFirst('.').CmpNoCase("minimum") )
1395 {
1396 *ppParameter = pParameter->asRange()->Get_Min_Parameter();
1397 *ppOwner = pParameter;
1398 }
1399 else if( !ID.AfterFirst('.').CmpNoCase("max") || !ID.AfterFirst('.').CmpNoCase("maximum") )
1400 {
1401 *ppParameter = pParameter->asRange()->Get_Max_Parameter();
1402 *ppOwner = pParameter;
1403 }
1404 else
1405 {
1406 *ppParameter = pParameter;
1407 }
1408
1409 return( true );
1410 }
1411 }
1412
1413 return( false );
1414}
1415
1416//---------------------------------------------------------
1417bool CSG_Tool_Chain::Tool_Get_Parameter(const CSG_MetaData &Parameter, CSG_Tool *pTool, CSG_Parameter **ppParameter, CSG_Parameter **ppOwner)
1418{
1419 CSG_String ID(Parameter.Get_Property("parms"));
1420
1421 if( !ID.is_Empty() )
1422 {
1423 ID += '.';
1424 }
1425
1426 ID += Parameter.Get_Property("id");
1427
1428 //-----------------------------------------------------
1429 CSG_Parameter *pOwner; if( !ppOwner ) { ppOwner = &pOwner; } *ppOwner = NULL;
1430
1431 CSG_Parameters *pParameters = pTool->Get_Parameters(ID.BeforeFirst('.'));
1432
1433 if( pParameters )
1434 {
1435 ID = ID.AfterFirst('.');
1436 }
1437 else
1438 {
1439 pParameters = pTool->Get_Parameters();
1440 }
1441
1442 return( Tool_Get_Parameter(ID, pParameters, ppParameter, ppOwner) );
1443}
1444
1445//---------------------------------------------------------
1446bool CSG_Tool_Chain::Tool_Initialize(const CSG_MetaData &Tool, CSG_Tool *pTool)
1447{
1448 //-----------------------------------------------------
1449 for(int i=0; i<Tool.Get_Children_Count(); i++) // check for invalid parameters...
1450 {
1451 const CSG_MetaData &Parameter = Tool[i]; if( Parameter.Cmp_Name("comment") ) { continue; }
1452
1453 if( Parameter.Cmp_Name("message") )
1454 {
1455 Message(Parameter);
1456
1457 continue;
1458 }
1459
1460 CSG_Parameter *pParameter, *pOwner;
1461
1462 if( !Tool_Get_Parameter(Parameter, pTool, &pParameter, &pOwner) )
1463 {
1464 Error_Fmt("%s: %s", _TL("parameter not found"), Parameter.Get_Property("id"));
1465
1466 return( false );
1467 }
1468 }
1469
1470 //-----------------------------------------------------
1471 if( Tool.Get_Property("grid_system") )
1472 {
1473 CSG_Parameter *pParameter = Parameters(Tool.Get_Property("grid_system"));
1474
1475 if( pParameter && pParameter->asGrid_System() )
1476 {
1477 if( !pTool->Set_Grid_System(*pParameter->asGrid_System()) )
1478 {
1479 Message_Fmt("\n%s: %s\n", _TL("Warning"), _TL("failed to set tool's grid system"));
1480 }
1481 }
1482 }
1483
1484 //-----------------------------------------------------
1485 for(int i=0; i<Tool.Get_Children_Count(); i++) // initialize all options first, some might en-/disable mandatory input data
1486 {
1487 const CSG_MetaData &Parameter = Tool[i]; if( !Parameter.Cmp_Name("option") ) { continue; }
1488
1489 CSG_Parameter *pParameter, *pOwner; Tool_Get_Parameter(Parameter, pTool, &pParameter, &pOwner);
1490
1491 if( pParameter->Get_Type() == PARAMETER_TYPE_Grid_System )
1492 {
1493 CSG_Parameter *pData = m_Data(Parameter.Get_Content());
1494
1495 if( pData && pData->asDataObject() && pData->asDataObject()->asGrid() && pData->asDataObject()->asGrid()->Get_System().is_Valid() )
1496 {
1497 pParameter->asGrid_System()->Create(pData->asDataObject()->asGrid()->Get_System());
1498
1499 continue;
1500 }
1501 }
1502
1503 if( IS_TRUE_PROPERTY(Parameter, "varname")
1504 ? pParameter->Set_Value(Parameters(Parameter.Get_Content()))
1505 : pParameter->Set_Value( Parameter.Get_Content() ) )
1506 {
1507 pParameter->has_Changed(); if( pOwner ) { pOwner->has_Changed(); }
1508 }
1509 }
1510
1511 //-----------------------------------------------------
1512 for(int i=0; i<Tool.Get_Children_Count(); i++) // set data input first
1513 {
1514 const CSG_MetaData &Parameter = Tool[i]; if( !Parameter.Cmp_Name("input") ) { continue; }
1515
1516 CSG_Parameter *pParameter, *pOwner; Tool_Get_Parameter(Parameter, pTool, &pParameter, &pOwner);
1517
1518 int Index;
1519
1520 if( Parameter.Get_Content().Find('[') < 1 || !Parameter.Get_Content().AfterFirst('[').asInt(Index) )
1521 {
1522 Index = -1;
1523 }
1524
1525 bool bResult = false;
1526
1527 CSG_Parameter *pData = m_Data(Index < 0 ? Parameter.Get_Content() : Parameter.Get_Content().BeforeFirst('['));
1528
1529 if( pData && (pParameter->is_DataObject() || pParameter->is_DataObject_List()) )
1530 {
1531 if( Index >= 0 && (pData->is_DataObject_List() || pData->asGrids()) )
1532 {
1533 CSG_Data_Object *pObject = pData->is_DataObject_List()
1534 ? pData->asList ()->Get_Item (Index)
1535 : pData->asGrids()->Get_Grid_Ptr(Index);
1536
1537 if( pParameter->is_DataObject() )
1538 {
1539 bResult = pParameter->Set_Value(pObject);
1540 }
1541 if( pParameter->is_DataObject_List() )
1542 {
1543 bResult = pParameter->asList()->Add_Item(pObject);
1544 }
1545 }
1546 else if( pParameter->Get_Type() == pData->Get_Type() )
1547 {
1548 if( pParameter->is_DataObject_List() && pParameter->asList()->Get_Item_Count() > 0 )
1549 {
1550 bResult = true;
1551
1552 for(int i=0; bResult && i<pData->asList()->Get_Item_Count(); i++)
1553 {
1554 bResult = pParameter->asList()->Add_Item(pData->asList()->Get_Item(i));
1555 }
1556 }
1557 else
1558 {
1559 bResult = pParameter->Assign(pData);
1560 }
1561 }
1562 else if( pParameter->is_DataObject_List() && pData->is_DataObject() )
1563 {
1564 bResult = pParameter->asList()->Add_Item(pData->asDataObject());
1565 }
1566 else if( Parameter_isCompatible(pParameter->Get_Type(), pData->Get_Type()) )
1567 {
1568 bResult = pParameter->Set_Value(pData->asDataObject());
1569 }
1570 }
1571
1572 if( bResult )
1573 {
1574 pParameter->has_Changed(); if( pOwner ) { pOwner->has_Changed(); }
1575 }
1576 else if( pParameter->is_Enabled() )
1577 {
1578 Error_Fmt("%s: %s", _TL("set input"), Parameter.Get_Property("id"));
1579
1580 return( false );
1581 }
1582 }
1583
1584 //-----------------------------------------------------
1585 for(int i=0; i<Tool.Get_Children_Count(); i++) // now set all options
1586 {
1587 const CSG_MetaData &Parameter = Tool[i]; if( !Parameter.Cmp_Name("option") ) { continue; }
1588
1589 CSG_Parameter *pParameter, *pOwner; Tool_Get_Parameter(Parameter, pTool, &pParameter, &pOwner);
1590
1591 if( IS_TRUE_PROPERTY(Parameter, "varname") )
1592 { // does option want a value from tool chain parameters and do these provide one ?
1593 switch( pParameter->Get_Type() )
1594 {
1595 default:
1596 pParameter->Set_Value(Parameters(Parameter.Get_Content()));
1597 break;
1598
1600 if( m_Data(Parameter.Get_Content()) && pParameter->asTable()->Assign_Values(m_Data(Parameter.Get_Content())->asTable()) )
1601 {
1602 pParameter->has_Changed();
1603 }
1604 break;
1605 }
1606 }
1607 else
1608 {
1609 switch( pParameter->Get_Type() )
1610 {
1612 if( Parameter("OPTION") )
1613 {
1614 pParameter->Serialize(*Parameter("OPTION"), false);
1615 }
1616 break;
1617
1618 default: {
1619 CSG_String Value(Parameter.Get_Content());
1620
1621 if( Value.Find("$(") >= 0 )
1622 {
1623 for(int j=0; j<Parameters.Get_Count(); j++)
1624 {
1625 CSG_String Var; Var.Printf("$(%s)", Parameters(j)->Get_Identifier());
1626
1627 if( Value.Find(Var) >= 0 )
1628 {
1629 Value.Replace(Var, Parameters(j)->asString());
1630 }
1631 }
1632 }
1633
1634 pParameter->Set_Value(Value);
1635
1636 if( pOwner )
1637 {
1638 pOwner->has_Changed();
1639 }
1640
1641 break; }
1642 }
1643 }
1644 }
1645
1646 //-----------------------------------------------------
1647 for(int i=0; i<Tool.Get_Children_Count(); i++) // finally set the data output
1648 {
1649 const CSG_MetaData &Parameter = Tool[i]; if( !Parameter.Cmp_Name("output") ) { continue; }
1650
1651 CSG_Parameter *pParameter, *pOwner; Tool_Get_Parameter(Parameter, pTool, &pParameter, &pOwner);
1652
1653 if( !pParameter->Assign(m_Data(Parameter.Get_Content())) )
1654 {
1655 if( pParameter->is_DataObject() )
1656 {
1657 pParameter->Set_Value(DATAOBJECT_CREATE);
1658 }
1659 else if( pParameter->is_DataObject_List() )
1660 {
1661 pParameter->asList()->Del_Items();
1662 }
1663 else if( pParameter->asGrids() )
1664 {
1665 pParameter->asGrids()->Del_Grids();
1666 }
1667 }
1668 }
1669
1670 //-----------------------------------------------------
1671 return( true );
1672}
1673
1674//---------------------------------------------------------
1675bool CSG_Tool_Chain::Tool_Finalize(const CSG_MetaData &Tool, CSG_Tool *pTool)
1676{
1677 for(int i=0; i<Tool.Get_Children_Count(); i++) // add all data objects declared as output to variable list
1678 {
1679 const CSG_MetaData &Parameter = Tool[i];
1680
1681 if( Parameter.Cmp_Name("output") )
1682 {
1683 CSG_String ID (Parameter.Get_Property("id" ));
1684 CSG_String ID_parms(Parameter.Get_Property("parms"));
1685
1686 CSG_Parameter *pParameter = pTool->Get_Parameters(ID_parms)
1687 ? (*pTool->Get_Parameters(ID_parms))(ID)
1688 : (*pTool->Get_Parameters( ))(ID);
1689
1690 if( !pParameter || !Data_Add(Parameter.Get_Content(), pParameter) )
1691 {
1692 return( false );
1693 }
1694 }
1695 }
1696
1697 //-----------------------------------------------------
1698 for(int i=-1; i<pTool->Get_Parameters_Count(); i++) // save memory: free all data objects that have not been added to variable list
1699 {
1700 CSG_Parameters *pParameters = i < 0 ? pTool->Get_Parameters() : pTool->Get_Parameters(i);
1701
1702 for(int j=0; j<pParameters->Get_Count(); j++)
1703 {
1704 CSG_Parameter *pParameter = (*pParameters)(j);
1705
1706 if( pParameter->is_Output() )
1707 {
1708 if( pParameter->is_DataObject() )
1709 {
1710 if( !Data_Exists(pParameter->asDataObject()) )
1711 {
1712 m_Data_Manager.Delete(pParameter->asDataObject());
1713 }
1714 }
1715 else if( pParameter->is_DataObject_List() )
1716 {
1717 for(int k=0; k<Get_List_Count(pParameter); k++)
1718 {
1719 if( !Data_Exists(Get_List_Item(pParameter, k)) )
1720 {
1721 m_Data_Manager.Delete(Get_List_Item(pParameter, k));
1722 }
1723 }
1724 }
1725 }
1726 }
1727 }
1728
1729 //-----------------------------------------------------
1730 return( true );
1731}
1732
1733
1735// //
1736// //
1737// //
1739
1740//---------------------------------------------------------
1741CSG_String CSG_Tool_Chain::Get_Script(CSG_Tool *pTool, bool bHeader, bool bAllParameters)
1742{
1743 CSG_MetaData Tool; Tool.Set_Name("tool");
1744
1745 Tool.Add_Property("library", pTool->Get_Library());
1746 Tool.Add_Property("tool" , pTool->Get_ID ());
1747 Tool.Add_Property("name" , pTool->Get_Name ());
1748
1749 _Get_Script_Tool(Tool, pTool->Get_Parameters(), bAllParameters, "", bHeader);
1750
1751 for(int i=0; i<pTool->Get_Parameters_Count(); i++)
1752 {
1753 _Get_Script_Tool(Tool, pTool->Get_Parameters(i), bAllParameters, pTool->Get_Parameters(i)->Get_Identifier() + '.', bHeader);
1754 }
1755
1756 if( !bHeader )
1757 {
1758 return( Tool.asText(1) );
1759 }
1760
1761 //-----------------------------------------------------
1763
1764 _Get_Script_Parameters(Parameters, pTool->Get_Parameters(), "");
1765
1766 for(int i=0; i<pTool->Get_Parameters_Count(); i++)
1767 {
1768 _Get_Script_Parameters(Parameters, pTool->Get_Parameters(i), pTool->Get_Parameters(i)->Get_Identifier() + '.');
1769 }
1770
1771 //-----------------------------------------------------
1772 CSG_MetaData Tools; Tools.Set_Name("toolchain");
1773
1774 Tools.Add_Property("saga-version", SAGA_VERSION);
1775
1776 Tools.Add_Child("group" );
1777 Tools.Add_Child("identifier" , "define-a-unique-tool-identifier-here");
1778 Tools.Add_Child("name" , pTool->Get_Name() + " [Tool Chain]");
1779 Tools.Add_Child("author" );
1780 Tools.Add_Child("description");
1781 Tools.Add_Child("menu" , pTool->Get_MenuPath(true))->Add_Property("absolute", "true");
1782 Tools.Add_Child("crs_sync" , "true");
1783 Tools.Add_Child("parameters" )->Add_Children(Parameters);
1784 Tools.Add_Child("tools" )->Add_Child(Tool);
1785 Tools ("tools" )->Add_Property("history", "false");
1786
1787 return( Tools.asText(1) );
1788}
1789
1790//---------------------------------------------------------
1791bool CSG_Tool_Chain::_Get_Script_Tool(CSG_MetaData &Tool, CSG_Parameters *pParameters, bool bAllParameters, const CSG_String &Prefix, bool bVarNames)
1792{
1793 for(int iParameter=0; iParameter<pParameters->Get_Count(); iParameter++)
1794 {
1795 CSG_Parameter &P = *pParameters->Get_Parameter(iParameter);
1796
1797 if( !bAllParameters && (!P.is_Enabled(false) || P.is_Information()) )
1798 {
1799 continue;
1800 }
1801
1802 CSG_MetaData *pChild = NULL;
1803
1804 switch( P.Get_Type() )
1805 {
1807 _Get_Script_Tool(Tool, P.asParameters(), bAllParameters, Prefix + P.Get_Identifier() + '.', true);
1808 break;
1809
1810 case PARAMETER_TYPE_Bool :
1811 pChild = Tool.Add_Child("option", P.asBool() ? "true" : "false");
1812 break;
1813
1814 case PARAMETER_TYPE_Int :
1817 case PARAMETER_TYPE_Date :
1820 case PARAMETER_TYPE_Text :
1825 pChild = Tool.Add_Child("option", P.asString());
1826 break;
1827
1830 pChild = Tool.Add_Child("option", P.asInt());
1831 break;
1832
1834 pChild = Tool.Add_Child("option");
1835 P.Serialize(*pChild, true);
1836 break;
1837
1839 if( P.Get_Children_Count() == 0 )
1840 {
1841 pChild = Tool.Add_Child("option", P.asString());
1842 }
1843 break;
1844
1845 default:
1846 if( P.is_Input() )
1847 {
1848 pChild = Tool.Add_Child("input");
1849 pChild->Set_Content(P.is_Optional() ? "INPUT_OPTIONAL" : "INPUT");
1850 }
1851 else if( P.is_Output() )
1852 {
1853 pChild = Tool.Add_Child("output");
1854 pChild->Set_Content("OUTPUT");
1855 }
1856 break;
1857 }
1858
1859 if( pChild )
1860 {
1861 pChild->Add_Property("id", Prefix + P.Get_Identifier());
1862
1863 if( bVarNames )
1864 {
1865 if( P.is_Option() )
1866 {
1867 pChild->Add_Property("varname", "true");
1868 }
1869
1870 pChild->Set_Content(Prefix + P.Get_Identifier());
1871 }
1872 }
1873 }
1874
1875 return( true );
1876}
1877
1878//---------------------------------------------------------
1879bool CSG_Tool_Chain::_Get_Script_Parameters(CSG_MetaData &Parameters, CSG_Parameters *pParameters, const CSG_String &Prefix)
1880{
1881 for(int i=0; i<pParameters->Get_Count(); i++)
1882 {
1883 CSG_Parameter &P = *pParameters->Get_Parameter(i);
1884
1886 {
1887 _Get_Script_Parameters(Parameters, P.asParameters(), Prefix + P.Get_Identifier() + '.');
1888
1889 continue; // no support for sub-parameter-lists in here
1890 }
1891
1892 CSG_MetaData &Parameter = *Parameters.Add_Child(
1893 P.is_Option() ? "option" :
1894 P.is_Output() ? "output" : "input"
1895 );
1896
1897 Parameter.Add_Property("varname" , P.Get_Identifier ());
1899 Parameter.Add_Child ("name" , P.Get_Name ());
1900 Parameter.Add_Child ("description", P.Get_Description());
1901
1902 if( P.Get_Parent() )
1903 {
1904 Parameter.Add_Property("parent", P.Get_Parent()->Get_Identifier());
1905 }
1906
1907 if( P.Get_Type() == PARAMETER_TYPE_Node
1909 {
1910 continue; // nothing more to do for these types
1911 }
1912
1913 if( P.is_Option() )
1914 {
1915 CSG_MetaData &Value = *Parameter.Add_Child("value", P.asString());
1916
1917 if( P.asValue() )
1918 {
1919 if( P.asValue()->has_Minimum() ) Value.Add_Property("min", P.asValue()->Get_Minimum());
1920 if( P.asValue()->has_Maximum() ) Value.Add_Property("max", P.asValue()->Get_Maximum());
1921 }
1922
1923 if( P.asChoice () ) Parameter.Add_Child("choices", P.asChoice ()->Get_Items());
1924 if( P.asChoices() ) Parameter.Add_Child("choices", P.asChoices()->Get_Items());
1925
1926 if( P.asFilePath() )
1927 {
1928 Parameter.Add_Property("save" , P.asFilePath()->is_Save () ? "true" : "false");
1929 Parameter.Add_Property("directory", P.asFilePath()->is_Directory() ? "true" : "false");
1930 Parameter.Add_Property("multiple" , P.asFilePath()->is_Multiple () ? "true" : "false");
1931 Parameter.Add_Child ("filter" , P.asFilePath()->Get_Filter());
1932 }
1933
1935 {
1936 P.Serialize(Parameter, true);
1937 }
1938
1940 {
1941 Value.Set_Content(P.is_Optional() ? "true" : "false");
1942 }
1943 }
1944 else // data objects
1945 {
1946 if( P.is_Optional() )
1947 {
1948 Parameter.Add_Property("optional", "true");
1949 }
1950
1952 {
1953 switch( ((CSG_Parameter_Data_Object_Output *)&P)->Get_DataObject_Type() )
1954 {
1957 Parameter.Add_Property("target", "none");
1958 break;
1959
1962 Parameter.Add_Property("target", "none");
1963 break;
1964
1965 default:
1966 break;
1967 }
1968 }
1969
1970 if( P.Get_Type() == PARAMETER_TYPE_Shapes )
1971 {
1972 switch( ((CSG_Parameter_Shapes *)&P)->Get_Shape_Type() )
1973 {
1974 case SHAPE_TYPE_Point : Parameter.Add_Property("feature_type", "point" ); break;
1975 case SHAPE_TYPE_Points : Parameter.Add_Property("feature_type", "points" ); break;
1976 case SHAPE_TYPE_Line : Parameter.Add_Property("feature_type", "line" ); break;
1977 case SHAPE_TYPE_Polygon: Parameter.Add_Property("feature_type", "polygon"); break;
1978 default: break;
1979 }
1980 }
1981
1983 && !((CSG_Parameter_Grid_List *)&P)->Get_System() )
1984 {
1985 Parameter.Add_Property("no_system", "true");
1986 }
1987
1989 && !((CSG_Parameter_Grid_List *)&P)->Get_System() )
1990 {
1991 Parameter.Add_Property("no_system", "true");
1992 }
1993 }
1994 }
1995
1996 return( true );
1997}
1998
1999
2001// //
2002// //
2003// //
2005
2006//---------------------------------------------------------
2008{
2009 m_Library_Name = Library_Name;
2010
2011 //-----------------------------------------------------
2012 if( m_Library_Name.is_Empty() || !m_Library_Name.Cmp("toolchains") )
2013 {
2014 m_Library_Name = "_tool_chains_uncategorized";
2015 m_Name = _TL("Uncategorized Tool Chains");
2016 m_Description = _TL("Uncategorized Tool Chains");
2017 m_Menu = _TL("Uncategorized Tool Chains");
2018 }
2019
2020 //-----------------------------------------------------
2021 else
2022 {
2023 CSG_MetaData XML(SG_File_Make_Path(Path, Library_Name, "xml"));
2024
2025 if( !XML.Cmp_Name("toolchains") )
2026 {
2027 XML.Destroy();
2028 }
2029
2030 m_Name = GET_XML_CONTENT(XML, "name" , m_Library_Name , true);
2031 m_Description = GET_XML_CONTENT(XML, "description", _TL("no description"), true);
2032 m_Menu = GET_XML_CONTENT(XML, "menu" , _TL("Tool Chains" ), true);
2033
2034 m_Description.Replace("[[", "<"); // support for xml/html tags
2035 m_Description.Replace("]]", ">");
2036
2037 // add references...
2038 for(int i=0; i<XML.Get_Children_Count(); i++)
2039 {
2040 if( !XML[i].Get_Name().CmpNoCase("REFERENCE") )
2041 {
2042 CSG_String Authors, Year, Title, Where, Link, Link_Text, DOI;
2043
2044 if( XML[i]("AUTHORS" ) ) Authors = XML[i].Get_Content("AUTHORS" );
2045 if( XML[i]("YEAR" ) ) Year = XML[i].Get_Content("YEAR" );
2046 if( XML[i]("TITLE" ) ) Title = XML[i].Get_Content("TITLE" );
2047 if( XML[i]("WHERE" ) ) Where = XML[i].Get_Content("WHERE" );
2048 if( XML[i]("LINK" ) ) Link = XML[i].Get_Content("LINK" );
2049 if( XML[i]("LINK_TEXT") ) Link_Text = XML[i].Get_Content("LINK_TEXT");
2050 if( XML[i]("DOI" ) ) DOI = XML[i].Get_Content("DOI" );
2051
2052 if( !DOI.is_Empty() )
2053 {
2054 Link = "https://doi.org/" + DOI; Link_Text = "doi:" + DOI;
2055 }
2056
2057 if( !Authors.is_Empty() && !Year.is_Empty() && !Title.is_Empty() )
2058 {
2059 Add_Reference(Authors, Year, Title, Where, Link.c_str(), Link_Text.c_str());
2060 }
2061 else if( !Link.is_Empty() )
2062 {
2063 Add_Reference(Link, Link_Text.c_str());
2064 }
2065 }
2066 }
2067 }
2068}
2069
2070//---------------------------------------------------------
2072{
2073 Delete_Tools();
2074
2075 for(size_t i=0; i<m_Tools.Get_uSize(); i++)
2076 {
2077 delete((CSG_Tool_Chain *)m_Tools[i]);
2078 }
2079}
2080
2081
2083// //
2085
2086//---------------------------------------------------------
2088{
2089 switch( Type )
2090 {
2091 case TLB_INFO_Name : return( m_Name );
2092 case TLB_INFO_Description: return( m_Description );
2093 case TLB_INFO_Menu_Path : return( m_Menu );
2094 case TLB_INFO_Category : return( _TL("Tool Chains") );
2095 }
2096
2097 return( "" );
2098}
2099
2100//---------------------------------------------------------
2102{
2103 m_Tools.Add(pTool);
2104
2106
2107 return( true );
2108}
2109
2110//---------------------------------------------------------
2112{
2113 CSG_Tool *pTool = Index >= 0 && Index < Get_Count() ? (CSG_Tool_Chain *)m_Tools[Index] : NULL;
2114
2115 return( pTool && (Type == TOOL_TYPE_Base || Type == pTool->Get_Type()) ? pTool : NULL );
2116}
2117
2118
2120// //
2122
2123//---------------------------------------------------------
2124CSG_Tool * CSG_Tool_Chains::Create_Tool(const CSG_String &Name, bool bWithGUI, bool bWithCMD)
2125{
2126 CSG_Tool *pTool = CSG_Tool_Library::Get_Tool(Name);
2127
2128 if( pTool && pTool->Get_Type() == TOOL_TYPE_Chain )
2129 {
2130 m_xTools.Add(pTool = new CSG_Tool_Chain(*((CSG_Tool_Chain *)pTool), bWithGUI, bWithCMD));
2131
2132 return( pTool );
2133 }
2134
2135 return( NULL );
2136}
2137
2138//---------------------------------------------------------
2140{
2141 if( m_xTools.Del(pTool) || m_Tools.Del(pTool) )
2142 {
2143 delete((CSG_Tool_Chain *)pTool);
2144
2145 return( true );
2146 }
2147
2148 return( false );
2149}
2150
2151//---------------------------------------------------------
2153{
2154 for(size_t i=0; i<m_xTools.Get_uSize(); i++)
2155 {
2156 delete((CSG_Tool_Chain *)m_xTools[i]);
2157 }
2158
2159 m_xTools.Destroy();
2160
2161 return( true );
2162}
2163
2164
2166// //
2167// //
2168// //
2170
2171//---------------------------------------------------------
2173{
2174 if( SG_Compare_Version(History.Get_Property("saga-version"), "2.1.3") < 0 || !(History("TOOL") || History("MODULE")) )
2175 {
2176 return( false );
2177 }
2178
2179 const CSG_MetaData &Tool(History("TOOL") ? History["TOOL"] : History["MODULE"]);
2180
2181 if( !Tool("OUTPUT") )
2182 {
2183 return( false );
2184 }
2185
2186 //-----------------------------------------------------
2188
2189 Chain.Set_Name ("toolchain" );
2190 Chain.Add_Property("saga-version", SAGA_VERSION);
2191
2192 Chain.Add_Child ("group" , "toolchains");
2193 Chain.Add_Child ("identifier" , SG_File_Get_Name(File, false));
2194 Chain.Add_Child ("name" , SG_File_Get_Name(File, false));
2195 Chain.Add_Child ("description", _TL("created from history"));
2196
2197 Chain.Add_Child ("parameters" );
2198 Chain.Add_Child ("tools" );
2199
2200 _Save_History_Add_Tool(Tool, *Chain("parameters"), *Chain("tools"), true);
2201
2202 for(int i=0; i<Chain["tools"].Get_Children_Count(); i++)
2203 {
2204 Chain["tools"](i)->Del_Property("id");
2205 }
2206
2207 return( Chain.Save(File) );
2208}
2209
2210//---------------------------------------------------------
2211bool CSG_Tool_Chain::_Save_History_Add_Tool(const CSG_MetaData &History, CSG_MetaData &Parms, CSG_MetaData &Tools, bool bAddOutput)
2212{
2213 if( !History("OUTPUT") || !History["OUTPUT"].Get_Property("id") )
2214 {
2215 return( false );
2216 }
2217
2218 //-----------------------------------------------------
2219 CSG_MetaData *pParameter, &Tool = *Tools.Ins_Child("tool", 0);
2220
2221 CSG_String Tool_ID(CSG_String::Format("tool_%02d", Tools.Get_Children_Count()));
2222
2223 Tool.Add_Property("id" , Tool_ID);
2224 Tool.Add_Property("library", History.Get_Property("library"));
2225 Tool.Add_Property("tool" , History.Get_Property("id" ));
2226 Tool.Add_Property("name" , History.Get_Property("name" ));
2227
2228 //-----------------------------------------------------
2229 const CSG_MetaData &Output = History["OUTPUT"];
2230
2231 CSG_String VarName = CSG_String::Format("%s__%s", Tool_ID.c_str(), Output.Get_Property("id"));
2232
2233 pParameter = Tool.Add_Child("output", VarName);
2234 pParameter->Add_Property("parms", Output.Get_Property("parms"));
2235 pParameter->Add_Property("id" , Output.Get_Property("id" ));
2236
2237 if( bAddOutput )
2238 {
2239 pParameter = Parms.Add_Child("output");
2240
2241 pParameter->Add_Property("varname" , VarName);
2242 pParameter->Add_Property("type" , Output.Get_Property("type"));
2243 pParameter->Add_Child ("name" , Output.Get_Property("name"));
2244 // pParameter->Add_Child ("description", Output.Get_Property("name"));
2245 }
2246
2247 //-----------------------------------------------------
2248 for(int i=0; i<History.Get_Children_Count(); i++) // Options and Input
2249 {
2250 CSG_MetaData *pChild = History.Get_Child(i);
2251
2252 if( !pChild->Get_Name().Cmp("OPTION") )
2253 {
2254 pParameter = NULL;
2255
2256 switch( SG_Parameter_Type_Get_Type(pChild->Get_Property("type")) )
2257 {
2258 case PARAMETER_TYPE_Bool :
2259 case PARAMETER_TYPE_Int :
2262 case PARAMETER_TYPE_Date :
2265 case PARAMETER_TYPE_Text :
2270 pParameter = Tool.Add_Child("option", pChild->Get_Content());
2271 break;
2272
2275 pParameter = Tool.Add_Child("option", pChild->Get_Property("index"));
2276 break;
2277
2279 if( pChild->Get_Children_Count() == 0 )
2280 {
2281 pParameter = Tool.Add_Child("option", pChild->Get_Content());
2282 }
2283 break;
2284
2285 default: break;
2286 }
2287
2288 if( pParameter )
2289 {
2290 pParameter->Add_Property("parms", pChild->Get_Property("parms"));
2291 pParameter->Add_Property("id" , pChild->Get_Property("id" ));
2292 }
2293 }
2294 else if( !pChild->Get_Name().Cmp("INPUT") )
2295 {
2296 _Save_History_Add_Input(*pChild, Parms, Tool);
2297 }
2298 else if( !pChild->Get_Name().Cmp("INPUT_LIST") )
2299 {
2300 for(int j=0; j<pChild->Get_Children_Count(); j++)
2301 {
2302 _Save_History_Add_Input(*pChild->Get_Child(j), Parms, Tool);
2303 }
2304 }
2305 }
2306
2307 return( true );
2308}
2309
2310//---------------------------------------------------------
2311bool CSG_Tool_Chain::_Save_History_Add_Input(const CSG_MetaData &History, CSG_MetaData &Parms, CSG_MetaData &Tool)
2312{
2313 CSG_MetaData *pInput = Tool.Add_Child("input");
2314
2315 pInput->Add_Property("parms", History.Get_Property("parms"));
2316 pInput->Add_Property("id" , History.Get_Property("id" ));
2317
2318 if( History("TOOL") || History("MODULE") )
2319 {
2320 const CSG_MetaData &History_Tool(History("TOOL") ? History["TOOL"] : History["MODULE"]);
2321
2322 if( History_Tool("OUTPUT") && History_Tool["OUTPUT"].Get_Property("id") )
2323 {
2324 pInput->Fmt_Content("tool_%02d__%s", Tool.Get_Parent()->Get_Children_Count() + 1, History_Tool["OUTPUT"].Get_Property("id"));
2325
2326 return( _Save_History_Add_Tool(History_Tool, Parms, *Tool.Get_Parent()) );
2327 }
2328 }
2329
2330 CSG_String VarName = CSG_String::Format("%s__%s", Tool.Get_Property("id"), History.Get_Property("id"));
2331
2332 pInput->Set_Content(VarName);
2333
2334 CSG_MetaData *pParameter = Parms.Ins_Child("input", 0);
2335
2336 pParameter->Add_Property("varname" , VarName);
2337 pParameter->Add_Property("type" , History.Get_Property("type"));
2338 pParameter->Add_Child ("name" , History.Get_Property("name"));
2339// pParameter->Add_Child ("description", History.Get_Property("name"));
2340
2341 return( true );
2342}
2343
2344
2346// //
2347// //
2348// //
2350
2351//---------------------------------------------------------
void SG_UI_Msg_Add(const char *Message, bool bNewLine, TSG_UI_MSG_STYLE Style)
bool SG_UI_DataObject_Add(CSG_Data_Object *pDataObject, int Show)
@ SG_UI_MSG_STYLE_FAILURE
Definition api_core.h:1585
@ SG_UI_MSG_STYLE_SUCCESS
Definition api_core.h:1584
SAGA_API_DLL_EXPORT bool SG_File_Cmp_Extension(const CSG_String &File, const CSG_String &Extension)
SAGA_API_DLL_EXPORT const SG_Char * SG_Translate(const CSG_String &Text)
#define SG_T(s)
Definition api_core.h:537
SAGA_API_DLL_EXPORT CSG_String SG_File_Make_Path(const CSG_String &Directory, const CSG_String &Name)
SAGA_API_DLL_EXPORT CSG_String SG_File_Get_Name(const CSG_String &full_Path, bool bExtension)
@ SG_UI_DATAOBJECT_SHOW_MAP
Definition api_core.h:1598
@ SG_UI_DATAOBJECT_UPDATE
Definition api_core.h:1597
#define SG_Char
Definition api_core.h:536
#define _TL(s)
Definition api_core.h:1568
size_t Get_uSize(void) const
Definition api_core.h:437
const SG_Char * Get_Name(void) const
void Set_Name(const CSG_String &Name)
virtual bool is_Valid(void) const =0
class CSG_Grid * asGrid(bool bPolymorph=false) const
bool Create(const CSG_Grid_System &System, int Precision=-1)
bool is_Valid(void) const
const CSG_Grid_System & Get_System(void) const
Definition grid.h:559
bool Del_Grids(bool bDetach=false)
Definition grids.cpp:891
CSG_Grid * Get_Grid_Ptr(int i) const
Definition grids.h:263
void Fmt_Content(const char *Format,...)
Definition metadata.cpp:510
bool Cmp_Name(const CSG_String &String, bool bNoCase=true) const
Definition metadata.cpp:461
const CSG_String & Get_Name(void) const
Definition metadata.h:132
int Get_Children_Count(void) const
Definition metadata.h:148
CSG_MetaData * Get_Child(int Index) const
Definition metadata.h:149
bool Set_Property(const CSG_String &Name, const CSG_String &Value, bool bAddIfNotExists=true)
Definition metadata.cpp:615
bool Cmp_Property(const CSG_String &Name, const CSG_String &String, bool bNoCase=false) const
Definition metadata.cpp:671
bool Add_Children(const CSG_MetaData &MetaData)
Definition metadata.cpp:359
CSG_MetaData * Get_Parent(void) const
Definition metadata.h:145
const CSG_String & Get_Content(void) const
Definition metadata.h:133
const SG_Char * Get_Property(int Index) const
Definition metadata.h:181
void Set_Name(const CSG_String &Name)
Definition metadata.h:130
CSG_String asText(int Flags=0) const
Definition metadata.cpp:698
void Set_Content(const CSG_String &Content)
Definition metadata.h:140
CSG_MetaData * Add_Child(void)
Definition metadata.cpp:166
void Destroy(void)
Definition metadata.cpp:140
CSG_MetaData * Ins_Child(int Position)
Definition metadata.cpp:207
bool Add_Property(const CSG_String &Name, const CSG_String &Value)
Definition metadata.cpp:559
CSG_String Get_Items(bool bIncludeData=false) const
CSG_String Get_Items(void) const
virtual TSG_Parameter_Type Get_Type(void) const
bool is_Directory(void) const
Definition parameters.h:877
bool is_Multiple(void) const
Definition parameters.h:874
bool is_Save(void) const
Definition parameters.h:871
bool Get_FilePaths(CSG_Strings &FilePaths) const
const SG_Char * Get_Filter(void) const
virtual TSG_Parameter_Type Get_Type(void) const
virtual bool Del_Items(void)
CSG_Data_Object * Get_Item(int Index) const
virtual bool Add_Item(CSG_Data_Object *pItem)
int Get_Item_Count(void) const
CSG_Parameter_Double * Get_Min_Parameter(void) const
Definition parameters.h:628
CSG_Parameter_Double * Get_Max_Parameter(void) const
Definition parameters.h:632
virtual TSG_Parameter_Type Get_Type(void) const
double Get_Minimum(void) const
Definition parameters.h:448
double Get_Maximum(void) const
Definition parameters.h:452
bool has_Maximum(void) const
Definition parameters.h:453
bool has_Minimum(void) const
Definition parameters.h:449
const SG_Char * Get_Identifier(void) const
bool is_DataObject(void) const
class CSG_Parameters * asParameters(void) const
bool Assign(CSG_Parameter *pSource)
CSG_Grids * asGrids(void) const
CSG_String Get_Type_Identifier(void) const
bool is_Optional(void) const
Definition parameters.h:238
TSG_Data_Object_Type Get_DataObject_Type(void) const
bool Serialize(CSG_MetaData &MetaData, bool bSave)
int Get_Children_Count(void) const
Definition parameters.h:259
class CSG_Parameter_Choice * asChoice(void) const
class CSG_Parameter_Value * asValue(void) const
double asDouble(void) const
Definition parameters.h:289
CSG_Parameter * Get_Parent(void) const
virtual TSG_Parameter_Type Get_Type(void) const =0
bool asBool(void) const
Definition parameters.h:286
bool is_Input(void) const
Definition parameters.h:236
const SG_Char * Get_Name(void) const
class CSG_Parameter_Choices * asChoices(void) const
bool is_Enabled(bool bCheckEnv=true) const
bool is_Option(void) const
virtual bool Set_Value(int Value)
class CSG_Parameter_List * asList(void) const
CSG_Grid_System * asGrid_System(void) const
CSG_Data_Object * asDataObject(void) const
class CSG_Parameter_Range * asRange(void) const
bool is_Output(void) const
Definition parameters.h:237
bool has_Changed(int Check_Flags=PARAMETER_CHECK_ALL)
class CSG_Parameter_File_Name * asFilePath(void) const
bool is_Information(void) const
Definition parameters.h:239
const SG_Char * asString(void) const
Definition parameters.h:290
CSG_Table * asTable(void) const
const SG_Char * Get_Description(void) const
bool is_DataObject_List(void) const
int asInt(void) const
Definition parameters.h:287
const CSG_String & Get_Identifier(void) const
int Get_Count(void) const
bool Del_Parameters(void)
void Del_References(void)
CSG_Parameter * Get_Parameter(int i) const
CSG_String AfterFirst(char Character) const
int CmpNoCase(const CSG_String &String) const
int Cmp(const CSG_String &String) const
void Clear(void)
CSG_String BeforeFirst(char Character) const
size_t Replace(const CSG_String &Old, const CSG_String &New, bool bReplaceAll=true)
static CSG_String Format(const char *Format,...)
int Find(char Character, bool fromEnd=false) const
CSG_String Right(size_t count) const
int asInt(void) const
const SG_Char * c_str(void) const
CSG_String & Make_Lower(void)
int Printf(const char *Format,...)
bool is_Empty(void) const
double asDouble(void) const
int Get_Count(void) const
Definition api_core.h:714
bool Assign_Values(const CSG_Table &Table)
Definition table.cpp:378
virtual int On_Parameters_Enable(CSG_Parameters *pParameters, CSG_Parameter *pParameter)
bool is_Okay(void) const
Definition tool_chain.h:96
void Set_Library_Menu(const CSG_String &Menu)
static CSG_String Get_Script(CSG_Tool *pTool, bool bHeader, bool bAllParameters=true)
bool Create(const CSG_Tool_Chain &Tool, bool bWithGUI, bool bWithCMD)
virtual ~CSG_Tool_Chain(void)
virtual bool On_Execute(void)
static bool Save_History_to_Model(const CSG_MetaData &History, const CSG_String &File)
virtual bool do_Sync_Projections(void) const
virtual CSG_Tool * Create_Tool(const CSG_String &Name, bool bWithGUI=false, bool bWithCMD=true)
virtual CSG_String Get_Info(int Type) const
virtual ~CSG_Tool_Chains(void)
CSG_Tool_Chains(const CSG_String &Library_Name, const CSG_String &Path)
virtual int Get_Count(void) const
Definition tool_chain.h:185
virtual bool Delete_Tools(void)
virtual bool Delete_Tool(CSG_Tool *pTool)
bool Add_Tool(CSG_Tool_Chain *pTool)
virtual CSG_Tool * Get_Tool(int Index, TSG_Tool_Type Type=TOOL_TYPE_Base) const
bool Delete_Tool(CSG_Tool *pTool) const
CSG_Tool * Create_Tool(const CSG_String &Library, int Index, bool bWithGUI=false, bool bWithCMD=true) const
virtual CSG_Tool * Get_Tool(int Index, TSG_Tool_Type Type=TOOL_TYPE_Base) const
void Add_Reference(const CSG_String &Authors, const CSG_String &Year, const CSG_String &Title, const CSG_String &Where, const SG_Char *Link=NULL, const SG_Char *Link_Text=NULL)
CSG_String m_Library_Name
CSG_String Get_Name(void) const
const CSG_String & Get_Library(void) const
Definition tool.cpp:115
bool Set_Grid_System(const CSG_Grid_System &System)
Definition tool.cpp:1402
int Get_Parameters_Count(void) const
Definition tool.h:167
virtual bool On_After_Execution(void)
Definition tool.h:230
bool Settings_Pop(void)
Definition tool.cpp:634
bool has_GUI(void) const
Definition tool.cpp:239
CSG_Parameters * Get_Parameters(void)
Definition tool.h:165
static bool DataObject_Set_Colors(CSG_Data_Object *pDataObject, const CSG_Colors &Colors)
Definition tool.cpp:1001
const CSG_String & Get_Name(void) const
Definition tool.cpp:132
static void Process_Set_Text(const CSG_String &Text)
Definition tool.cpp:852
bool Settings_Push(class CSG_Data_Manager *pManager=NULL)
Definition tool.cpp:621
virtual bool On_Before_Execution(void)
Definition tool.h:229
CSG_Parameters Parameters
Definition tool.h:256
virtual TSG_Tool_Type Get_Type(void) const
Definition tool.h:148
CSG_Tool(void)
Definition tool.cpp:67
virtual CSG_String Get_MenuPath(void)
Definition tool.h:162
void Set_Description(const CSG_String &String)
Definition tool.cpp:160
bool Execute(bool bAddHistory=false)
Definition tool.cpp:258
void Message_Fmt(const char *Format,...)
Definition tool.cpp:921
void Set_Author(const CSG_String &String)
Definition tool.cpp:138
const CSG_String & Get_Description(void) const
Definition tool.cpp:165
const CSG_String & Get_ID(void) const
Definition tool.h:150
bool Error_Set(TSG_Tool_Error Error_ID=TOOL_ERROR_Unknown)
Definition tool.cpp:705
bool Error_Fmt(const char *Format,...)
Definition tool.cpp:742
virtual int On_Parameters_Enable(CSG_Parameters *pParameters, CSG_Parameter *pParameter)
Definition tool.cpp:482
void Add_Reference(const CSG_String &Authors, const CSG_String &Year, const CSG_String &Title, const CSG_String &Where, const SG_Char *Link=NULL, const SG_Char *Link_Text=NULL)
Definition tool.cpp:171
void Message_Dlg(const CSG_String &Text, const SG_Char *Caption=NULL)
Definition tool.cpp:693
void Set_Name(const CSG_String &String)
Definition tool.cpp:127
@ SG_DATAOBJECT_TYPE_PointCloud
Definition dataobject.h:123
@ SG_DATAOBJECT_TYPE_Grids
Definition dataobject.h:119
@ SG_DATAOBJECT_TYPE_TIN
Definition dataobject.h:122
@ SG_DATAOBJECT_TYPE_Shapes
Definition dataobject.h:121
@ SG_DATAOBJECT_TYPE_Grid
Definition dataobject.h:118
@ SG_DATAOBJECT_TYPE_Table
Definition dataobject.h:120
#define DATAOBJECT_CREATE
Definition dataobject.h:130
#define B
#define A
TSG_Parameter_Type SG_Parameter_Type_Get_Type(const CSG_String &Identifier)
CSG_String SG_Parameter_Type_Get_Identifier(TSG_Parameter_Type Type)
#define PARAMETER_INPUT_OPTIONAL
Definition parameters.h:103
#define PARAMETER_OUTPUT_OPTIONAL
Definition parameters.h:104
TSG_Parameter_Type
Definition parameters.h:123
@ PARAMETER_TYPE_Degree
Definition parameters.h:129
@ PARAMETER_TYPE_FixedTable
Definition parameters.h:142
@ PARAMETER_TYPE_Node
Definition parameters.h:124
@ PARAMETER_TYPE_Grid
Definition parameters.h:149
@ PARAMETER_TYPE_Grid_List
Definition parameters.h:155
@ PARAMETER_TYPE_Text
Definition parameters.h:136
@ PARAMETER_TYPE_TIN
Definition parameters.h:153
@ PARAMETER_TYPE_Table
Definition parameters.h:151
@ PARAMETER_TYPE_Int
Definition parameters.h:127
@ PARAMETER_TYPE_Table_Fields
Definition parameters.h:146
@ PARAMETER_TYPE_Grids
Definition parameters.h:150
@ PARAMETER_TYPE_Color
Definition parameters.h:140
@ PARAMETER_TYPE_Colors
Definition parameters.h:141
@ PARAMETER_TYPE_DataObject_Output
Definition parameters.h:162
@ PARAMETER_TYPE_Table_List
Definition parameters.h:157
@ PARAMETER_TYPE_Double
Definition parameters.h:128
@ PARAMETER_TYPE_TIN_List
Definition parameters.h:159
@ PARAMETER_TYPE_Grid_System
Definition parameters.h:144
@ PARAMETER_TYPE_Font
Definition parameters.h:139
@ PARAMETER_TYPE_Date
Definition parameters.h:130
@ PARAMETER_TYPE_PointCloud_List
Definition parameters.h:160
@ PARAMETER_TYPE_Choices
Definition parameters.h:134
@ PARAMETER_TYPE_Data_Type
Definition parameters.h:132
@ PARAMETER_TYPE_Shapes
Definition parameters.h:152
@ PARAMETER_TYPE_Shapes_List
Definition parameters.h:158
@ PARAMETER_TYPE_Range
Definition parameters.h:131
@ PARAMETER_TYPE_PointCloud
Definition parameters.h:148
@ PARAMETER_TYPE_Table_Field
Definition parameters.h:145
@ PARAMETER_TYPE_Parameters
Definition parameters.h:164
@ PARAMETER_TYPE_FilePath
Definition parameters.h:137
@ PARAMETER_TYPE_Bool
Definition parameters.h:126
@ PARAMETER_TYPE_Grids_List
Definition parameters.h:156
@ PARAMETER_TYPE_String
Definition parameters.h:135
@ PARAMETER_TYPE_Choice
Definition parameters.h:133
#define PARAMETER_OUTPUT
Definition parameters.h:95
#define PARAMETER_INPUT
Definition parameters.h:94
int SG_Compare_Version(const CSG_String &Version, int Major, int Minor, int Release)
Definition saga_api.cpp:82
#define SAGA_VERSION
Definition saga_api.h:90
@ SHAPE_TYPE_Polygon
Definition shapes.h:105
@ SHAPE_TYPE_Line
Definition shapes.h:104
@ SHAPE_TYPE_Points
Definition shapes.h:103
@ SHAPE_TYPE_Point
Definition shapes.h:102
@ SHAPE_TYPE_Undefined
Definition shapes.h:101
@ TLB_INFO_Menu_Path
Definition tool.h:641
@ TLB_INFO_Name
Definition tool.h:637
@ TLB_INFO_Category
Definition tool.h:642
@ TLB_INFO_Description
Definition tool.h:638
TSG_Tool_Type
Definition tool.h:101
@ TOOL_TYPE_Base
Definition tool.h:102
@ TOOL_TYPE_Chain
Definition tool.h:106
#define IS_TRUE_PROPERTY(Item, Property)
#define IS_TRUE_STRING(String)
#define Get_List_Item(p, i)
#define Get_List_Count(p)
#define GET_XML_CONTENT(XML, ID, DEFAULT, TRANSLATE)
CSG_Tool_Library_Manager & SG_Get_Tool_Library_Manager(void)