/* orxonox - the future of 3D-vertical-scrollers Copyright (C) 2004 orx This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ### File Specific: main-programmer: Benjamin Grauer */ #include "orxonox_gui_exec.h" #include #include #include HashTable* orxonoxFlagHash; /** \brief Creates the Exec-Frame */ OrxonoxGuiExec::OrxonoxGuiExec(void) { configFile =(char*)malloc(512*sizeof(char)); this->execFrame = new Frame("Execute-Tags:"); this->execBox = new Box('v'); this->execFrame->setGroupName("misc"); this->start = new Button("Start"); #ifdef HAVE_GTK2 this->start->connectSignal("clicked", this, startOrxonox); #endif /* HAVE_GTK2 */ this->execBox->fill(start); this->saveSettings = new CheckButton("Save Settings"); this->saveSettings->value = 1; this->saveSettings->saveability(); this->execBox->fill(this->saveSettings); this->verboseMode = new Menu("verbose mode", "nothing", "error", "warning", "info", "lastItem"); this->verboseMode->setFlagName("verbose", "v", 0); this->verboseMode->saveability(); this->execBox->fill(this->verboseMode); this->alwaysShow = new CheckButton("Always Show this Menu"); this->alwaysShow->setFlagName("gui", "g", 0); this->alwaysShow->saveability(); this->execBox->fill(this->alwaysShow); this->quit = new Button("Quit"); #ifdef HAVE_GTK2 this->quit->connectSignal("clicked", this, OrxonoxGuiExec::quitOrxonox); // Window::mainWindow->connectSignal("remove", this, OrxonoxGuiExec::quitOrxonox); Window::mainWindow->connectSignal("destroy", this, OrxonoxGuiExec::quitOrxonox); #endif /* HAVE_GTK2 */ this->execBox->fill(this->quit); this->execFrame->fill(this->execBox); this->setMainWidget(execFrame); } /** \brief Destructs the Execution-stuff */ OrxonoxGuiExec::~OrxonoxGuiExec(void) { if(this->configFile) delete []this->configFile; } /* FILE HANDLING */ /** \brief sets the confDir and File-name out of an input-string */ void OrxonoxGuiExec::setConfFile(char* confFile) { char splitter = #ifdef __WIN32__ '\\'; #else '/'; #endif char* tmpConfFile = new char[strlen(confFile)+1]; strcpy(tmpConfFile, confFile); char* tmp = strrchr(tmpConfFile, splitter); if (tmp) { tmp[0] = '\0'; this->setConfDir(tmpConfFile); this->setFileName(tmp+1); } else { this->setConfDir("~/"); this->setFileName(tmpConfFile); } delete []tmp; delete []tmpConfFile; } /** \brief sets the Directory of the configuration files \param confDir the Directory for the configuration files */ void OrxonoxGuiExec::setConfDir(char* confDir) { if (!strncmp(confDir, "~/", 2)) { char tmp[500]; #ifdef __WIN32__ strcpy(tmp, getenv("USERPROFILE")); #else strcpy(tmp, getenv("HOME")); #endif this->confDir = new char[strlen(tmp)+strlen(confDir)]; sprintf(this->confDir, "%s%s", tmp, confDir+1); } else { this->confDir = new char[strlen(confDir)+1]; strcpy(this->confDir, confDir); } PRINTF(3)("Config Directory is: %s.\n", this->confDir); mkdir(this->confDir, 0755); } /** \brief Sets the location of the configuration File. \param fileName the location of the configFile \todo: memory allocation could be better. The name will be parsed from ~/ to /home/[username] on unix and c:/Documents and Settings/username/Settings/ on Windows */ void OrxonoxGuiExec::setFileName(char* fileName) { if (!this->confDir) this->setConfDir("~/"); this->configFile = new char[strlen(this->confDir)+strlen(fileName)+2]; sprintf(this->configFile, "%s/%s", this->confDir, fileName); PRINTF(3)("ConfigurationFile is %s.\n", this->configFile); } /** \returns The name of the Configuration-File */ char* OrxonoxGuiExec::getConfigFile(void) const { return this->configFile; } /** \brief checks if a option should be saved. \return 1 if it should 0 if not/ */ int OrxonoxGuiExec::shouldsave() { return(static_cast(this->saveSettings)->value); } /** \brief Saves the configuration-file to the Disk.\n \param widget from which Widget on should be saved. this Function only opens and closes the file, in between OrxonoxGuiExec::writeFileText(Widget* widget) will execute the real writing process. */ void OrxonoxGuiExec::writeToFile(Widget* widget) { this->CONFIG_FILE = fopen(configFile, "w"); if(this->CONFIG_FILE) this->writeFileText(widget, 0); fclose(this->CONFIG_FILE); } /** \brief Actually writes into the configuration file to the disk. \param widget from which Widget on should be saved. \param depth initially "0", and grows higher, while new Groups are bundeled. */ void OrxonoxGuiExec::writeFileText(Widget* widget, int depth) { int counter = 0; while(counter < depth &&((widget->isOption>0 &&(static_cast(widget)->isSaveable())) ||(widget->isOption<0 && static_cast(widget)->getGroupName()))) { fprintf(this->CONFIG_FILE, " ", depth); counter++; } // check if it is a Packer, and if it is, check if it has a name and if there is something in it. if(widget->isOption <0) { if(static_cast(widget)->getGroupName()) { fprintf(CONFIG_FILE, "[%s]\n", static_cast(widget)->getGroupName()); this->writeFileText(static_cast(widget)->down, depth+1); fprintf(CONFIG_FILE, "\n"); } else { this->writeFileText(static_cast(widget)->down, depth); } } // if(widget->isOption == 0) // printf("%s\n",widget->title); if(widget->isOption >= 1) if (static_cast(widget)->isSaveable()) { char Buffer[256]; char* space2under; strcpy(Buffer, static_cast(widget)->title); if(strchr(Buffer, '_')) PRINTF(2)("Optionname %s is not Valid for Saving, because it includes an underscore\n", Buffer); while(space2under = strchr(Buffer, ' ')) { space2under[0] = '_'; } fprintf(CONFIG_FILE, "%s = %s\n", Buffer, static_cast(widget)->save()); } if(widget->next != NULL) this->writeFileText(widget->next, depth); } /** \brief Reads in Configuration Data. \param widget from which Widget on should be saved. */ void OrxonoxGuiExec::readFromFile(Widget* widget) { this->CONFIG_FILE = fopen(configFile, "r"); VarInfo varInfo; if(this->CONFIG_FILE) { Widget* groupWidget = widget; char Buffer[256] = ""; char Variable[256]= ""; char* Value; while(fscanf(this->CONFIG_FILE, "%s", Buffer) != EOF) { // group-search // if(!strncmp(Buffer, "[", 1)) { if((groupWidget = locateGroup(widget, Buffer, 1))==NULL) { PRINTF(2)("!!There is no group called %s in this GUI.\n First best Widget will get the Infos assigned.\n Config-File will be updated in next Save\n", Buffer); groupWidget = widget; } else PRINT(5)("Group %s located.\n", static_cast(groupWidget)->groupName); } // option-setting // if(!strcmp(Buffer, "=")) { char* under2space; while(under2space = strchr(Variable, '_')) { sprintf(under2space, " %s", under2space+1); } fscanf(this->CONFIG_FILE, "%s", Buffer); varInfo.variableName = Variable; varInfo.variableValue = Buffer; groupWidget->walkThrough(this->readFileText, &varInfo, 0); sprintf(Variable, ""); } sprintf(Variable, "%s", Buffer); } widget->walkThrough(widget->setOptions, 0); } } /** \brief Maps Confugurations to the Options. \param widget which widget downwards \param varInfo Information about the Variable to read */ void OrxonoxGuiExec::readFileText(Widget* widget, void* varInfo) { VarInfo* info =(VarInfo*)varInfo; if(widget->title && !strcmp(widget->title, info->variableName)) { PRINT(5)("Located Option %s.\n", widget->title); if(widget->isOption >= 1) static_cast(widget)->load(info->variableValue); } } /** \brief Locates a Group. \param widget The Widget from where to search from \param groupName The GroupName for which to search. \param depth The Depth of the search seen from the first widget we searched from. \returns The Widget that holds the Group, or the NULL if the Group wasn't found. \todo do this in gui-gtk. */ Widget* OrxonoxGuiExec::locateGroup(Widget* widget, char* groupName, int depth) { Widget* tmp; // removes the trailing and ending [ ]. if(!strncmp(groupName, "[", 1)) { groupName = groupName+1; groupName[strlen(groupName)-1] = '\0'; } if(widget->isOption < 0) { if(static_cast(widget)->getGroupName() && !strcmp(groupName, static_cast(widget)->getGroupName())) { return widget; } else { if((tmp = locateGroup(static_cast(widget)->down, groupName, depth+1)) != NULL) return tmp; } } if(widget->next != NULL && depth != 0) { if((tmp = locateGroup(widget->next, groupName, depth)) != NULL) return tmp; } return NULL; } #ifdef HAVE_GTK2 /** \brief Starts ORXONOX.(not really implemented yet, but the function is there.\n \param widget the widget that executed the start command \param data additional data This is a Signal and can be executed through Widget::signal_connect */ int OrxonoxGuiExec::startOrxonox(GtkWidget* widget, void* data) { OrxonoxGuiExec* exec =(OrxonoxGuiExec*)data; if(exec->shouldsave()) exec->writeToFile(Window::mainWindow); cout << "Starting Orxonox" <shouldsave()) exec->writeToFile(Window::mainWindow); gtk_main_quit(); } #else /* HAVE_GTK2 */ /** \brief Starts ORXONOX.(not really implemented yet, but the function is there.\n \param widget the widget that executed the start command \param data additional data */ int OrxonoxGuiExec::startOrxonox(void* widget, void* data) { OrxonoxGuiExec* exec =(OrxonoxGuiExec*)data; PRINT(3)("Starting Orxonox\n"); if(exec->shouldsave()) exec->writeToFile(Window::mainWindow); system("cd ..;./orxonox"); //!< \todo fix this. should execute orxonox for real(coded not over the shell) } /** \brief Quits ORXONOX. \param widget the widget that executed the Quit command \param data additional data This is a Signal and can be executed through Widget::signal_connect */ int OrxonoxGuiExec::quitOrxonox(void* widget, void* data) { OrxonoxGuiExec* exec =(OrxonoxGuiExec*)data; PRINT(3)("Quiting Orxonox"); if(exec->shouldsave()) exec->writeToFile(Window::mainWindow); } #endif /* HAVE_GTK2 */