Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/consolecommands3/src/libraries/core/command/ArgumentCompletionFunctions.cc @ 7233

Last change on this file since 7233 was 7233, checked in by landauf, 15 years ago
  • console commands "setMMSoundPath" and "printObjects" are now hidden.
  • added "unhide" command to show hidden commands
  • extended auto-completion capability by allowing multi-word ArgumentCompleter and more
  • added new auto-completion function that allows other commands as argument for a command (for example "delay [time] [command]")
  • Property svn:eol-style set to native
File size: 10.3 KB
Line 
1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *                    > www.orxonox.net <
4 *
5 *
6 *   License notice:
7 *
8 *   This program is free software; you can redistribute it and/or
9 *   modify it under the terms of the GNU General Public License
10 *   as published by the Free Software Foundation; either version 2
11 *   of the License, or (at your option) any later version.
12 *
13 *   This program is distributed in the hope that it will be useful,
14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 *   GNU General Public License for more details.
17 *
18 *   You should have received a copy of the GNU General Public License
19 *   along with this program; if not, write to the Free Software
20 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 *
22 *   Author:
23 *      Fabian 'x3n' Landau
24 *   Co-authors:
25 *      ...
26 *
27 */
28
29#include "ArgumentCompletionFunctions.h"
30
31#include <map>
32#include <boost/version.hpp>
33#include <boost/filesystem.hpp>
34
35#include "util/Convert.h"
36#include "util/StringUtils.h"
37#include "core/Identifier.h"
38#include "core/ConfigFileManager.h"
39#include "core/ConfigValueContainer.h"
40#include "CommandExecutor.h"
41#include "ConsoleCommand.h"
42#include "TclThreadManager.h"
43
44// Boost 1.36 has some issues with deprecated functions that have been omitted
45#if (BOOST_VERSION == 103600)
46#  define BOOST_LEAF_FUNCTION filename
47#else
48#  define BOOST_LEAF_FUNCTION leaf
49#endif
50
51namespace orxonox
52{
53    namespace autocompletion
54    {
55        ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION(fallback)()
56        {
57            return ArgumentCompletionList();
58        }
59
60        namespace detail
61        {
62            bool groupIsVisible(const std::map<std::string, _ConsoleCommand*>& group, bool bOnlyShowHidden)
63            {
64                for (std::map<std::string, _ConsoleCommand*>::const_iterator it_command = group.begin(); it_command != group.end(); ++it_command)
65                    if (it_command->second->isActive() && it_command->second->hasAccess() && (!it_command->second->isHidden())^bOnlyShowHidden)
66                        return true;
67
68                return false;
69            }
70
71            ArgumentCompletionList _groupsandcommands(bool bOnlyShowHidden)
72            {
73                ArgumentCompletionList groupList;
74
75                const std::map<std::string, std::map<std::string, _ConsoleCommand*> >& commands = _ConsoleCommand::getCommands();
76                for (std::map<std::string, std::map<std::string, _ConsoleCommand*> >::const_iterator it_group = commands.begin(); it_group != commands.end(); ++it_group)
77                    if (groupIsVisible(it_group->second, bOnlyShowHidden) && it_group->first != "")
78                        groupList.push_back(ArgumentCompletionListElement(it_group->first, getLowercase(it_group->first)));
79
80                std::map<std::string, std::map<std::string, _ConsoleCommand*> >::const_iterator it_group = commands.find("");
81                if (it_group != commands.end())
82                {
83                    groupList.push_back(ArgumentCompletionListElement("", "", "\n"));
84
85                    for (std::map<std::string, _ConsoleCommand*>::const_iterator it_command = it_group->second.begin(); it_command != it_group->second.end(); ++it_command)
86                        if (it_command->second->isActive() && it_command->second->hasAccess() && (!it_command->second->isHidden())^bOnlyShowHidden)
87                            groupList.push_back(ArgumentCompletionListElement(it_command->first, getLowercase(it_command->first)));
88                }
89
90                return groupList;
91            }
92
93            ArgumentCompletionList _subcommands(const std::string& fragment, const std::string& group, bool bOnlyShowHidden)
94            {
95                ArgumentCompletionList commandList;
96
97                std::string groupLC = getLowercase(group);
98
99                std::map<std::string, std::map<std::string, _ConsoleCommand*> >::const_iterator it_group = _ConsoleCommand::getCommands().begin();
100                for ( ; it_group != _ConsoleCommand::getCommands().end(); ++it_group)
101                    if (getLowercase(it_group->first) == groupLC)
102                        break;
103
104                if (it_group != _ConsoleCommand::getCommands().end())
105                {
106                    for (std::map<std::string, _ConsoleCommand*>::const_iterator it_command = it_group->second.begin(); it_command != it_group->second.end(); ++it_command)
107                        if (it_command->second->isActive() && it_command->second->hasAccess() && (!it_command->second->isHidden())^bOnlyShowHidden)
108                            commandList.push_back(ArgumentCompletionListElement(it_command->first, getLowercase(it_command->first)));
109                }
110
111                return commandList;
112            }
113        }
114
115        ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION(groupsandcommands)()
116        {
117            return detail::_groupsandcommands(false);
118        }
119
120        ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION(subcommands)(const std::string& fragment, const std::string& group)
121        {
122            return detail::_subcommands(fragment, group, false);
123        }
124
125        ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION(hiddengroupsandcommands)()
126        {
127            return detail::_groupsandcommands(true);
128        }
129
130        ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION(hiddensubcommands)(const std::string& fragment, const std::string& group)
131        {
132            return detail::_subcommands(fragment, group, true);
133        }
134
135        ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION_MULTI(command)(const std::string& fragment)
136        {
137            CommandEvaluation evaluation = CommandExecutor::evaluate(fragment);
138            const std::string& hint = evaluation.hint();
139
140            if (evaluation.getPossibleArguments().size() > 0)
141            {
142                return evaluation.getPossibleArguments();
143            }
144            else
145            {
146                ArgumentCompletionList list;
147                list.push_back(ArgumentCompletionListElement("", "", hint));
148                return list;
149            }
150        }
151
152        ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION(files)(const std::string& fragment)
153        {
154            ArgumentCompletionList dirlist;
155            ArgumentCompletionList filelist;
156
157            try
158            {
159                boost::filesystem::path input(fragment);
160                boost::filesystem::path startdirectory(input.branch_path());
161
162                if (!boost::filesystem::exists(startdirectory))
163                {
164                    startdirectory = ".";
165                }
166#ifdef ORXONOX_PLATFORM_WINDOWS
167                else
168                {
169                    const std::string& dir = startdirectory.string();
170                    if (dir.size() > 0 && dir[dir.size() - 1] == ':')
171                        startdirectory = dir + '/';
172                }
173#endif
174
175                boost::filesystem::directory_iterator file(startdirectory);
176                boost::filesystem::directory_iterator end;
177
178                while (file != end)
179                {
180                    if (boost::filesystem::is_directory(*file))
181                        dirlist.push_back(ArgumentCompletionListElement(file->string() + '/', getLowercase(file->string()) + '/', file->BOOST_LEAF_FUNCTION() + '/'));
182                    else
183                        filelist.push_back(ArgumentCompletionListElement(file->string(), getLowercase(file->string()), file->BOOST_LEAF_FUNCTION()));
184                    ++file;
185                }
186            }
187            catch (...) {}
188
189            filelist.insert(filelist.begin(), dirlist.begin(), dirlist.end());
190            return filelist;
191        }
192
193        ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION(settingssections)()
194        {
195            ArgumentCompletionList sectionList;
196
197            const std::set<std::string>& names = SettingsConfigFile::getInstance().getSectionNames();
198            for (std::set<std::string>::const_iterator it = names.begin(); it != names.end(); ++it)
199                sectionList.push_back(ArgumentCompletionListElement(*it, getLowercase(*it)));
200
201            return sectionList;
202        }
203
204        ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION(settingsentries)(const std::string& fragment, const std::string& section)
205        {
206            ArgumentCompletionList entryList;
207            SettingsConfigFile& settings = SettingsConfigFile::getInstance();
208            const std::string& sectionLC = getLowercase(section);
209
210            SettingsConfigFile::ContainerMap::const_iterator upper = settings.getContainerUpperBound(sectionLC);
211            for (SettingsConfigFile::ContainerMap::const_iterator it = settings.getContainerLowerBound(sectionLC); it != upper; ++it)
212                entryList.push_back(ArgumentCompletionListElement(it->second.second->getName(), it->second.first));
213
214            return entryList;
215        }
216
217        ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION(settingsvalue)(const std::string& fragment, const std::string& entry, const std::string& section)
218        {
219            ArgumentCompletionList oldValue;
220            SettingsConfigFile& settings = SettingsConfigFile::getInstance();
221            const std::string& sectionLC = getLowercase(section);
222            const std::string& entryLC = getLowercase(entry);
223
224            SettingsConfigFile::ContainerMap::const_iterator upper = settings.getContainerUpperBound(sectionLC);
225            for (SettingsConfigFile::ContainerMap::const_iterator it = settings.getContainerLowerBound(sectionLC); it != upper; ++it)
226            {
227                if (it->second.first == entryLC)
228                {
229                    const std::string& valuestring = it->second.second->toString();
230                    oldValue.push_back(ArgumentCompletionListElement(valuestring, getLowercase(valuestring), "Old value: " + valuestring));
231                }
232            }
233
234            return oldValue;
235        }
236
237        ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION(tclthreads)()
238        {
239            std::list<unsigned int> threadnumbers = TclThreadManager::getInstance().getThreadList();
240            ArgumentCompletionList threads;
241
242            for (std::list<unsigned int>::const_iterator it = threadnumbers.begin(); it != threadnumbers.end(); ++it)
243                threads.push_back(ArgumentCompletionListElement(multi_cast<std::string>(*it)));
244
245            return threads;
246        }
247    }
248}
Note: See TracBrowser for help on using the repository browser.