/* 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 "gui_exec.h" #include "resource_manager.h" #include #include #include #include #ifdef __WIN32__ #include #endif /* __WIN32__ */ HashTable* orxonoxFlagHash; /** \brief Creates the Exec-Frame */ GuiExec::GuiExec(void) { Frame* execFrame; //!< The Frame that holds the ExecutionOptions. this->confFile = NULL; this->confDir = NULL; execFrame = new Frame("Execute-Tags:"); { Box* execBox; //!< The Box that holds the ExecutionOptions. execBox = new Box('v'); execFrame->setGroupName("misc"); { Button* start; //!< The start Button of orxonox. Menu* verboseMode; //!< A Menu for setting the verbose-Mode. \todo setting up a verbose-class. CheckButton* alwaysShow; //!< A CheckButton, for if orxonox should start with or without gui. Button* quit; //!< A Button to quit the Gui without starting orxonox. start = new Button("Start"); #ifdef HAVE_GTK2 start->connectSignal("clicked", this, startOrxonox); #endif /* HAVE_GTK2 */ execBox->fill(start); this->saveSettings = new CheckButton("Save Settings"); this->saveSettings->value = 1; this->saveSettings->saveability(); execBox->fill(this->saveSettings); verboseMode = new Menu("verbose mode", "nothing", "error", "warning", "info", "lastItem"); verboseMode->setFlagName("verbose", "v", 2); verboseMode->saveability(); execBox->fill(verboseMode); alwaysShow = new CheckButton("Always Show this Menu"); alwaysShow->setFlagName("gui", "g", 0); alwaysShow->saveability(); execBox->fill(alwaysShow); quit = new Button("Quit"); #ifdef HAVE_GTK2 quit->connectSignal("clicked", this, GuiExec::quitGui); // Window::mainWindow->connectSignal("remove", this, GuiExec::quitGui); Window::mainWindow->connectSignal("destroy", this, GuiExec::quitGui); #endif /* HAVE_GTK2 */ execBox->fill(quit); } execFrame->fill(execBox); } setMainWidget(execFrame); } /** \brief Destructs the Execution-stuff */ GuiExec::~GuiExec(void) { if(this->confFile) delete []this->confFile; if(this->confDir) delete []this->confDir; } /* FILE HANDLING */ /** \brief sets the Directory of the configuration files \param confDir the Directory for the configuration files */ void GuiExec::setConfDir(const char* confDir) { this->confDir = ResourceManager::homeDirCheck(confDir); PRINTF(3)("Config Directory is: %s.\n", this->confDir); //! \todo F** Windows-support #ifndef __WIN32__ mkdir(this->confDir, 0755); #else /* __WiN32__ */ mkdir(this->confDir); #endif /* __WIN32__ */ } /** \brief Sets the location of the configuration File. \param fileName the location of the configFile The name will be parsed from ~/ to /home/[username] on unix and c:/Documents and Settings/username/Settings/ on Windows */ void GuiExec::setConfFile(const char* fileName) { if (!this->confDir) this->setConfDir("~/"); this->confFile = new char[strlen(this->confDir)+strlen(fileName)+2]; sprintf(this->confFile, "%s/%s", this->confDir, fileName); PRINTF(3)("ConfigurationFile is %s.\n", this->confFile); } /** \returns The name of the Configuration-File */ const char* GuiExec::getConfigFile(void) const { return this->confFile; } /** \brief checks if a option should be saved. \return 1 if it should 0 if not/ */ int GuiExec::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 GuiExec::writeFileText(Widget* widget) will execute the real writing process. */ void GuiExec::writeToFile(Widget* widget) { this->CONFIG_FILE = fopen(this->confFile, "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 GuiExec::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 GuiExec::readFromFile(Widget* widget) { this->CONFIG_FILE = fopen(this->confFile, "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 GuiExec::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* GuiExec::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; } /** \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 */ #ifdef HAVE_GTK2 int GuiExec::startOrxonox(GtkWidget* widget, void* data) #else /* HAVE_GTK2 */ int GuiExec::startOrxonox(void* widget, void* data) #endif /* HAVE_GTK2 */ { Window::mainWindow->hide(); #ifdef HAVE_GTK2 gtk_widget_destroy(Window::mainWindow->widget); #else quitGui(widget, data); #endif /* HAVE_GTK2 */ PRINT(3)("Starting Orxonox\n"); Gui::startOrxonox = true; } /** \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 */ #ifdef HAVE_GTK2 int GuiExec::quitGui(GtkWidget* widget, void* data) #else /* HAVE_GTK2 */ int GuiExec::quitGui(void* widget, void* data) #endif /* HAVE_GTK2 */ { GuiExec* exec = (GuiExec*)data; if(exec->shouldsave()) exec->writeToFile(Window::mainWindow); #ifdef HAVE_GTK2 gtk_main_quit(); while(gtk_events_pending()) gtk_main_iteration(); #endif /* HAVE_GTK2 */ }