From 8822f9075c66dcf742b9edae47271bb46af6a9b7 Mon Sep 17 00:00:00 2001 From: guigues Date: Tue, 27 Jan 2009 14:22:44 +0000 Subject: [PATCH] are now generated in user's .bbtk dir * bug fixes in doc/boxes lists regeneration * bbStudio : -splash screen -doc automatically generated on first time --- .../bbRegenerateBoxesLists.cpp | 2 +- .../bbRegeneratePackageDoc.cpp | 2 +- kernel/data/icons/CMakeLists.txt | 5 + kernel/data/icons/bbStudioSplashScreen.png | Bin 0 -> 58488 bytes kernel/src/bbtkConfigurationFile.cxx | 306 ++++--------- kernel/src/bbtkConfigurationFile.h | 51 ++- kernel/src/bbtkExecuter.cxx | 7 +- kernel/src/bbtkInterpreter.cxx | 52 ++- kernel/src/bbtkUtilities.cxx | 419 +++++++++++++----- kernel/src/bbtkUtilities.h | 70 +-- kernel/src/bbtkWx.cxx | 19 +- kernel/src/bbtkWxGUIScriptingInterface.cxx | 102 ++++- 12 files changed, 604 insertions(+), 431 deletions(-) create mode 100644 kernel/data/icons/bbStudioSplashScreen.png diff --git a/kernel/appli/bbRegenerateBoxesLists/bbRegenerateBoxesLists.cpp b/kernel/appli/bbRegenerateBoxesLists/bbRegenerateBoxesLists.cpp index b981604..e9b2535 100644 --- a/kernel/appli/bbRegenerateBoxesLists/bbRegenerateBoxesLists.cpp +++ b/kernel/appli/bbRegenerateBoxesLists/bbRegenerateBoxesLists.cpp @@ -30,7 +30,7 @@ int main(int argc, char **argv) doc_path += "bbdoc"; doc_path += bbtk::ConfigurationFile::GetInstance().Get_file_separator(); - I->InterpretLine( "exec freeze"); + I->InterpretLine( "exec freeze_no_error"); I->InterpretLine( "include *"); I->GetExecuter()->GetFactory()->CreateHtmlIndex(bbtk::Factory::Initials,doc_path + "index-alpha.html"); I->GetExecuter()->GetFactory()->CreateHtmlIndex(bbtk::Factory::Packages,doc_path + "index-package.html"); diff --git a/kernel/appli/bbRegeneratePackageDoc/bbRegeneratePackageDoc.cpp b/kernel/appli/bbRegeneratePackageDoc/bbRegeneratePackageDoc.cpp index 9faa7d5..1f8249a 100644 --- a/kernel/appli/bbRegeneratePackageDoc/bbRegeneratePackageDoc.cpp +++ b/kernel/appli/bbRegeneratePackageDoc/bbRegeneratePackageDoc.cpp @@ -73,7 +73,7 @@ int main(int argc, char **argv) bbtk::Interpreter::Pointer I = bbtk::Interpreter::New(); I->SetCommandLine(true); I->SetThrow(false); - I->InterpretLine( "exec freeze"); + I->InterpretLine( "exec freeze_no_error"); if (pack != "-a") { I->InterpretLine( "include "+pack); diff --git a/kernel/data/icons/CMakeLists.txt b/kernel/data/icons/CMakeLists.txt index 26a4309..cc8438b 100644 --- a/kernel/data/icons/CMakeLists.txt +++ b/kernel/data/icons/CMakeLists.txt @@ -5,3 +5,8 @@ INSTALL( FILES ${IMAGES} DESTINATION ${BBTK_DATA_INSTALL_PATH}/kernel/icons ) + +CONFIGURE_FILE( ${CMAKE_CURRENT_SOURCE_DIR}/bbStudioSplashScreen.png + ${BBTK_DATA_BUILD_PATH}/kernel/icons/bbStudioSplashScreen.png + COPYONLY +) diff --git a/kernel/data/icons/bbStudioSplashScreen.png b/kernel/data/icons/bbStudioSplashScreen.png new file mode 100644 index 0000000000000000000000000000000000000000..bddb6cb5890c5211897536dd4ebc4580b946caef GIT binary patch literal 58488 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 z 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 ZB-!H+lK6f2`1trtZd=?cz2WlezW|8zS8o6S literal 0 HcmV?d00001 diff --git a/kernel/src/bbtkConfigurationFile.cxx b/kernel/src/bbtkConfigurationFile.cxx index 4d59d57..f7b9002 100644 --- a/kernel/src/bbtkConfigurationFile.cxx +++ b/kernel/src/bbtkConfigurationFile.cxx @@ -2,8 +2,8 @@ Program: bbtk Module: $RCSfile: bbtkConfigurationFile.cxx,v $ Language: C++ - Date: $Date: 2008/12/12 10:20:48 $ - Version: $Revision: 1.25 $ + Date: $Date: 2009/01/27 14:22:56 $ + Version: $Revision: 1.26 $ =========================================================================*/ /* --------------------------------------------------------------------- @@ -65,21 +65,29 @@ namespace bbtk ConfigurationFile::ConfigurationFile() { - mFile_separator = VALID_FILE_SEPARATOR; + mFile_separator = VALID_FILE_SEPARATOR; // ==> Set system paths - mBin_path = GetExecutablePath(); - + mBin_path = Utilities::GetExecutablePath(); + #ifdef MACOSX mInstall_path = mBin_path + "/../../../.."; #else mInstall_path = mBin_path + "/.."; #endif - + + // The relative path to the doc folder (=BBTK_DOC_REL_PATH) - mDoc_rel_path = BBTK_STRINGIFY_SYMBOL(BBTK_DOC_REL_PATH); + // mDoc_rel_path = BBTK_STRINGIFY_SYMBOL(BBTK_DOC_REL_PATH); // The path to the doc folder (=mInstall_path+"/"+mDoc_rel_path) - mDoc_path = mInstall_path + "/" + mDoc_rel_path; + // mDoc_path = mInstall_path + "/" + mDoc_rel_path; + // Have to create bbtk user's dirs if needed + + // LG 27/01/09 : doc is now user dependent + // and located in user's .bbtk dir /doc + // All dirs under .bbtk user's dir are set and created by: + InitializeDotBbtkStructure(); + // The relative path to the doc folder (=BBTK_BBS_REL_PATH) mBbs_rel_path = BBTK_STRINGIFY_SYMBOL(BBTK_BBS_REL_PATH); // The path to the bbs folder (=mInstall_path+"/"+mBbs_rel_path) @@ -93,12 +101,6 @@ namespace bbtk Utilities::replace( mInstall_path, INVALID_FILE_SEPARATOR, VALID_FILE_SEPARATOR); - Utilities::replace( mDoc_rel_path, - INVALID_FILE_SEPARATOR, - VALID_FILE_SEPARATOR); - Utilities::replace( mDoc_path, - INVALID_FILE_SEPARATOR, - VALID_FILE_SEPARATOR); Utilities::replace( mBbs_path, INVALID_FILE_SEPARATOR, VALID_FILE_SEPARATOR); @@ -211,8 +213,75 @@ namespace bbtk } //========================================================================= + //========================================================================= + void ConfigurationFile::InitializeDotBbtkStructure() + { + mDot_bbtk_path = Utilities::GetUserSettingsDir(); + mDot_bbtk_is_new = false; + if (!Utilities::FileExists(mDot_bbtk_path)) mDot_bbtk_is_new = true; + Utilities::CreateDirectoryIfNeeded(mDot_bbtk_path); + + mDoc_path = Utilities::MakeUserSettingsFullFileName("doc"); + Utilities::CreateDirectoryIfNeeded(mDoc_path); + + std::string bbdoc_path = + Utilities::MakeUserSettingsFullFileName("doc/bbdoc"); + Utilities::CreateDirectoryIfNeeded(bbdoc_path); + + // Create help_contents.html if does not exist + std::string filename = Utilities::MakeUserSettingsFullFileName("doc/help_contents.html"); + if (!Utilities::FileExists(filename)) + { + bbtkDebugMessage("Config",1, + "* Creating [" << filename << "]" << std::endl); + // The path to the doc folder (=mInstall_path+"/"+mDoc_rel_path) + std::string doc_path = mInstall_path + "/" + + BBTK_STRINGIFY_SYMBOL(BBTK_DOC_REL_PATH) + "/"; + Utilities::MakeValidFileName(doc_path); + std::ofstream f; + f.open(filename.c_str(), std::ios::out ); + f << "" + << "Help Contents - bbtk " + << GetVersion() << "" + << "

