/*************************************************************************** * * Copyright (C) 2007 Elad Lahav (elad_lahav@users.sourceforge.net) * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ***************************************************************************/ #include #include #include #include #include #include "project.h" #include "kscopeconfig.h" #include "cscopefrontend.h" #define PROJECT_CONFIG_VER 2 inline void flListFromStringList(FileLocationList& fll, const TQStringList& sl) { TQStringList::ConstIterator itr; TQString sPath; uint nLine, nCol; // Transform the string into a list of file locations for (itr = sl.begin(); itr != sl.end(); ++itr) { sPath = (*itr).section(':', 0, 0); nLine = (*itr).section(':', 1, 1).toUInt(); nCol = (*itr).section(':', 2, 2).toUInt(); fll.append(new FileLocation(sPath, nLine, nCol)); } } inline void stringListFromFlList(TQStringList& sl, const FileLocationList& fll) { FileLocationList* pList; FileLocation* pLoc; TQString sLoc; // Nasty... pList = (FileLocationList*)&fll; sl.clear(); // Turn the object list into a string list, so that it can be written in // the configuration file for (pLoc = pList->first(); pLoc != NULL; pLoc = pList->next()) { sLoc = ""; TQTextOStream(&sLoc) << pLoc->m_sPath << ":" << pLoc->m_nLine << ":" << pLoc->m_nCol; sl.append(sLoc); } } /** */ Project::Project() : ProjectBase(), m_pConf(NULL) { } /** */ Project::~Project() { close(); } /** */ bool Project::open(const TQString& sPath) { TQString sConfFile; Options opt; // Associate the object with the project directory m_dir.setPath(sPath); if (!m_dir.exists()) { KMessageBox::error(0, i18n("Project directory does not exist")); return false; } // Initialise the file-list file object m_fiFileList.setName(sPath + "/cscope.files"); // Open the configuration files m_pConf = new TDEConfig(sPath + "/cscope.proj"); // Verify the configuration file's version is compatible m_pConf->setGroup(""); if (m_pConf->readUnsignedNumEntry("Version", 0) != PROJECT_CONFIG_VER) { KMessageBox::error(0, i18n("Your project is not compatible with this " "version of KScope.\nPlease re-create the project.")); return false; } // Get the project name m_pConf->setGroup("Project"); m_sName = m_pConf->readEntry("Name"); if (m_sName == TQString::null) { KMessageBox::error(0, i18n("Cannot read project name")); return false; } // Get stored options initOptions(); // Set default make values for new projects (overriden in loadSession(), // which is not called for new projects) m_sMakeRoot = getSourceRoot(); m_sMakeCmd = "make"; return true; } /** */ void Project::close() { if (m_pConf) delete m_pConf; m_fiFileList.close(); } /** * Returns a semi-colon separated list of the file types included in the * current project. */ TQString Project::getFileTypes() const { TQString sTypes; m_pConf->setGroup("Project"); return m_pConf->readEntry("FileTypes"); } /** * Reads the project's options from the configuration file. * @param opt A structure to fill with the read options */ void Project::getOptions(Options& opt) const { // Get project properties m_pConf->setGroup("Project"); opt.sSrcRootPath = m_pConf->readEntry("RootPath", "/"); opt.slFileTypes = m_pConf->readListEntry("FileTypes", ' '); opt.bKernel = m_pConf->readBoolEntry("Kernel", DEF_IS_KERNEL); opt.bInvIndex = m_pConf->readBoolEntry("InvIndex", DEF_INV_INDEX); opt.bNoCompress = m_pConf->readBoolEntry("NoCompress", DEF_NO_COMPRESS); opt.bSlowPathDef = m_pConf->readBoolEntry("SlowPathDef", DEF_SLOW_PATH); opt.nAutoRebuildTime = m_pConf->readNumEntry("AutoRebuildTime"); opt.nTabWidth = m_pConf->readUnsignedNumEntry("TabWidth"); opt.sCtagsCmd = m_pConf->readEntry("CtagsCommand", DEF_CTAGS_COMMAND); // Get auto-completion options m_pConf->setGroup("AutoCompletion"); opt.bACEnabled = m_pConf->readBoolEntry("Enabled"); opt.nACMinChars = m_pConf->readUnsignedNumEntry("MinChars", DEF_AC_MIN_CHARS); opt.nACDelay = m_pConf->readUnsignedNumEntry("Delay", DEF_AC_DELAY); opt.nACMaxEntries = m_pConf->readUnsignedNumEntry("MaxEntries", DEF_AC_MAX_ENTRIES); } /** * Sets project options. * @param opt A structure containing the new parameters to set */ void Project::setOptions(const Options& opt) { // Write the options to the configuration nfile writeOptions(m_pConf, opt); // Update project parameters initOptions(); } /** */ void Project::loadSession(Session& sess) { TQStringList slEntry; m_pConf->setGroup("Session"); // Read the list of open file locations slEntry = m_pConf->readListEntry("OpenFiles"); flListFromStringList(sess.fllOpenFiles, slEntry); // Get the path of the last viewed file sess.sLastFile = m_pConf->readEntry("LastOpenFile"); // Read the lists of locked query files and call-tree/graph files sess.slQueryFiles = m_pConf->readListEntry("QueryFiles"); sess.slCallTreeFiles = m_pConf->readListEntry("CallTreeFiles"); // Read the list of bookmarks slEntry = m_pConf->readListEntry("Bookmarks"); flListFromStringList(sess.fllBookmarks, slEntry); // Read make-related information sess.sMakeCmd = m_pConf->readEntry("MakeCommand", "make"); sess.sMakeRoot = m_pConf->readEntry("MakeRoot", getSourceRoot()); // Cache make values m_sMakeCmd = sess.sMakeCmd; m_sMakeRoot = sess.sMakeRoot; } /** * Saves session-related information in the project's configuration file. * @param sess Session parameters */ void Project::storeSession(const Session& sess) { TQStringList slEntry; m_pConf->setGroup("Session"); // Write the list of open file locations stringListFromFlList(slEntry, sess.fllOpenFiles); m_pConf->writeEntry("OpenFiles", slEntry); // Write the path of the last viewed file m_pConf->writeEntry("LastOpenFile", sess.sLastFile); // Write the lists of locked query files and call-tree/graph files m_pConf->writeEntry("QueryFiles", sess.slQueryFiles); m_pConf->writeEntry("CallTreeFiles", sess.slCallTreeFiles); // Write the list of bookmarks stringListFromFlList(slEntry, sess.fllBookmarks); m_pConf->writeEntry("Bookmarks", slEntry); // Write make-related information // Be careful not to write empty strings, as they may occur if the make // dialogue was not invoked during this session if (!sess.sMakeCmd.isEmpty()) m_pConf->writeEntry("MakeCommand", sess.sMakeCmd); if (!sess.sMakeRoot.isEmpty()) m_pConf->writeEntry("MakeRoot", sess.sMakeRoot); } /** * Fills a list object with all files in the project. * List items are created by reading and parsing all file name entries from * the project's 'cscope.files' file. * Note that the file may contain option lines, beginning with a dash. These * should be ignored. * @param pList Pointer to the object to fill */ bool Project::loadFileList(FileListTarget* pList) { TQString sFilePath; // Open the 'cscope.files' file if (!m_fiFileList.open(IO_ReadOnly)) return false; // Read all file names from the file TQTextStream str(&m_fiFileList); while ((sFilePath = str.readLine()) != TQString::null) { // Skip option lines if (sFilePath.at(0) == '-') continue; // Set the new list item pList->addItem(sFilePath); } m_fiFileList.close(); return true; } /** * Writes all file entries in a list view widget to the project's * 'cscope.files' file (replacing current file contents.) * @param pList Pointer to the object from which to take the new entries */ bool Project::storeFileList(FileListSource* pList) { TQString sFilePath; // Open the 'cscope.files' file if (!m_fiFileList.open(IO_WriteOnly | IO_Truncate)) return false; TQTextStream str(&m_fiFileList); // Write all file names if (pList->firstItem(sFilePath)) { do { str << sFilePath << "\n"; } while (pList->nextItem(sFilePath)); } m_fiFileList.close(); return true; } /** * Adds a single file to the file list. * @param sPath The path of the file to add * @return true if successful, false otherwise */ bool Project::addFile(const TQString& sPath) { // Open the 'cscope.files' file if (!m_fiFileList.open(IO_WriteOnly | IO_Append)) return false; // Write the file path TQTextStream str(&m_fiFileList); str << sPath << "\n"; m_fiFileList.close(); return true; } /** * Determines whether the project includes any files. * Reads the 'cscope.files' file and looks for any file names in it. If none * is present, then the project is considered empty. * Note that the file may contain option lines, beginning with a dash. These * should be ignored. * @return true if no files are included in the project, false otherwise */ bool Project::isEmpty() { TQString sPath, sFileName; bool bResult = true; // Open the 'cscope.files' file if (!m_fiFileList.open(IO_ReadOnly)) return true; // Find at least one file name entry in the file TQTextStream str(&m_fiFileList); while ((sPath = str.readLine()) != TQString::null) { if (sPath.at(0) != '-') { bResult = false; break; } } m_fiFileList.close(); return bResult; } /** * Copies the list of previously queried symbols to the target object. * @param slSymHistory The list object to copy into */ void Project::getSymHistory(TQStringList& slSymHistory) const { slSymHistory = m_slSymHistory; } /** * Copies the list of previously queried symbols from the target object. * @param slSymHistory The list object to copy from */ void Project::setSymHistory(TQStringList& slSymHistory) { m_slSymHistory = slSymHistory; } void Project::getMakeParams(TQString& sCmd, TQString& sDir) const { sCmd = m_sMakeCmd; sDir = m_sMakeRoot; } /** * Creates a project by writing a configuration file inside the given * directory. * @param sName The project's name * @param sPath The full path of the project's directory * @param opt Project options */ bool Project::create(const TQString& sName, const TQString& sPath, const Options& opt) { // Prepare the project's files TDEConfig conf(sPath + "/cscope.proj"); // Write the configuration file version conf.setGroup(""); conf.writeEntry("Version", PROJECT_CONFIG_VER); // Write project properties in the configuration file conf.setGroup("Project"); conf.writeEntry("Name", sName); writeOptions(&conf, opt); // Flush the config file data, so the project is created even if KScope // crashes... conf.sync(); return true; } void Project::writeOptions(TDEConfig* pConf, const Options& opt) { pConf->setGroup("Project"); pConf->writeEntry("RootPath", opt.sSrcRootPath); pConf->writeEntry("FileTypes", opt.slFileTypes.join(" ")); pConf->writeEntry("Kernel", opt.bKernel); pConf->writeEntry("InvIndex", opt.bInvIndex); pConf->writeEntry("NoCompress", opt.bNoCompress); pConf->writeEntry("SlowPathDef", opt.bSlowPathDef); pConf->writeEntry("AutoRebuildTime", opt.nAutoRebuildTime); pConf->writeEntry("TabWidth", opt.nTabWidth); pConf->writeEntry("CtagsCommand", opt.sCtagsCmd); // Set auto-completion options pConf->setGroup("AutoCompletion"); pConf->writeEntry("Enabled", opt.bACEnabled); pConf->writeEntry("MinChars", opt.nACMinChars); pConf->writeEntry("Delay", opt.nACDelay); pConf->writeEntry("MaxEntries", opt.nACMaxEntries); }