SAGA API Version 9.12
Loading...
Searching...
No Matches
tool_library.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_library.cpp //
15// //
16// Copyright (C) 2006 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 Goettingen //
44// Goldschmidtstr. 5 //
45// 37077 Goettingen //
46// Germany //
47// //
48// e-mail: oconrad@saga-gis.org //
49// //
51
52//---------------------------------------------------------
53#include <wx/dynlib.h>
54#include <wx/dir.h>
55#include <wx/filename.h>
56#include <wx/utils.h>
57
58#include "tool_chain.h"
59
60
62// //
63// //
64// //
66
67//---------------------------------------------------------
69{
70 m_pInterface = NULL;
71 m_pLibrary = NULL;
72}
73
74//---------------------------------------------------------
76{
77 m_pLibrary = new wxDynamicLibrary(SG_File_Get_Path_Absolute(File).c_str(), wxDL_DEFAULT|wxDL_QUIET);
78
79 if( m_pLibrary->IsLoaded()
80 && m_pLibrary->HasSymbol(SYMBOL_TLB_Get_Interface)
81 && m_pLibrary->HasSymbol(SYMBOL_TLB_Initialize)
82 && m_pLibrary->HasSymbol(SYMBOL_TLB_Finalize)
83 && ((TSG_PFNC_TLB_Initialize)m_pLibrary->GetSymbol(SYMBOL_TLB_Initialize))(File) )
84 {
85 m_pInterface = ((TSG_PFNC_TLB_Get_Interface)m_pLibrary->GetSymbol(SYMBOL_TLB_Get_Interface))();
86
87 if( m_pInterface->Get_Count() > 0 )
88 {
89 m_File_Name = m_pInterface->Get_Info(TLB_INFO_File );
90 m_Library_Name = m_pInterface->Get_Info(TLB_INFO_Library );
91 m_Description = m_pInterface->Get_Info(TLB_INFO_Description);
92
93 m_References.Set_Name(_TL("References"));
94 m_References.Add_Field("Authors" , SG_DATATYPE_String);
95 m_References.Add_Field("Date" , SG_DATATYPE_String);
96 m_References.Add_Field("Title" , SG_DATATYPE_String);
97 m_References.Add_Field("Source" , SG_DATATYPE_String);
98 m_References.Add_Field("Link" , SG_DATATYPE_String);
99 m_References.Add_Field("LinkText" , SG_DATATYPE_String);
100
102
103 return; // success
104 }
105 }
106
107 _Destroy();
108}
109
110//---------------------------------------------------------
112{
113 _Destroy();
114}
115
116//---------------------------------------------------------
117bool CSG_Tool_Library::_Destroy(void)
118{
119 if( m_pLibrary )
120 {
121 if( m_pLibrary->IsLoaded() && m_pLibrary->HasSymbol(SYMBOL_TLB_Finalize) )
122 {
123 TSG_PFNC_TLB_Finalize TLB_Finalize = (TSG_PFNC_TLB_Finalize)m_pLibrary->GetSymbol(SYMBOL_TLB_Finalize);
124
125 TLB_Finalize();
126 }
127
128 Del_References(); m_Description.Clear();
129
130 delete(m_pLibrary);
131
132 m_pLibrary = NULL;
133 }
134
135 m_pInterface = NULL;
136
137 return( true );
138}
139
140
142// //
144
145//---------------------------------------------------------
147{
148 if( m_pInterface != NULL )
149 {
150 return( m_pInterface->Get_Info(Type) );
151 }
152
153 static CSG_String Dummy; return( Dummy );
154}
155
156
158// //
160
161//---------------------------------------------------------
163{
164 CSG_Tool *pTool = m_pInterface && Index >= 0 && Index < Get_Count() ? m_pInterface->Get_Tool(Index) : NULL;
165
166 return( pTool && (Type == TOOL_TYPE_Base || Type == pTool->Get_Type()) ? pTool : NULL );
167}
168
169//---------------------------------------------------------
170CSG_Tool * CSG_Tool_Library::Get_Tool(const char *Name, TSG_Tool_Type Type) const { return( Get_Tool(CSG_String(Name), Type) ); }
171CSG_Tool * CSG_Tool_Library::Get_Tool(const wchar_t *Name, TSG_Tool_Type Type) const { return( Get_Tool(CSG_String(Name), Type) ); }
173{
174 for(int i=0; i<Get_Count(); i++)
175 {
176 CSG_Tool *pTool = Get_Tool(i, Type);
177
178 if( pTool && (!pTool->Get_ID().Cmp(Name) || !pTool->Get_Name().Cmp(Name)) )
179 {
180 return( pTool );
181 }
182 }
183
184 return( NULL );
185}
186
187
189// //
191
192//---------------------------------------------------------
202//---------------------------------------------------------
203CSG_Tool * CSG_Tool_Library::Create_Tool(int Index, bool bWithGUI, bool bWithCMD)
204{
205 return( m_pInterface ? m_pInterface->Create_Tool(Index, bWithGUI, bWithCMD) : NULL );
206}
207
208//---------------------------------------------------------
209CSG_Tool * CSG_Tool_Library::Create_Tool(const char *Name, bool bWithGUI, bool bWithCMD) { return( Create_Tool(CSG_String(Name), bWithGUI, bWithCMD) ); }
210CSG_Tool * CSG_Tool_Library::Create_Tool(const wchar_t *Name, bool bWithGUI, bool bWithCMD) { return( Create_Tool(CSG_String(Name), bWithGUI, bWithCMD) ); }
211CSG_Tool * CSG_Tool_Library::Create_Tool(const CSG_String &Name, bool bWithGUI, bool bWithCMD)
212{
213 int Index; return( Name.asInt(Index) ? Create_Tool(Index, bWithGUI, bWithCMD) : NULL );
214}
215
216//---------------------------------------------------------
221//---------------------------------------------------------
223{
224 return( m_pInterface ? m_pInterface->Delete_Tool(pTool) : false );
225}
226
227//---------------------------------------------------------
229{
230 return( m_pInterface ? m_pInterface->Delete_Tools() : false );
231}
232
233
235// //
237
238//---------------------------------------------------------
240{
241 if( Get_Tool(i) )
242 {
243 return( Get_Tool(i)->Get_MenuPath(true) );
244 }
245
246 return( "" );
247}
248
249
251// //
253
254//---------------------------------------------------------
256{
258
259 if( SG_Dir_Exists(Folder) )
260 {
261 CSG_String Description; CSG_File Stream; CSG_Table Table;
262
263 if( Stream.Open(SG_File_Make_Path(Folder, m_Library_Name, "txt"), SG_FILE_R, true, SG_FILE_ENCODING_UTF8) && Stream.Read(Description) > 0 )
264 {
265 m_Description = CSG_Text_Format_Converter::Markdown_to_Html(Description, true);
266 m_Description = CSG_Text_Format_Converter::Html_Absolute_Image_Paths(m_Description, Folder, true);
267 }
268
270
272
273 if( Table.Create(SG_File_Make_Path(Folder, m_Library_Name + "_references", "txt")) && Table.Get_Field_Count() == 6 )
274 {
275 for(int i=0; i<Table.Get_Field_Count(); i++) { Table.Set_Field_Type(i, SG_DATATYPE_String); }
276
277 for(sLong i=0; i<Table.Get_Count(); i++)
278 {
279 Add_Reference(Table[i].asString(0), Table[i].asString(1), Table[i].asString(2), Table[i].asString(3), Table[i].asString(4), Table[i].asString(5));
280 }
281 }
282
284
285 return( true );
286 }
287
288 return( false );
289}
290
291//---------------------------------------------------------
292void CSG_Tool_Library::Add_Reference(const CSG_String &Authors, const CSG_String &Date, const CSG_String &Title, const CSG_String &Source, const CSG_String &Link, const CSG_String &LinkText)
293{
294 CSG_Table_Record &Reference = *m_References.Add_Record();
295
296 Reference.Set_Value(0, Authors );
297 Reference.Set_Value(1, Date );
298 Reference.Set_Value(2, Title );
299 Reference.Set_Value(3, Source );
300 Reference.Set_Value(4, Link );
301 Reference.Set_Value(5, LinkText);
302
303 m_References.Sort(0);
304}
305
306//---------------------------------------------------------
307void CSG_Tool_Library::Add_Reference(const CSG_String &Link, const CSG_String &Link_Text)
308{
309 Add_Reference("", "", "", "", Link, Link_Text);
310}
311
312//---------------------------------------------------------
314{
315 return( m_References.Del_Records() );
316}
317
318//---------------------------------------------------------
320{
321 CSG_Strings References;
322
323 for(int i=0; i<m_References.Get_Count(); i++)
324 {
325 CSG_String Reference,
326 Authors(m_References[i].asString(0)),
327 Date (m_References[i].asString(1)),
328 Title (m_References[i].asString(2)),
329 Source (m_References[i].asString(3)),
330 Link (m_References[i].asString(4)),
331 LinkTxt(m_References[i].asString(5));
332
333 if( !Authors.is_Empty() )
334 {
335 if( Date.is_Empty() ) { Date = "n.d."; }
336
337 Reference += bHTML ? "<b>" + Authors + " (" + Date + "):</b>" : Authors + " (" + Date + "):";
338 }
339 else if( !Date.is_Empty() ) // date only
340 {
341 Reference += bHTML ? "<b>(" + Date + "):</b>" : "(" + Date + "):";
342 }
343
344 if( !Title.is_Empty() ) // title
345 {
346 if( Title[Title.Length() - 1] != '.' ) { Title += '.'; }
347
348 if( !Reference.is_Empty() ) { Reference += " "; }
349
350 Reference += bHTML ? "<i>" + Title + "</i>" : Title;
351 }
352
353 if( !Source.is_Empty() ) // title
354 {
355 if( Source[Source.Length() - 1] != '.' ) { Source += '.'; }
356
357 if( !Reference.is_Empty() ) { Reference += " "; }
358
359 Reference += Source;
360 }
361
362 if( !Link.is_Empty() )
363 {
364 if( !Reference.is_Empty() ) { Reference += " "; }
365
366 Reference += bHTML ? "<a href=\"" + Link + "\">" + (LinkTxt.is_Empty() ? Link : LinkTxt) + "</a>" : "[" + LinkTxt + "](" + Link + ")";
367 }
368
369 if( !Reference.is_Empty() )
370 {
371 References += Reference;
372 }
373 }
374
375 return( References );
376}
377
378
380// //
381// //
382// //
384
385//---------------------------------------------------------
387
388//---------------------------------------------------------
393
394
396// //
398
399//---------------------------------------------------------
401{
402 m_pLibraries = NULL;
403 m_nLibraries = 0;
404
405 if( this == &g_Tool_Library_Manager )
406 {
407 CSG_Random::Initialize(); // initialize with current time on startup
408 }
409}
410
411//---------------------------------------------------------
416
417
419// //
421
422//---------------------------------------------------------
424{
425 int nTools = 0;
426
427 for(int i=0; i<m_nLibraries; i++)
428 {
429 nTools += m_pLibraries[i]->Get_Count();
430 }
431
432 return( nTools );
433}
434
435
437// //
439
440//---------------------------------------------------------
442{
443 if( bVerbose == false )
444 {
445 SG_UI_Msg_Lock(true);
446 }
447
448 //-----------------------------------------------------
449 #if defined(_SAGA_MSW)
450 {
452 }
453 #elif defined(__WXMAC__)
454 {
455 if( SG_Get_Tool_Library_Manager().Add_Directory(SG_UI_Get_Application_Path(true) + "/../Tools", false) < 1 )
456 {
457 #ifdef TOOLS_PATH
459 #endif
460
461 #ifdef SHARE_PATH
462 SG_Get_Tool_Library_Manager().Add_Directory(SG_File_Make_Path(SHARE_PATH, "toolchains")); // look for tool chains
463 #endif
464 }
465 }
466 #else // #if defined(_SAGA_LINUX)
467 {
468 #ifdef TOOLS_PATH
470 #endif
471
472 #ifdef SHARE_PATH
473 SG_Get_Tool_Library_Manager().Add_Directory(SG_File_Make_Path(SHARE_PATH, "toolchains")); // look for tool chains
474 #endif
475 }
476 #endif
477
478 //-----------------------------------------------------
479 CSG_String Paths;
480
481 if( SG_Get_Environment("SAGA_TLB", &Paths) )
482 {
483 #if defined(_SAGA_MSW)
484 CSG_Strings Path = SG_String_Tokenize(Paths, ";" ); // colon (':') would split drive from paths!
485 #else // #if defined(_SAGA_LINUX) || defined(__WXMAC__)
486 CSG_Strings Path = SG_String_Tokenize(Paths, ";:"); // colon (':') is more native to non-windows os than semi-colon (';'), we support both...
487 #endif
488
489 for(int i=0; i<Path.Get_Count(); i++)
490 {
492 }
493 }
494
495 //-----------------------------------------------------
496 if( bVerbose == false )
497 {
498 SG_UI_Msg_Lock(false);
499 }
500
501 return( Get_Count() > 0 );
502}
503
504
506// //
508
509//---------------------------------------------------------
513{
514 if( SG_File_Exists(File) == false )
515 {
516 return( NULL );
517 }
518
519 if( SG_File_Cmp_Extension(File, "xml") )
520 {
521 return( _Add_Tool_Chain(File) );
522 }
523
524 if( SG_File_Cmp_Extension(File, "dll" ) == false
525 && SG_File_Cmp_Extension(File, "dylib") == false
526 && SG_File_Cmp_Extension(File, "so" ) == false )
527 {
528 return( NULL );
529 }
530
531 //-----------------------------------------------------
532 wxFileName FileName(File.c_str());
533
534 SG_UI_Msg_Add(CSG_String::Format("%s: %s...", _TL("Loading library"), File.c_str()), true);
535
536 for(int i=0; i<Get_Count(); i++)
537 {
538 if( FileName == Get_Library(i)->Get_File_Name().c_str() )
539 {
540 SG_UI_Msg_Add(_TL("has already been loaded"), false);
541
542 return( Get_Library(i) );
543 }
544 }
545
546 //-----------------------------------------------------
547 CSG_Tool_Library *pLibrary = new CSG_Tool_Library(File);
548
549 if( pLibrary->is_Valid() )
550 {
551 m_pLibraries = (CSG_Tool_Library **)SG_Realloc(m_pLibraries, (m_nLibraries + 1) * sizeof(CSG_Tool_Library *));
552 m_pLibraries[m_nLibraries++] = pLibrary;
553
555
556 return( pLibrary );
557 }
558
559 delete(pLibrary);
560
561 SG_UI_Msg_Add(_TL("failed"), false, SG_UI_MSG_STYLE_FAILURE);
562
563 return( NULL );
564}
565
566//---------------------------------------------------------
567int CSG_Tool_Library_Manager::Add_Directory(const char *Directory, bool bOnlySubDirectories) { return( Add_Directory(CSG_String(Directory), bOnlySubDirectories) ); }
568int CSG_Tool_Library_Manager::Add_Directory(const wchar_t *Directory, bool bOnlySubDirectories) { return( Add_Directory(CSG_String(Directory), bOnlySubDirectories) ); }
569int CSG_Tool_Library_Manager::Add_Directory(const CSG_String &Directory, bool bOnlySubDirectories)
570{
571 int nOpened = 0; wxDir Dir;
572
573 if( Dir.Open(Directory.c_str()) )
574 {
575 wxString FileName, DirName(Dir.GetName());
576
577 if( !bOnlySubDirectories && Dir.GetFirst(&FileName, wxEmptyString, wxDIR_FILES) )
578 {
579 do
580 { if( FileName.Find("saga_") < 0 && FileName.Find("wx") < 0 )
581 if( Add_Library(SG_File_Make_Path(&DirName, &FileName)) )
582 {
583 nOpened++;
584 }
585 }
586 while( Dir.GetNext(&FileName) );
587 }
588
589 if( Dir.GetFirst(&FileName, wxEmptyString, wxDIR_DIRS) )
590 {
591 do
592 {
593 if( FileName.CmpNoCase("dll") )
594 {
595 nOpened += Add_Directory(SG_File_Make_Path(&DirName, &FileName), false);
596 }
597 }
598 while( Dir.GetNext(&FileName) );
599 }
600 }
601
602 return( nOpened );
603}
604
605
607// //
609
610//---------------------------------------------------------
611CSG_Tool_Library * CSG_Tool_Library_Manager::_Add_Tool_Chain(const CSG_String &File, bool bReload)
612{
613 if( !SG_File_Cmp_Extension(File, "xml") )
614 {
615 return( NULL );
616 }
617
618 //-----------------------------------------------------
619 CSG_Tool_Chains *pLibrary = NULL;
620 CSG_Tool_Chain *pTool = NULL;
621
622 //-----------------------------------------------------
623 wxFileName FileName(File.c_str()); // check if tool chain is already loaded ?
624
625 for(int iLibrary=0; !pTool && iLibrary<Get_Count(); iLibrary++)
626 {
627 if( Get_Library(iLibrary)->Get_Type() == ESG_Library_Type::Chain )
628 {
629 for(int iTool=0; !pTool && iTool<Get_Library(iLibrary)->Get_Count(); iTool++)
630 {
631 if( FileName == ((CSG_Tool_Chain *)Get_Library(iLibrary)->Get_Tool(iTool))->Get_File_Name().c_str() )
632 {
633 pLibrary = (CSG_Tool_Chains *)Get_Library(iLibrary);
634 pTool = (CSG_Tool_Chain *)Get_Library(iLibrary)->Get_Tool(iTool);
635 }
636 }
637 }
638 }
639
640 if( pTool )
641 {
642 if( bReload ) // ...then try to reload !
643 {
645 CSG_Tool_Chain Tool(File); // don't reset loaded tool in case reloading fails!!!
647
648 if( Tool.is_Okay() )
649 {
650 pTool->Create(File);
651 }
652 }
653
654 return( pLibrary );
655 }
656
657 //-----------------------------------------------------
658 pTool = new CSG_Tool_Chain(File);
659
660 if( !pTool || !pTool->is_Okay() )
661 {
662 if( pTool )
663 {
664 delete(pTool);
665 }
666
667 return( NULL );
668 }
669
670 //-----------------------------------------------------
671 CSG_String Library = pTool->Get_Library();
672
673 for(int iLibrary=0; !pLibrary && iLibrary<Get_Count(); iLibrary++)
674 {
675 if( Get_Library(iLibrary)->Get_Type() == ESG_Library_Type::Chain
676 && Get_Library(iLibrary)->Get_Library_Name().Cmp(Library) == 0 )
677 {
678 pLibrary = (CSG_Tool_Chains *)Get_Library(iLibrary);
679 }
680 }
681
682 if( !pLibrary && (pLibrary = new CSG_Tool_Chains(pTool->Get_Library(), SG_File_Get_Path(File))) != NULL )
683 {
684 m_pLibraries = (CSG_Tool_Library **)SG_Realloc(m_pLibraries, (m_nLibraries + 1) * sizeof(CSG_Tool_Library *));
685 m_pLibraries[m_nLibraries++] = pLibrary;
686 }
687
688 if( !pLibrary ) // this should never happen, but who knows...
689 {
690 SG_UI_Msg_Add_Error(CSG_String::Format("%s %s: %s", _TL("ERROR"), _TL("tool chain library"), File.c_str()));
691
692 delete(pTool);
693
694 return( NULL );
695 }
696
697 pLibrary->Add_Tool(pTool);
698
699 //-----------------------------------------------------
700 return( pLibrary );
701}
702
703
705// //
707
708//---------------------------------------------------------
710{
711 if( m_pLibraries )
712 {
713 for(int i=0; i<Get_Count(); i++)
714 {
715// #ifndef _SAGA_MSW
716 if( !SG_UI_Get_Window_Main() && m_pLibraries[i]->m_pLibrary )
717 {
718 m_pLibraries[i]->m_pLibrary->Detach();
719 }
720// #endif
721
722 delete(m_pLibraries[i]);
723 }
724
725 SG_Free(m_pLibraries);
726
727 m_pLibraries = NULL;
728 m_nLibraries = 0;
729 }
730
731 return( true );
732}
733
734
736// //
738
739//---------------------------------------------------------
741{
742 for(int i=0; i<Get_Count(); i++)
743 {
744 if( pLibrary == Get_Library(i) )
745 {
746 return( Del_Library(i) );
747 }
748 }
749
750 return( false );
751}
752
753//---------------------------------------------------------
755{
756 if( i >= 0 && i < Get_Count() )
757 {
758 delete(m_pLibraries[i]);
759
760 for(m_nLibraries--; i<m_nLibraries; i++)
761 {
762 m_pLibraries[i] = m_pLibraries[i + 1];
763 }
764
765 m_pLibraries = (CSG_Tool_Library **)SG_Realloc(m_pLibraries, m_nLibraries * sizeof(CSG_Tool_Library *));
766
767 return( true );
768 }
769
770 return( false );
771}
772
773//---------------------------------------------------------
775{
776 for(int i=0; i<Get_Count(); i++)
777 {
778 if( pLibrary == Get_Library(i) )
779 {
780 return( true );
781 }
782 }
783
784 return( false );
785}
786
787
789// //
791
792//---------------------------------------------------------
797
798//---------------------------------------------------------
799CSG_Tool_Library * CSG_Tool_Library_Manager::Get_Library(const char *Name, bool bLibrary, ESG_Library_Type Type) const { return( Get_Library(CSG_String(Name), bLibrary, Type) ); }
800CSG_Tool_Library * CSG_Tool_Library_Manager::Get_Library(const wchar_t *Name, bool bLibrary, ESG_Library_Type Type) const { return( Get_Library(CSG_String(Name), bLibrary, Type) ); }
802{
803 if( bLibrary )
804 {
805 SG_Get_Tool_Library_Manager()._Add_Library(Name);
806 }
807
808 for(int i=0; i<Get_Count(); i++)
809 {
810 CSG_Tool_Library *pLibrary = Get_Library(i);
811
812 if( Type == ESG_Library_Type::Undefined || Type == pLibrary->Get_Type() )
813 {
814 if( !Name.Cmp(bLibrary ? pLibrary->Get_Library_Name() : pLibrary->Get_Name()) )
815 {
816 return( pLibrary );
817 }
818 }
819 }
820
821 return( NULL );
822}
823
824//---------------------------------------------------------
825bool CSG_Tool_Library_Manager::_Add_Library(const CSG_String &Library)
826{
827 int bOkay = false;
828
830
831 //-----------------------------------------------------
832 #if defined(_SAGA_MSW)
833 if( Add_Library ( CSG_String::Format("%s\\tools\\%s.dll" , SG_UI_Get_API_Path().c_str() , Library.c_str())) ) { bOkay = true; }
834 if( _Add_Library_Chains(Library, CSG_String::Format("%s\\tools\\toolchains" , SG_UI_Get_API_Path().c_str() )) ) { bOkay = true; }
835 #elif defined(__WXMAC__)
836 if( Add_Library ( CSG_String::Format("%s/../Tools/lib%s.dylib", SG_UI_Get_Application_Path(true).c_str(), Library.c_str())) ) { bOkay = true; }
837 if( _Add_Library_Chains(Library, CSG_String::Format("%s/../Tools" , SG_UI_Get_Application_Path(true).c_str() )) ) { bOkay = true; }
838 #ifdef TOOLS_PATH
839 if( Add_Library ( CSG_String::Format("%s/lib%s.dylib" , CSG_String(TOOLS_PATH).c_str() , Library.c_str())) ) { bOkay = true; }
840 #endif
841 #ifdef SHARE_PATH
842 if( _Add_Library_Chains(Library, CSG_String::Format("%s/toolchains" , CSG_String(SHARE_PATH).c_str() )) ) { bOkay = true; }
843 #endif
844 #else // #if defined(_SAGA_LINUX)
845 #ifdef TOOLS_PATH
846 if( Add_Library ( CSG_String::Format("%s/lib%s.so" , CSG_String(TOOLS_PATH).c_str() , Library.c_str())) ) { bOkay = true; }
847 #endif
848 #ifdef SHARE_PATH
849 if( _Add_Library_Chains(Library, CSG_String::Format("%s/toolchains" , CSG_String(SHARE_PATH).c_str() )) ) { bOkay = true; }
850 #endif
851 #endif
852
853 //-----------------------------------------------------
854 CSG_String Paths;
855
856 if( SG_Get_Environment("SAGA_TLB", &Paths) )
857 {
858 #if defined(_SAGA_MSW)
859 const char *Format("%s\\%s.dll" ); CSG_Strings Path = SG_String_Tokenize(Paths, ";" ); // colon (':') would split drive from paths!
860 #elif defined(__WXMAC__)
861 const char *Format("%s/lib%s.dylib"); CSG_Strings Path = SG_String_Tokenize(Paths, ";:"); // colon (':') is more native to non-windows os than semi-colon (';'), we support both...
862 #else // #if defined(_SAGA_LINUX)
863 const char *Format("%s/lib%s.so" ); CSG_Strings Path = SG_String_Tokenize(Paths, ";:"); // colon (':') is more native to non-windows os than semi-colon (';'), we support both...
864 #endif
865
866 for(int i=0; i<Path.Get_Count(); i++)
867 {
868 if( Add_Library (CSG_String::Format(Format, Path[i].c_str(), Library.c_str())) ) { bOkay = true; }
869 if( _Add_Library_Chains(Library , Path[i]) ) { bOkay = true; }
870 }
871 }
872
873 //-----------------------------------------------------
875
876 return( bOkay );
877}
878
879//---------------------------------------------------------
880bool CSG_Tool_Library_Manager::_Add_Library_Chains(const CSG_String &Library, const CSG_String &Directory)
881{
882 wxDir dir; wxString file; bool bOkay = false;
883
884 if( dir.Open(Directory.c_str()) && dir.GetFirst(&file, wxEmptyString, wxDIR_FILES) )
885 {
886 do
887 {
888 CSG_String path(SG_File_Make_Path(Directory, &file)); CSG_Tool_Chain Tool(path);
889
890 if( Tool.is_Okay() && Tool.Get_Library().Cmp(Library) == 0 && _Add_Tool_Chain(path, false) )
891 {
892 bOkay = true;
893 }
894 }
895 while( dir.GetNext(&file) );
896 }
897
898 return( bOkay );
899}
900
901
903// //
905
906//---------------------------------------------------------
907CSG_Tool * CSG_Tool_Library_Manager::Get_Tool(const char *Library, int ID) const { return( Get_Tool(CSG_String(Library), ID) ); }
908CSG_Tool * CSG_Tool_Library_Manager::Get_Tool(const wchar_t *Library, int ID) const { return( Get_Tool(CSG_String(Library), ID) ); }
910{
911 return( Get_Tool(Library, CSG_String::Format("%d", ID)) );
912}
913
914//---------------------------------------------------------
915CSG_Tool * CSG_Tool_Library_Manager::Get_Tool(const char *Library, const char *Name) const { return( Get_Tool(CSG_String(Library), CSG_String(Name)) ); }
916CSG_Tool * CSG_Tool_Library_Manager::Get_Tool(const wchar_t *Library, const wchar_t *Name) const { return( Get_Tool(CSG_String(Library), CSG_String(Name)) ); }
918{
919 SG_Get_Tool_Library_Manager()._Add_Library(Library);
920
921 for(int i=0; i<Get_Count(); i++)
922 {
923 if( Get_Library(i)->Get_Library_Name().Cmp(Library) == 0 )
924 {
925 CSG_Tool *pTool = Get_Library(i)->Get_Tool(Name);
926
927 if( pTool )
928 {
929 return( pTool );
930 }
931 }
932 }
933
934 return( NULL );
935}
936
937
939// //
941
942//---------------------------------------------------------
943CSG_Tool * CSG_Tool_Library_Manager::Create_Tool(const char *Library, int Index, bool bWithGUI, bool bWithCMD) const { return( Create_Tool(CSG_String(Library), Index, bWithGUI, bWithCMD) ); }
944CSG_Tool * CSG_Tool_Library_Manager::Create_Tool(const wchar_t *Library, int Index, bool bWithGUI, bool bWithCMD) const { return( Create_Tool(CSG_String(Library), Index, bWithGUI, bWithCMD) ); }
945CSG_Tool * CSG_Tool_Library_Manager::Create_Tool(const CSG_String &Library, int Index, bool bWithGUI, bool bWithCMD) const
946{
947 return( Create_Tool(Library, CSG_String::Format("%d", Index), bWithGUI, bWithCMD) );
948}
949
950//---------------------------------------------------------
951CSG_Tool * CSG_Tool_Library_Manager::Create_Tool(const char *Library, const char *Name, bool bWithGUI, bool bWithCMD) const { return( Create_Tool(CSG_String(Library), CSG_String(Name), bWithGUI, bWithCMD) ); }
952CSG_Tool * CSG_Tool_Library_Manager::Create_Tool(const wchar_t *Library, const wchar_t *Name, bool bWithGUI, bool bWithCMD) const { return( Create_Tool(CSG_String(Library), CSG_String(Name), bWithGUI, bWithCMD) ); }
953CSG_Tool * CSG_Tool_Library_Manager::Create_Tool(const CSG_String &Library, const CSG_String &Name, bool bWithGUI, bool bWithCMD) const
954{
955 SG_Get_Tool_Library_Manager()._Add_Library(Library);
956
957 for(int i=0; i<Get_Count(); i++)
958 {
959 if( Get_Library(i)->Get_Library_Name().Cmp(Library) == 0 )
960 {
961 CSG_Tool *pTool = Get_Library(i)->Create_Tool(Name, bWithGUI, bWithCMD);
962
963 if( pTool )
964 {
965 return( pTool );
966 }
967 }
968 }
969
970 return( NULL );
971}
972
973//---------------------------------------------------------
975{
976 for(int i=0; i<Get_Count(); i++)
977 {
978 if( Get_Library(i)->Delete_Tool(pTool) )
979 {
980 return( true );
981 }
982 }
983
984 return( false );
985}
986
987
989// //
991
992//---------------------------------------------------------
993bool CSG_Tool_Library_Manager::Create_Python_ToolBox(const CSG_String &Destination, bool bClean, bool bName, bool bSingleFile, CSG_Table *pDeprecated_Names) const
994{
995 const char *Header =
996 "#! /usr/bin/env python\n\n"
997 "'''\n"
998 "Python Interface to SAGA Tools Library\n"
999 "----------\n"
1000 "- Category : %s\n"
1001 "- Name : %s\n"
1002 "- ID : %s\n\n"
1003 "Description\n"
1004 "----------\n%s\n"
1005 "'''\n\n"
1006 "from PySAGA.helper import Tool_Wrapper\n\n";
1007
1008 //-----------------------------------------------------
1009 if( pDeprecated_Names && (pDeprecated_Names->Get_Field_Count() != 3 || pDeprecated_Names->Get_Count() < 1) ) // LibraryID, ToolID, Name
1010 {
1011 pDeprecated_Names = NULL;
1012 }
1013
1014 //-----------------------------------------------------
1015 CSG_File Stream, Init;
1016
1017 if( bSingleFile )
1018 {
1019 if( SG_File_Exists(Destination) )
1020 {
1021 SG_File_Delete(Destination);
1022 }
1023
1024 if( !Stream.Open(Destination, SG_FILE_W, false, SG_FILE_ENCODING_UTF8) )
1025 {
1026 SG_UI_Msg_Add_Error(CSG_String::Format("%s: %s", _TL("failed to create destination file"), Destination.c_str()));
1027
1028 return( false );
1029 }
1030
1031 Stream.Write("#! /usr/bin/env python\n\n'''\n");
1032 Stream.Write("Python Interface to SAGA Tools\n");
1033 Stream.Write("----------\n'''\n\n");
1034 Stream.Write("from PySAGA.helper import Tool_Wrapper\n\n");
1035 }
1036 else
1037 {
1038 if( !SG_Dir_Exists(Destination) && !SG_Dir_Create(Destination, true) )
1039 {
1040 SG_UI_Msg_Add_Error(CSG_String::Format("%s: %s", _TL("failed to create destination folder"), Destination.c_str()));
1041
1042 return( false );
1043 }
1044
1045 if( bClean )
1046 {
1047 CSG_Strings Files;
1048
1049 SG_Dir_List_Files(Files, Destination);
1050
1051 for(int i=0; i<Files.Get_Count(); i++)
1052 {
1053 SG_File_Delete(Files[i]);
1054 }
1055 }
1056
1057 if( !Init.Open(SG_File_Make_Path(Destination, SG_T("__init__"), "py"), SG_FILE_W, false, SG_FILE_ENCODING_UTF8) )
1058 {
1059 SG_UI_Msg_Add_Error(CSG_String::Format("%s: %s", _TL("failed to create file"), SG_T("__init__.py")));
1060
1061 return( false );
1062 }
1063 }
1064
1066
1067 //-----------------------------------------------------
1068 // skip tool chains in 1st run...
1069 for(int iLibrary=0; iLibrary<Get_Count() && SG_UI_Process_Set_Progress(iLibrary, Get_Count()); iLibrary++)
1070 {
1071 CSG_Tool_Library *pLibrary = Get_Library(iLibrary);
1072
1073 if( !pLibrary->Get_Category ().Cmp("SAGA Development" ) // generally exclude certain categories/libraries
1074 || !pLibrary->Get_Category ().Cmp("Garden" )
1075 || !pLibrary->Get_Library_Name().Cmp("grid_calculus_bsl")
1076 || !pLibrary->Get_Library_Name().Cmp("pj_geotrans" )
1077 || !pLibrary->Get_Library_Name().Cmp("vis_3d_viewer" )
1078 || pLibrary->Get_Type() == ESG_Library_Type::Chain ) // exclude tool chains in 1st run
1079 {
1080 continue;
1081 }
1082
1083 SG_UI_Process_Set_Text(CSG_String::Format("%s: %s", SG_T("Library"), pLibrary->Get_Library_Name().c_str()));
1084
1085 if( !bSingleFile )
1086 {
1087 if( !Stream.Open(SG_File_Make_Path(Destination, pLibrary->Get_Library_Name(), "py"), SG_FILE_W, false, SG_FILE_ENCODING_UTF8) )
1088 {
1089 continue;
1090 }
1091
1092 Stream.Printf(Header, pLibrary->Get_Category().c_str(), pLibrary->Get_Name().c_str(), pLibrary->Get_Library_Name().c_str(), CSG_Text_Format_Converter::Html_to_SimpleText(pLibrary->Get_Description()).c_str());
1093
1094 Init.Printf("from . import %s\n", pLibrary->Get_Library_Name().c_str());
1095 }
1096
1097 for(int iTool=0; iTool<pLibrary->Get_Count(); iTool++)
1098 {
1099 CSG_Tool *pTool = pLibrary->Create_Tool(pLibrary->Get_Tool(iTool)->Get_ID(), false, false);
1100
1101 if( pTool && !pTool->needs_GUI() && !pTool->is_Interactive() && pTool->Get_Parameters_Count() == 0 )
1102 {
1104
1105 if( bName )
1106 {
1108
1109 for(int i=0; pDeprecated_Names && i<pDeprecated_Names->Get_Count(); i++)
1110 {
1111 CSG_Table_Record &Name = *pDeprecated_Names->Get_Record(i);
1112
1113 if( !pLibrary->Get_Library_Name().Cmp(Name.asString(0)) && !pTool->Get_ID().Cmp(Name.asString(1)) )
1114 {
1116 }
1117 }
1118 }
1119 }
1120
1121 pLibrary->Delete_Tool(pTool);
1122 }
1123 }
1124
1125 //-----------------------------------------------------
1126 // add tool chains in 2nd run...
1127 for(int iLibrary=0; iLibrary<Get_Count() && SG_UI_Process_Set_Progress(iLibrary, Get_Count()); iLibrary++)
1128 {
1129 CSG_Tool_Library *pLibrary = Get_Library(iLibrary);
1130
1131 if( !pLibrary->Get_Category().Cmp("SAGA Development" ) // generally exclude certain categories
1132 || !pLibrary->Get_Category().Cmp("Garden" )
1133 || pLibrary->Get_Type() != ESG_Library_Type::Chain ) // only process tool chains in 2nd run
1134 {
1135 continue;
1136 }
1137
1138 SG_UI_Process_Set_Text(CSG_String::Format("%s: %s", SG_T("Library"), pLibrary->Get_Library_Name().c_str()));
1139
1140 if( !bSingleFile )
1141 {
1142 CSG_String File(SG_File_Make_Path(Destination, pLibrary->Get_Library_Name(), "py"));
1143
1144 if( SG_File_Exists(File) )
1145 {
1146 if( !Stream.Open(File, SG_FILE_RW, false, SG_FILE_ENCODING_UTF8) )
1147 {
1148 continue;
1149 }
1150
1151 Stream.Seek_End();
1152 }
1153 else
1154 {
1155 if( !Stream.Open(File, SG_FILE_W, false, SG_FILE_ENCODING_UTF8) )
1156 {
1157 continue;
1158 }
1159
1160 Stream.Printf(Header, pLibrary->Get_Category().c_str(), pLibrary->Get_Name().c_str(), pLibrary->Get_Library_Name().c_str(), CSG_Text_Format_Converter::Html_to_SimpleText(pLibrary->Get_Description()).c_str());
1161
1162 Init.Printf("from . import %s\n", pLibrary->Get_Library_Name().c_str());
1163 }
1164 }
1165
1166 for(int iTool=0; iTool<pLibrary->Get_Count(); iTool++)
1167 {
1168 CSG_Tool *pTool = pLibrary->Create_Tool(pLibrary->Get_Tool(iTool)->Get_ID(), false, false);
1169
1170 if( pTool && !pTool->needs_GUI() && !pTool->is_Interactive() && pTool->Get_Parameters_Count() == 0 )
1171 {
1173
1174 if( bName )
1175 {
1177
1178 for(int i=0; pDeprecated_Names && i<pDeprecated_Names->Get_Count(); i++)
1179 {
1180 CSG_Table_Record &Name = *pDeprecated_Names->Get_Record(i);
1181
1182 if( !pLibrary->Get_Library_Name().Cmp(Name.asString(0)) && !pTool->Get_ID().Cmp(Name.asString(1)) )
1183 {
1185 }
1186 }
1187 }
1188 }
1189
1190 pLibrary->Delete_Tool(pTool);
1191 }
1192 }
1193
1194 //-----------------------------------------------------
1195 SG_UI_Set_Application_Name(); // reset
1196
1197 return( true );
1198}
1199
1200
1202// //
1203// //
1204// //
1206
1207//---------------------------------------------------------
void SG_UI_Msg_Add_Error(const char *Message)
void SG_UI_Msg_Add(const char *Message, bool bNewLine, TSG_UI_MSG_STYLE Style)
void SG_UI_Process_Set_Text(const CSG_String &Text)
bool SG_UI_Process_Set_Progress(int Position, int Range)
void * SG_UI_Get_Window_Main(void)
int SG_UI_Msg_Lock(bool bOn)
void SG_UI_ProgressAndMsg_Lock(bool bOn)
CSG_String SG_UI_Set_Application_Name(const CSG_String &Name)
Definition api_core.cpp:388
CSG_String SG_UI_Get_Application_Path(bool bPathOnly)
Definition api_core.cpp:356
CSG_String SG_UI_Get_API_Path(void)
Definition api_core.cpp:345
SAGA_API_DLL_EXPORT bool SG_Get_Environment(const CSG_String &Variable, CSG_String *Value=NULL)
SAGA_API_DLL_EXPORT bool SG_File_Exists(const CSG_String &FileName)
@ SG_UI_MSG_STYLE_FAILURE
Definition api_core.h:1627
@ SG_UI_MSG_STYLE_SUCCESS
Definition api_core.h:1626
SAGA_API_DLL_EXPORT bool SG_File_Cmp_Extension(const CSG_String &File, const CSG_String &Extension)
SAGA_API_DLL_EXPORT CSG_String SG_File_Get_Path_Absolute(const CSG_String &full_Path, const CSG_String &CWD="")
signed long long sLong
Definition api_core.h:158
SAGA_API_DLL_EXPORT bool SG_Dir_Create(const CSG_String &Directory, bool bFullPath=false)
Definition api_file.cpp:982
SAGA_API_DLL_EXPORT bool SG_Dir_List_Files(CSG_Strings &List, const CSG_String &Directory, const CSG_String &Extension="", bool bRecursive=false)
#define SG_T(s)
Definition api_core.h:537
SAGA_API_DLL_EXPORT void SG_Free(void *memblock)
SAGA_API_DLL_EXPORT CSG_String SG_File_Get_Path(const CSG_String &full_Path)
SAGA_API_DLL_EXPORT CSG_String SG_File_Make_Path(const CSG_String &Directory, const CSG_String &Name)
SAGA_API_DLL_EXPORT bool SG_File_Delete(const CSG_String &FileName)
SAGA_API_DLL_EXPORT void * SG_Realloc(void *memblock, size_t size)
SAGA_API_DLL_EXPORT CSG_Strings SG_String_Tokenize(const CSG_String &String, const CSG_String &Delimiters=SG_DEFAULT_DELIMITERS, TSG_String_Tokenizer_Mode Mode=SG_TOKEN_DEFAULT)
SAGA_API_DLL_EXPORT bool SG_Dir_Exists(const CSG_String &Directory)
Definition api_file.cpp:976
@ SG_DATATYPE_String
Definition api_core.h:1048
#define _TL(s)
Definition api_core.h:1610
@ SG_FILE_ENCODING_UTF8
Definition api_core.h:552
@ SG_FILE_W
Definition api_core.h:1154
@ SG_FILE_R
Definition api_core.h:1153
@ SG_FILE_RW
Definition api_core.h:1155
virtual bool Open(const SG_Char *FileName, int Mode=SG_FILE_R, bool bBinary=true, int Encoding=SG_FILE_ENCODING_ANSI)
Definition api_file.cpp:113
bool Seek_End(void) const
Definition api_file.cpp:262
size_t Write(void *Buffer, size_t Size, size_t Count=1) const
Definition api_file.cpp:382
size_t Read(void *Buffer, size_t Size, size_t Count=1) const
Definition api_file.cpp:338
int Printf(const char *Format,...)
Definition api_file.cpp:287
static void Initialize(void)
int Cmp(const CSG_String &String) const
static CSG_String Format(const char *Format,...)
int asInt(void) const
const SG_Char * c_str(void) const
bool is_Empty(void) const
int Get_Count(void) const
Definition api_core.h:719
bool Set_Value(int Field, const CSG_String &Value)
const SG_Char * asString(int Field, int Decimals=-99) const
bool Create(void)
Definition table.cpp:153
sLong Get_Count(void) const
Definition table.h:400
virtual CSG_Table_Record * Get_Record(sLong Index) const
Definition table.h:402
int Get_Field_Count(void) const
Definition table.h:361
virtual bool Set_Field_Type(int Field, TSG_Data_Type Type)
Definition table.cpp:610
static CSG_String Html_Absolute_Image_Paths(const CSG_String &Text, const CSG_String &Path, bool bAltAsText=false)
static CSG_String Markdown_to_Html(const CSG_String &Text, bool bSimple=true)
static CSG_String Html_to_SimpleText(const CSG_String &Text)
bool is_Okay(void) const
Definition tool_chain.h:96
bool Create(const CSG_Tool_Chain &Tool, bool bWithGUI, bool bWithCMD)
bool Add_Tool(CSG_Tool_Chain *pTool)
int Get_Count(void) const
int Get_Tool_Count(void) const
virtual ~CSG_Tool_Library_Manager(void)
bool Create_Python_ToolBox(const CSG_String &Destination, bool bClean=true, bool bName=true, bool bSingleFile=false, CSG_Table *pDeprecated_Names=NULL) const
CSG_Tool_Library * Add_Library(const CSG_String &File)
int Add_Directory(const CSG_String &Directory, bool bOnlySubDirectories=false)
CSG_Tool_Library * Get_Library(int i) const
bool Delete_Tool(CSG_Tool *pTool) const
CSG_Tool * Get_Tool(const CSG_String &Library, int Index) const
CSG_Tool * Create_Tool(const CSG_String &Library, int Index, bool bWithGUI=false, bool bWithCMD=true) const
bool is_Loaded(CSG_Tool_Library *pLibrary) const
bool Add_Default_Libraries(bool bVerbose=false)
bool Load_Description(void)
CSG_String m_File_Name
virtual CSG_Tool * Create_Tool(int Index, bool bWithGUI=false, bool bWithCMD=true)
const CSG_String & Get_Menu(void) const
void Add_Reference(const CSG_String &Authors, const CSG_String &Date, const CSG_String &Title, const CSG_String &Source, const CSG_String &Link="", const CSG_String &Link_Text="")
const CSG_String & Get_Description(void) const
bool Del_References(void)
virtual CSG_Tool * Get_Tool(int Index, TSG_Tool_Type Type=TOOL_TYPE_Base) const
virtual bool Delete_Tools(void)
const CSG_String & Get_Library_Name(void) const
virtual bool Delete_Tool(CSG_Tool *pTool)
virtual ~CSG_Tool_Library(void)
const CSG_String & Get_Name(void) const
CSG_Strings Get_References(bool bHTML=true) const
virtual const CSG_String & Get_Info(int Type) const
bool is_Valid(void) const
const CSG_String & Get_Category(void) const
virtual ESG_Library_Type Get_Type(void) const
virtual int Get_Count(void) const
CSG_String m_Library_Name
const CSG_String & Get_Library(void) const
Definition tool.cpp:129
int Get_Parameters_Count(void) const
Definition tool.h:177
virtual bool is_Interactive(void) const
Definition tool.h:233
CSG_String Get_Script(Script_Format Format, bool bHeader=true, int Arguments=0, bool bWrapArgs=true)
Definition tool.cpp:1789
const CSG_String & Get_Name(void) const
Definition tool.cpp:146
virtual bool needs_GUI(void) const
Definition tool.h:228
virtual TSG_Tool_Type Get_Type(void) const
Definition tool.h:148
const CSG_String & Get_ID(void) const
Definition tool.h:150
static const CSG_String & Get_Description_Source(void)
Definition tool.cpp:453
void Set_Name(const CSG_String &String)
Definition tool.cpp:141
#define SYMBOL_TLB_Get_Interface
Definition tool.h:712
CSG_Tool_Library_Interface *(* TSG_PFNC_TLB_Get_Interface)(void)
Definition tool.h:713
@ TLB_INFO_Library
Definition tool.h:665
@ TLB_INFO_Description
Definition tool.h:658
@ TLB_INFO_File
Definition tool.h:664
bool(* TSG_PFNC_TLB_Finalize)(void)
Definition tool.h:710
TSG_Tool_Type
Definition tool.h:101
@ TOOL_TYPE_Base
Definition tool.h:102
@ TOOL_TYPE_Chain
Definition tool.h:106
bool(* TSG_PFNC_TLB_Initialize)(const SG_Char *)
Definition tool.h:707
#define SYMBOL_TLB_Initialize
Definition tool.h:706
#define SYMBOL_TLB_Finalize
Definition tool.h:709
CSG_Tool_Library_Manager & SG_Get_Tool_Library_Manager(void)
CSG_Tool_Library_Manager g_Tool_Library_Manager
SAGA_API_DLL_EXPORT CSG_Tool_Library_Manager & SG_Get_Tool_Library_Manager(void)
ESG_Library_Type