Help Contents

" + << "
Demos
" + << "Examples" + << "

Guides

" + << "User's Guide
" + << "Package Developer's Guide
" + << "bbtk library doxygen doc
" + << "

Boxes

" + << "" + << "Alphabetical list
" + << "" + << "List by package
" + << "" + << "List by category
" + << "" + << "List of adaptors
" + << "" + << ""; + } + mTemp_path = Utilities::MakeUserSettingsFullFileName("tmp"); + Utilities::CreateDirectoryIfNeeded(mTemp_path); + + } + //========================================================================= //========================================================================= void ConfigurationFile::CreateConfigXML( char *rootDirectory ) @@ -226,7 +295,6 @@ namespace bbtk fprintf(fp, "\n"); fprintf(fp, " \n"); fprintf(fp, " \n"); - fprintf(fp, " $ \n"); fprintf(fp, "\n"); fclose(fp); } @@ -234,192 +302,6 @@ namespace bbtk - //========================================================================= - // From http://www.fltk.org/newsgroups.php?gfltk.general+v:22083 - // - int get_app_path (char *pname, size_t pathsize) - { -#ifdef LINUX - /* Oddly, the readlink(2) man page says no NULL is appended. */ - /* So you have to do it yourself, based on the return value: */ - pathsize --; /* Preserve a space to add the trailing NULL */ - long result = readlink("/proc/self/exe", pname, pathsize); - if (result > 0) - { - pname[result] = 0; /* add the #@!%ing NULL */ - - if ((access(pname, 0) == 0)) - return 0; /* file exists, return OK */ - /*else name doesn't seem to exist, return FAIL (falls - through) */ - } -#endif /* LINUX */ - -#ifdef WIN32 - long result = GetModuleFileName(NULL, pname, pathsize); - if (result > 0) - { - /* fix up the dir slashes... */ - int len = strlen(pname); - int idx; - for (idx = 0; idx < len; idx++) - { - if (pname[idx] == '\\') pname[idx] = '/'; - } - - for (idx = len-1; idx >=0 ; idx--) - { - if (pname[idx] == '/') - { - pname[idx+1] = '\0'; - idx = -1; - } - } - - if ((access(pname, 0) == 0)) - return 0; /* file exists, return OK */ - /*else name doesn't seem to exist, return FAIL (falls - through) */ - } -#endif /* WIN32 */ - -#ifdef SOLARIS - char *p = getexecname(); - if (p) - { - /* According to the Sun manpages, getexecname will - "normally" return an */ - /* absolute path - BUT might not... AND that IF it is not, - pre-pending */ - /* getcwd() will "usually" be the correct thing... Urgh! - */ - - /* check pathname is absolute (begins with a / ???) */ - if (p[0] == '/') /* assume this means we have an - absolute path */ - { - strncpy(pname, p, pathsize); - if ((access(pname, 0) == 0)) - return 0; /* file exists, return OK */ - } - else /* if not, prepend getcwd() then check if file - exists */ - { - getcwd(pname, pathsize); - long result = strlen(pname); - strncat(pname, "/", (pathsize - result)); - result ++; - strncat(pname, p, (pathsize - result)); - - if ((access(pname, 0) == 0)) - return 0; /* file exists, return OK */ - /*else name doesn't seem to exist, return FAIL - (falls through) */ - } - } -#endif /* SOLARIS */ - -#ifdef MACOSX /* assume this is OSX */ - /* - from http://www.hmug.org/man/3/NSModule.html - - extern int _NSGetExecutablePath(char *buf, unsigned long - *bufsize); - - _NSGetExecutablePath copies the path of the executable - into the buffer and returns 0 if the path was successfully - copied in the provided buffer. If the buffer is not large - enough, -1 is returned and the expected buffer size is - copied in *bufsize. Note that _NSGetExecutablePath will - return "a path" to the executable not a "real path" to the - executable. That is the path may be a symbolic link and - not the real file. And with deep directories the total - bufsize needed could be more than MAXPATHLEN. - */ - int status = -1; - char *given_path = (char*)malloc(MAXPATHLEN * 2); - if (!given_path) return status; - - uint32_t npathsize = MAXPATHLEN * 2; - long result = _NSGetExecutablePath(given_path, &npathsize); - if (result == 0) - { /* OK, we got something - now try and resolve the real path... - */ - if (realpath(given_path, pname) != NULL) - { - if ((access(pname, 0) == 0)) - status = 0; /* file exists, return OK */ - } - } - free (given_path); - return status; -#endif /* MACOSX */ - - return -1; /* Path Lookup Failed */ - } - - - - //========================================================================= - std::string ConfigurationFile::GetExecutablePath() - { - char name[PATH_MAX]; - int err = get_app_path(name, PATH_MAX); - if (err) - { - bbtkError("Could not determine current executable path ?"); - } - - // remove the exe name - char *slash; - slash = strrchr(name, VALID_FILE_SEPARATOR_CHAR); - if (slash) - { - *slash = 0; - } - return name; - } - -/* - /// \todo : Think to delete it! - char *buf = (char *)malloc(512); - if (!buf) - { - bbtkError("Could not allocate 512 bytes !"); - } - char *slash; - -#if defined(WIN32) - GetModuleFileName(NULL, buf, 511); - slash = strrchr(buf, '\\'); - if (slash) - { - *slash = 0; - } -#endif - - -#if defined(__GNUC__) - int res; - res = readlink("/proc/self/exe", buf, 512); - if (res == -1) - { - free(buf); - - } - buf[res] = 0; - slash = strrchr(buf, '/'); - if (slash) - { - *slash = 0; - } -#endif - std::string ret(buf); - free(buf); - return ret; - } - //========================================================================= -*/ //========================================================================= void ConfigurationFile::InstallPath () @@ -458,10 +340,6 @@ namespace bbtk char configPath[200]; sprintf(configPath, "%s/bbtk_config.xml",rootDirectory); - // makeDir - char makeDir[250]; - sprintf( makeDir, "mkdir \"%s\" ", rootDirectory); - // configXmlTmp char configXmlTmp[250]; sprintf(configXmlTmp, "%s/bbtk_config.xml.tmp", bbtk_path); @@ -471,23 +349,12 @@ namespace bbtk if (!Utilities::FileExists(configXmlTmp)) // bbtk_config.xml.tmp not found (not installed) { - if (!Utilities::FileExists(rootDirectory)) // .bbtk not found - { - system(makeDir); // create .bbtk - } - // if "bbtk_path/bbtk_config.xml.tmp" doesn't exist, hard-create a minimum version in .bbtk CreateConfigXML( rootDirectory );// create .bbtk } else { sprintf(copyFile,"cp %s %s/bbtk_config.xml ",configXmlTmp,rootDirectory ); - if (!Utilities::FileExists(rootDirectory)) - { - //std::cout << "makeDir[" << makeDir << "]" << std::endl; - system(makeDir); - } - if (!Utilities::FileExists(configPath)) { system(copyFile); @@ -527,11 +394,6 @@ namespace bbtk if (!Utilities::FileExists(configXmlTmp)) // bbtk_config.xml.tmp not found { - if (!Utilities::FileExists(rootDirectory)) // .bbtk not found - { - system(makeDir); // create .bbtk - } - // if "bbtk_path/bbtk_config.xml.tmp" doesn't exist, hard-create a minimum version in .bbtk CreateConfigXML( rootDirectory );// create .bbtk return; @@ -634,6 +496,7 @@ namespace bbtk } // default_temp_dir + /* if( BB.nChildNode((XMLCSTR)"default_temp_dir") ) GetTextOrClear(BB.getChildNode((XMLCSTR)"default_temp_dir"),mDefault_temp_dir); @@ -642,6 +505,7 @@ namespace bbtk size_t pos = mConfig_xml_full_path.find("bbtk_config.xml"); mDefault_temp_dir = mConfig_xml_full_path.substr (0,pos); } + */ GetHelp(2); } diff --git a/kernel/src/bbtkConfigurationFile.h b/kernel/src/bbtkConfigurationFile.h index aa5daf3..e6dd488 100644 --- a/kernel/src/bbtkConfigurationFile.h +++ b/kernel/src/bbtkConfigurationFile.h @@ -2,8 +2,8 @@ Program: bbtk Module: $RCSfile: bbtkConfigurationFile.h,v $ Language: C++ - Date: $Date: 2008/10/17 08:18:13 $ - Version: $Revision: 1.10 $ + Date: $Date: 2009/01/27 14:22:56 $ + Version: $Revision: 1.11 $ =========================================================================*/ /* --------------------------------------------------------------------- @@ -82,31 +82,28 @@ namespace bbtk ~ConfigurationFile(); - private: - ConfigurationFile(); - void InstallPath (); - - public: void GetHelp(int level) const; + /// Returns true iff the directory .bbtk has been created on construction + inline bool DotBbtkIsNew() { return mDot_bbtk_is_new; } + inline const std::string& Get_description() const { return mDescription;} - // inline const std::string& Get_url() const - // { return mUrl;} + inline const std::string& Get_data_path() const { return mData_path;} inline const std::string& Get_file_separator() const { return mFile_separator;} + inline const std::string& Get_dot_bbtk_path() const + { return mDot_bbtk_path;} inline const std::string& Get_bin_path() const { return mBin_path;} inline const std::string& Get_install_path() const { return mInstall_path;} inline const std::string& Get_doc_path() const { return mDoc_path;} - inline const std::string& Get_rsc_path() const - { return mRsc_path;} - + inline const std::string& Get_root_bbs_path() const { return mBbs_path;} inline const std::vector& Get_bbs_paths() const @@ -116,15 +113,16 @@ namespace bbtk inline const std::string& Get_config_xml_full_path() const { return mConfig_xml_full_path;} inline const std::string& Get_default_temp_dir() const - { return mDefault_temp_dir;} + { return mTemp_path;} bool AddPackagePathsAndWrite( const std::string& package_root_path ); private: + ConfigurationFile(); + void InstallPath (); void Read(const std::string& fileName); - std::string GetExecutablePath(); - void CreateConfigXML( char *rootDirectory ); - + void CreateConfigXML( char *rootDirectory ); + void InitializeDotBbtkStructure(); // Attributes : private : std::string mDescription; @@ -134,20 +132,18 @@ namespace bbtk /// Set automatically : /// The path to the executable (usually bbi) std::string mBin_path; + /// The path to the .bbtk user's dir (e.g. /home/username/.bbtk) + std::string mDot_bbtk_path; /// The path to the install prefix (=mBinPath+"/..") std::string mInstall_path; - /// The relative path to the doc folder (=BBTK_DOC_REL_PATH) - std::string mDoc_rel_path; - /// The path to the doc folder (=mInstall_path+"/"+mDoc_rel_path) + /// The path to the doc folder (=mDot_bbtk_path+"/doc") std::string mDoc_path; + /// Temp directory for generated data (=mDot_bbtk_path+"/tmp") + std::string mTemp_path; /// The relative path to the doc folder (=BBTK_BBS_REL_PATH) std::string mBbs_rel_path; /// The path to the bbs folder (=mInstall_path+"/"+mBbs_rel_path) std::string mBbs_path; - /// The relative path to the rsc folder (=BBTK_RSC_REL_PATH) - std::string mRsc_rel_path; - /// The path to the rsc folder (=mInstall_path+"/"+mRsc_rel_path) - std::string mRsc_path; /// The path to the bbtk data folder /// Initialized to mInstall_path+"/"+BBTK_DATA_REL_PATH /// But can be overriden by value read from bbtk_config.xml @@ -165,9 +161,12 @@ namespace bbtk std::vector mPackage_paths; /// If Packages link against extern dlls std::vector mExt_dll_paths; - /// Temp directory for generated data - std::string mDefault_temp_dir; - }; + + + /// Set to true by InitializeDotBbtkStructure() if .bbtk has been newly + /// created + bool mDot_bbtk_is_new; + }; }// namespace bbtk diff --git a/kernel/src/bbtkExecuter.cxx b/kernel/src/bbtkExecuter.cxx index 45d6473..84273c0 100644 --- a/kernel/src/bbtkExecuter.cxx +++ b/kernel/src/bbtkExecuter.cxx @@ -2,8 +2,8 @@ Program: bbtk Module: $RCSfile: bbtkExecuter.cxx,v $ Language: C++ - Date: $Date: 2009/01/13 08:45:27 $ - Version: $Revision: 1.26 $ + Date: $Date: 2009/01/27 14:22:56 $ + Version: $Revision: 1.27 $ =========================================================================*/ /* --------------------------------------------------------------------- @@ -64,7 +64,8 @@ namespace bbtk mRootPackage(), mRootCBB(), mNoExecMode(false), - mDialogMode(NoDialog) + mDialogMode(NoDialog), + mNoErrorMode(false) { bbtkDebugMessageInc("Kernel",9,"Executer::Executer()" <GetNoErrorMode()) + { + bbtkWarning("ERROR :"<GetNoErrorMode()) + { + std::string file("?"); + int line = 0; + if (mFileName.size()) { + file = mFileName.back(); + line = mLine.back(); + } + bbtkWarning("ERROR '"<GetNoErrorMode()) + { + std::string file("?"); + int line = 0; + if (mFileName.size()) { + file = mFileName.back(); + line = mLine.back(); + } + bbtkWarning("ERROR '"<GetNoErrorMode()) + { + std::string file("?"); + int line = 0; + if (mFileName.size()) { + file = mFileName.back(); + line = mLine.back(); + } + bbtkWarning("UNDEFINED ERROR " + <<"("<SetNoExecMode(true); mThrow = false; } - else if (words[1]=="freeze_no_error ") + else if (words[1]=="freeze_no_error") { mVirtualExecuter->SetNoExecMode(true); mVirtualExecuter->SetNoErrorMode(true); diff --git a/kernel/src/bbtkUtilities.cxx b/kernel/src/bbtkUtilities.cxx index 778b45e..21fa947 100644 --- a/kernel/src/bbtkUtilities.cxx +++ b/kernel/src/bbtkUtilities.cxx @@ -2,8 +2,8 @@ Program: bbtk Module: $RCSfile: bbtkUtilities.cxx,v $ Language: C++ - Date: $Date: 2008/12/12 10:20:48 $ - Version: $Revision: 1.10 $ + Date: $Date: 2009/01/27 14:22:57 $ + Version: $Revision: 1.11 $ =========================================================================*/ /* --------------------------------------------------------------------- @@ -300,6 +300,22 @@ namespace bbtk } return libname; } + // ======================================================================= + + // ======================================================================= + /// Returns the user settings dir, e.g. /home/username/.bbtk + std::string Utilities::GetUserSettingsDir() + { +#if defined(__GNUC__) + std::string str_home(getenv("HOME")); +#elif defined(_WIN32) + std::string str_home(getenv("USERPROFILE")); +#endif + std::string fullname = str_home + "/.bbtk"; + MakeValidFileName(fullname); + return fullname; + } + // ======================================================================= /// Builds the complete path to the file 'name' located @@ -312,116 +328,128 @@ namespace bbtk std::string str_home(getenv("USERPROFILE")); #endif std::string fullname = str_home + "/.bbtk/" + name; - Utilities::replace( fullname, - INVALID_FILE_SEPARATOR , - VALID_FILE_SEPARATOR); + MakeValidFileName(fullname); return fullname; } + // ======================================================================= + // ======================================================================= + void Utilities::CreateDirectoryIfNeeded( std::string const &dirName) + { + if (FileExists(dirName)) return; + std::string cmd("mkdir \""); + cmd += dirName; + cmd += "\""; + system(cmd.c_str()); + } + // ======================================================================= + + + //======================================================================== + bool Utilities::IsAtRoot(std::string cwd) + { + if ( cwd == "/" // hope it gets / (for Linux) + || (cwd.size() <= 3 && cwd[1] == ':') ) // hope it gets C: D: (for Windows) + return (true); + else + return(false); + } + // ====================================================================== - //======================================================================== - - bool Utilities::IsAtRoot(std::string cwd) - { - if ( cwd == "/" // hope it gets / (for Linux) - || (cwd.size() <= 3 && cwd[1] == ':') ) // hope it gets C: D: (for Windows) - return (true); - else - return(false); - } - - // ====================================================================== + // ====================================================================== + bool Utilities::IsDirectory(std::string const &dirName) + { + struct stat fs; - bool Utilities::IsDirectory(std::string const &dirName) - { - struct stat fs; - - if ( stat(dirName.c_str(), &fs) == 0 ) - { + if ( stat(dirName.c_str(), &fs) == 0 ) + { #if _WIN32 - return ((fs.st_mode & _S_IFDIR) != 0); + return ((fs.st_mode & _S_IFDIR) != 0); #else - return S_ISDIR(fs.st_mode); + return S_ISDIR(fs.st_mode); #endif - } - else - { - return false; - } - } - - // =================================================================================== - - void Utilities::SplitAroundFirstDot( const std::string& in, - std::string& left, - std::string& right) - { - std::string delimiter = "."; - std::string::size_type pos = in.find_first_of(delimiter); - if (std::string::npos != pos) - { - left = in.substr(0,pos); - right = in.substr(pos+1,in.size()); - - } - else - { - left =""; - right = ""; - bbtkGlobalError("Token '"<& tokens) - { - // Skip delimiters at beginning. - std::string::size_type lastPos = str.find_first_not_of(delimiters, 0); - // Find first delimiter. - std::string::size_type pos = str.find_first_of(delimiters, lastPos); - - while (std::string::npos != pos || std::string::npos != lastPos) - { - // Found a token, add it to the vector. - tokens.push_back(str.substr(lastPos, pos - lastPos)); - // Skip delimiters. Note the "not_of" - lastPos = str.find_first_not_of(delimiters, pos); - // Find next delimiter - pos = str.find_first_of(delimiters, lastPos); - } - - } - //======================================================================= - + } + else + { + return false; + } + } + // ======================================================================= - // =================================================================================== + // ======================================================================= + void Utilities::SplitAroundFirstDot( const std::string& in, + std::string& left, + std::string& right) + { + std::string delimiter = "."; + std::string::size_type pos = in.find_first_of(delimiter); + if (std::string::npos != pos) + { + left = in.substr(0,pos); + right = in.substr(pos+1,in.size()); + + } + else + { + left =""; + right = ""; + bbtkGlobalError("Token '"<& tokens) + { + // Skip delimiters at beginning. + std::string::size_type lastPos = str.find_first_not_of(delimiters, 0); + // Find first delimiter. + std::string::size_type pos = str.find_first_of(delimiters, lastPos); - std::string Utilities::get_file_name(const std::string& s) - { - std::string::size_type slash_position = s.find_last_of("/\\"); - if (slash_position != std::string::npos) - { - return s.substr(slash_position+1,std::string::npos); - } - else - { - return s; - } - } + while (std::string::npos != pos || std::string::npos != lastPos) + { + // Found a token, add it to the vector. + tokens.push_back(str.substr(lastPos, pos - lastPos)); + // Skip delimiters. Note the "not_of" + lastPos = str.find_first_not_of(delimiters, pos); + // Find next delimiter + pos = str.find_first_of(delimiters, lastPos); + } - // =================================================================================== - /** - * \brief Explore a directory with possibility of recursion - * return number of files read - * @param dirpath directory to explore - * @param recursive whether we want recursion or not - */ - int Utilities::Explore(std::string const &dirpath, bool recursive, std::vector &Filenames) - { - int numberOfFiles = 0; - std::string fileName; + } + //======================================================================= + + + // ====================================================================== + std::string Utilities::get_file_name(const std::string& s) + { + std::string::size_type slash_position = s.find_last_of("/\\"); + if (slash_position != std::string::npos) + { + return s.substr(slash_position+1,std::string::npos); + } + else + { + return s; + } + } + //======================================================================= + + + // ======================================================================== + /** + * \brief Explore a directory with possibility of recursion + * return number of files read + * @param dirpath directory to explore + * @param recursive whether we want recursion or not + */ + int Utilities::Explore(std::string const &dirpath, bool recursive, std::vector &Filenames) + { + int numberOfFiles = 0; + std::string fileName; std::string dirName = dirpath; @@ -518,7 +546,8 @@ namespace bbtk return numberOfFiles; } - + //======================================================================= + //======================================================================= // Replaces substrings "\\n" by a real carriage return "\n" @@ -537,30 +566,180 @@ namespace bbtk //======================================================================= + //======================================================================= -bool Utilities::loosematch(std::string stdLine,std::string stdOptions) -{ - bool result=false; - std::vector tokens; - SplitString ( stdOptions,"|", tokens); - int i,size=tokens.size(); - for (i=0; i tokens; + SplitString ( stdOptions,"|", tokens); + int i,size=tokens.size(); + for (i=0; i 0) + { + pname[result] = 0; /* add the #@!%ing NULL */ + + if ((access(pname, 0) == 0)) + return 0; /* file exists, return OK */ + /*else name doesn't seem to exist, return FAIL (falls + through) */ + } +#endif /* LINUX */ + +#ifdef WIN32 + long result = GetModuleFileName(NULL, pname, pathsize); + if (result > 0) + { + /* fix up the dir slashes... */ + int len = strlen(pname); + int idx; + for (idx = 0; idx < len; idx++) + { + if (pname[idx] == '\\') pname[idx] = '/'; } - return result; -} + + for (idx = len-1; idx >=0 ; idx--) + { + if (pname[idx] == '/') + { + pname[idx+1] = '\0'; + idx = -1; + } + } + + if ((access(pname, 0) == 0)) + return 0; /* file exists, return OK */ + /*else name doesn't seem to exist, return FAIL (falls + through) */ + } +#endif /* WIN32 */ + +#ifdef SOLARIS + char *p = getexecname(); + if (p) + { + /* According to the Sun manpages, getexecname will + "normally" return an */ + /* absolute path - BUT might not... AND that IF it is not, + pre-pending */ + /* getcwd() will "usually" be the correct thing... Urgh! + */ + + /* check pathname is absolute (begins with a / ???) */ + if (p[0] == '/') /* assume this means we have an + absolute path */ + { + strncpy(pname, p, pathsize); + if ((access(pname, 0) == 0)) + return 0; /* file exists, return OK */ + } + else /* if not, prepend getcwd() then check if file + exists */ + { + getcwd(pname, pathsize); + long result = strlen(pname); + strncat(pname, "/", (pathsize - result)); + result ++; + strncat(pname, p, (pathsize - result)); + + if ((access(pname, 0) == 0)) + return 0; /* file exists, return OK */ + /*else name doesn't seem to exist, return FAIL + (falls through) */ + } + } +#endif /* SOLARIS */ + +#ifdef MACOSX /* assume this is OSX */ + /* + from http://www.hmug.org/man/3/NSModule.html + + extern int _NSGetExecutablePath(char *buf, unsigned long + *bufsize); + + _NSGetExecutablePath copies the path of the executable + into the buffer and returns 0 if the path was successfully + copied in the provided buffer. If the buffer is not large + enough, -1 is returned and the expected buffer size is + copied in *bufsize. Note that _NSGetExecutablePath will + return "a path" to the executable not a "real path" to the + executable. That is the path may be a symbolic link and + not the real file. And with deep directories the total + bufsize needed could be more than MAXPATHLEN. + */ + int status = -1; + char *given_path = (char*)malloc(MAXPATHLEN * 2); + if (!given_path) return status; + + uint32_t npathsize = MAXPATHLEN * 2; + long result = _NSGetExecutablePath(given_path, &npathsize); + if (result == 0) + { /* OK, we got something - now try and resolve the real path... + */ + if (realpath(given_path, pname) != NULL) + { + if ((access(pname, 0) == 0)) + status = 0; /* file exists, return OK */ + } + } + free (given_path); + return status; +#endif /* MACOSX */ + + return -1; /* Path Lookup Failed */ + } + //========================================================================= + + + + //========================================================================= + std::string Utilities::GetExecutablePath() + { + char name[PATH_MAX]; + int err = get_app_path(name, PATH_MAX); + if (err) + { + bbtkGlobalError("Could not determine current executable path ?"); + } + + // remove the exe name + char *slash; + slash = strrchr(name, VALID_FILE_SEPARATOR_CHAR); + if (slash) + { + *slash = 0; + } + return name; + } + //========================================================================= diff --git a/kernel/src/bbtkUtilities.h b/kernel/src/bbtkUtilities.h index 34d17eb..6d0c2cf 100644 --- a/kernel/src/bbtkUtilities.h +++ b/kernel/src/bbtkUtilities.h @@ -2,8 +2,8 @@ Program: bbtk Module: $RCSfile: bbtkUtilities.h,v $ Language: C++ - Date: $Date: 2008/10/22 09:16:16 $ - Version: $Revision: 1.18 $ + Date: $Date: 2009/01/27 14:22:57 $ + Version: $Revision: 1.19 $ =========================================================================*/ /* --------------------------------------------------------------------- @@ -72,61 +72,77 @@ namespace bbtk /// Holds various usefull methods struct BBTK_EXPORT Utilities { - + // ====================================================================== + static std::string GetExecutablePath(); + // ====================================================================== // See : http://www.techbytes.ca/techbyte103.html for more O.S. static bool FileExists(std::string strFilename); // ===================================================================== - static std::string ExtractPackageName(const std::string &name, std::string& path); - + //===================================================================== static std::string ExtractScriptName(const std::string &name, std::string& path); - + // ======================================================================== - static std::string ExpandLibName(const std::string &name, bool verbose); - -// =================================================================================== - - static std::string MakeLibnameFromPath(std::string path, std::string pkgname); - -// =================================================================================== - - static std::string MakePkgnameFromPath(std::string path, std::string pkgname, bool addExt); + + // ======================================================================= + static std::string MakeLibnameFromPath(std::string path, std::string pkgname); + + // ===================================================================== + static std::string MakePkgnameFromPath(std::string path, + std::string pkgname, bool addExt); //======================================================================== + // ======================================================================= - /// Builds the complete path to the file 'name' located - /// in user settings dir, e.g. /home/username/.bbtk/ - static std::string MakeUserSettingsFullFileName(const std::string& name); + /// Makes a valid filename with string (replaces invalid file seps + /// by valid ones) + static inline void MakeValidFileName(std::string& name) + { + replace( name, + INVALID_FILE_SEPARATOR , + VALID_FILE_SEPARATOR); + } + // ======================================================================= + /// Returns the user settings dir, e.g. /home/username/.bbtk + static std::string GetUserSettingsDir(); + // ======================================================================= + /// Builds the complete path to the file 'name' located + /// in user settings dir, e.g. /home/username/.bbtk/ + static std::string MakeUserSettingsFullFileName(const std::string& name); + + static bool IsAtRoot(std::string cwd); // ====================================================================== static bool IsDirectory(std::string const &dirName); - // =================================================================================== + + static void CreateDirectoryIfNeeded( std::string const &dirName); + // ======================================================================= static void SplitAroundFirstDot( const std::string& in, - std::string& left, + std::string& left, std::string& right); - //======================================================================= + //====================================================================== static void SplitString ( const std::string& str, const std::string& delimiters, std::vector& tokens); - //======================================================================= + //==================================================================== - // =================================================================================== + // ==================================================================== static std::string get_file_name(const std::string& s) ; - - // =================================================================================== + + // ==================================================================== /** * \brief Explore a directory with possibility of recursion * return number of files read @@ -134,8 +150,8 @@ namespace bbtk * @param recursive whether we want recursion or not */ static int Explore(std::string const &dirpath, bool recursive, std::vector &Filenames); - - + + //======================================================================= // Replaces substrings "\\n" by a real carriage return "\n" static void SubsBackslashN ( std::string& s ); diff --git a/kernel/src/bbtkWx.cxx b/kernel/src/bbtkWx.cxx index 29567ff..c8026e4 100644 --- a/kernel/src/bbtkWx.cxx +++ b/kernel/src/bbtkWx.cxx @@ -2,8 +2,8 @@ Program: bbtk Module: $RCSfile: bbtkWx.cxx,v $ Language: C++ - Date: $Date: 2008/10/21 13:55:49 $ - Version: $Revision: 1.11 $ + Date: $Date: 2009/01/27 14:22:57 $ + Version: $Revision: 1.12 $ =========================================================================*/ /* --------------------------------------------------------------------- @@ -302,17 +302,22 @@ namespace bbtk Wx::BusyCursor::BusyCursor() { mCursor = 0; - if (TopWindowExists()) + if (wxApp::GetInstance()!=0) { bbtkDebugMessage("wx",2, - "Wx::BusyCursor::BusyCursor()"< +#include //#include "icons/cc_run.xpm" @@ -88,7 +89,6 @@ namespace bbtk : wxFrame((wxFrame *)parent, -1, _T("bbStudio"), wxDefaultPosition, wxSize(1200,800) ) { - // m_mgr = new wxAuiManager(this); m_mgr.SetManagedWindow(this); mInterpreter = bbtk::Interpreter::New(); @@ -262,11 +262,38 @@ namespace bbtk // LoadPerspective(); mBreaked = false; + + wxBitmap bitmap; + wxSplashScreen* splash; + long style = wxSPLASH_CENTRE_ON_SCREEN | wxSPLASH_TIMEOUT; + if (ConfigurationFile::GetInstance().DotBbtkIsNew()) + style = wxSPLASH_CENTRE_ON_SCREEN | wxSPLASH_NO_TIMEOUT; + std::string splash_file = ConfigurationFile::GetInstance().Get_data_path(); + splash_file += "/kernel/icons/bbStudioSplashScreen.png"; + + if (bitmap.LoadFile(std2wx(splash_file),wxBITMAP_TYPE_PNG)) + splash = + new wxSplashScreen(bitmap, + style, + 1000, 0, -1, wxDefaultPosition, wxDefaultSize, + wxSIMPLE_BORDER|wxSTAY_ON_TOP); + - wxTipWindow* tip = new wxTipWindow(this, - _T("\n Welcome to bbStudio !\n\n To run a demo or example:\n 1. click on the 'Demos' or 'Examples' link\n 2. select a demo or example\n 3. click on the '[source]' link : the source file is loaded in bbStudio\n 4. click on the 'Run' button (the arrow at the bottom right of the source file) \n"),1000); - tip->CenterOnParent(); - tip->Show(); + if (ConfigurationFile::GetInstance().DotBbtkIsNew()) + { + + DoRegeneratePackageDoc("-a"); + DoRegenerateBoxesLists(); + + /* + wxTipWindow* tip = new wxTipWindow(this, + _T("\n Welcome to bbStudio !\n\n To run a demo or example:\n 1. click on the 'Demos' or 'Examples' link\n 2. select a demo or example\n 3. click on the '[source]' link : the source file is loaded in bbStudio\n 4. click on the 'Run' button (the arrow at the bottom right of the source file) \n"),1000); + tip->CenterOnParent(); + tip->Show(); + */ + if (splash) splash->Destroy(); + } + } //================================================================ @@ -507,11 +534,22 @@ namespace bbtk void WxGUIScriptingInterface::DoRegeneratePackageDoc( const std::string& pack ) { - std::string command; + std::string mess("Regenerating doc for package '"); + if (pack!="-a") + mess += pack + "'"; + else + mess = "Regenerating doc for all packages"; + mess += " ... please wait"; + + SetStatusText( std2wx(mess) ); + + BBTK_BUSY_CURSOR; + + std::string command; #if defined(WIN32) - command = "\""; + command = "\""; #endif - command += ConfigurationFile::GetInstance().Get_bin_path(); + command += ConfigurationFile::GetInstance().Get_bin_path(); command += ConfigurationFile::GetInstance().Get_file_separator(); command += "bbRegeneratePackageDoc"; #if defined(WIN32) @@ -523,15 +561,23 @@ namespace bbtk if ( ! system ( command.c_str() ) ) { - wxMessageBox(_T("Done !"),_T("Regenerate package '")+std2wx(pack)+_T("' doc"), + SetStatusText( _T("Done !")); + /* + wxMessageBox(_T("Done !"),_T("Regenerate package '") + +std2wx(pack)+_T("' doc"), wxOK | wxICON_INFORMATION); + */ } else { + SetStatusText( _T("Done !")); wxString err(_T("An error occured while running '")); err += bbtk::std2wx(command) + _T("'"); wxMessageBox(err,_T("Regenerate package doc"),wxOK | wxICON_ERROR); } + + + } @@ -549,8 +595,12 @@ namespace bbtk //================================================================ + //================================================================ void WxGUIScriptingInterface::DoRegenerateBoxesLists() { + SetStatusText( _T("Regenerating boxes lists ... please wait") ); + BBTK_BUSY_CURSOR ; + std::string command; #if defined(WIN32) command = "\""; @@ -564,18 +614,26 @@ namespace bbtk command += " -q"; bbtkMessage("debug",1,"Executing system command '"<