Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 7712 was 7276, checked in by landauf, 14 years ago

until now we could group words and values in console commands and XML values using parentheses (…). now we have to use braces {…}, because that works better in connection with Tcl. in practice however this feature was never used before, so this change shouldn't affect anything.

  • Property svn:eol-style set to native
File size: 11.6 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(const std::string& fragment, bool bOnlyShowHidden)
72            {
73                ArgumentCompletionList groupList;
74                std::string fragmentLC = getLowercase(fragment);
75
76                const std::map<std::string, std::map<std::string, ConsoleCommand*> >& commands = ConsoleCommand::getCommands();
77                for (std::map<std::string, std::map<std::string, ConsoleCommand*> >::const_iterator it_group = commands.begin(); it_group != commands.end(); ++it_group)
78                    if (groupIsVisible(it_group->second, bOnlyShowHidden) && it_group->first != "" && (fragmentLC == "" || getLowercase(it_group->first).find_first_of(fragmentLC) == 0))
79                        groupList.push_back(ArgumentCompletionListElement(it_group->first, getLowercase(it_group->first)));
80
81                std::map<std::string, std::map<std::string, ConsoleCommand*> >::const_iterator it_group = commands.find("");
82                if (it_group != commands.end())
83                {
84                    if (!groupList.empty())
85                        groupList.push_back(ArgumentCompletionListElement("", "", "\n"));
86
87                    for (std::map<std::string, ConsoleCommand*>::const_iterator it_command = it_group->second.begin(); it_command != it_group->second.end(); ++it_command)
88                        if (it_command->second->isActive() && it_command->second->hasAccess() && (!it_command->second->isHidden())^bOnlyShowHidden && (fragmentLC == "" || getLowercase(it_command->first).find_first_of(fragmentLC) == 0))
89                            groupList.push_back(ArgumentCompletionListElement(it_command->first, getLowercase(it_command->first)));
90                }
91
92                if (!groupList.empty() && groupList.back().getDisplay() == "\n")
93                    groupList.pop_back();
94
95                return groupList;
96            }
97
98            ArgumentCompletionList _subcommands(const std::string& fragment, const std::string& group, bool bOnlyShowHidden)
99            {
100                ArgumentCompletionList commandList;
101
102                std::string groupLC = getLowercase(group);
103
104                std::map<std::string, std::map<std::string, ConsoleCommand*> >::const_iterator it_group = ConsoleCommand::getCommands().begin();
105                for ( ; it_group != ConsoleCommand::getCommands().end(); ++it_group)
106                    if (getLowercase(it_group->first) == groupLC)
107                        break;
108
109                if (it_group != ConsoleCommand::getCommands().end())
110                {
111                    for (std::map<std::string, ConsoleCommand*>::const_iterator it_command = it_group->second.begin(); it_command != it_group->second.end(); ++it_command)
112                        if (it_command->second->isActive() && it_command->second->hasAccess() && (!it_command->second->isHidden())^bOnlyShowHidden)
113                            commandList.push_back(ArgumentCompletionListElement(it_command->first, getLowercase(it_command->first)));
114                }
115
116                return commandList;
117            }
118        }
119
120        ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION(groupsandcommands)(const std::string& fragment)
121        {
122            return detail::_groupsandcommands(fragment, false);
123        }
124
125        ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION(subcommands)(const std::string& fragment, const std::string& group)
126        {
127            return detail::_subcommands(fragment, group, false);
128        }
129
130        ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION_MULTI(command)(const std::string& fragment)
131        {
132            CommandEvaluation evaluation = CommandExecutor::evaluate(fragment);
133            const std::string& hint = evaluation.hint();
134
135            if (evaluation.getPossibleArguments().size() > 0 && evaluation.getPossibleArgumentsSize() > 0)
136            {
137                return evaluation.getPossibleArguments();
138            }
139            else
140            {
141                ArgumentCompletionList list;
142                list.push_back(ArgumentCompletionListElement("", "", hint));
143                return list;
144            }
145        }
146
147        ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION_MULTI(hiddencommand)(const std::string& fragment)
148        {
149            SubString tokens(fragment, " ", SubString::WhiteSpaces, false, '\\', true, '"', true, '{', '}', true, '\0');
150
151            if (tokens.size() == 0)
152                return detail::_groupsandcommands(fragment, true);
153
154            if (ConsoleCommand::getCommandLC(getLowercase(tokens[0])))
155                return ARGUMENT_COMPLETION_FUNCTION_CALL(command)(fragment);
156
157            if (tokens.size() == 1)
158            {
159                std::map<std::string, std::map<std::string, ConsoleCommand*> >::const_iterator it_group = ConsoleCommand::getCommands().find(tokens[0]);
160                if (it_group != ConsoleCommand::getCommands().end())
161                    return detail::_subcommands(fragment, tokens[0], true);
162                else
163                    return detail::_groupsandcommands(fragment, true);
164            }
165
166            if (ConsoleCommand::getCommandLC(getLowercase(tokens[0]), getLowercase(tokens[1])))
167                return ARGUMENT_COMPLETION_FUNCTION_CALL(command)(fragment);
168
169            return ArgumentCompletionList();
170        }
171
172        ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION(files)(const std::string& fragment)
173        {
174            ArgumentCompletionList dirlist;
175            ArgumentCompletionList filelist;
176
177            try
178            {
179                boost::filesystem::path input(fragment);
180                boost::filesystem::path startdirectory(input.branch_path());
181
182                if (!boost::filesystem::exists(startdirectory))
183                {
184                    startdirectory = ".";
185                }
186#ifdef ORXONOX_PLATFORM_WINDOWS
187                else
188                {
189                    const std::string& dir = startdirectory.string();
190                    if (dir.size() > 0 && dir[dir.size() - 1] == ':')
191                        startdirectory = dir + '/';
192                }
193#endif
194
195                boost::filesystem::directory_iterator file(startdirectory);
196                boost::filesystem::directory_iterator end;
197
198                while (file != end)
199                {
200                    if (boost::filesystem::is_directory(*file))
201                        dirlist.push_back(ArgumentCompletionListElement(file->string() + '/', getLowercase(file->string()) + '/', file->BOOST_LEAF_FUNCTION() + '/'));
202                    else
203                        filelist.push_back(ArgumentCompletionListElement(file->string(), getLowercase(file->string()), file->BOOST_LEAF_FUNCTION()));
204                    ++file;
205                }
206            }
207            catch (...) {}
208
209            filelist.insert(filelist.begin(), dirlist.begin(), dirlist.end());
210            return filelist;
211        }
212
213        ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION(settingssections)()
214        {
215            ArgumentCompletionList sectionList;
216
217            const std::set<std::string>& names = SettingsConfigFile::getInstance().getSectionNames();
218            for (std::set<std::string>::const_iterator it = names.begin(); it != names.end(); ++it)
219                sectionList.push_back(ArgumentCompletionListElement(*it, getLowercase(*it)));
220
221            return sectionList;
222        }
223
224        ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION(settingsentries)(const std::string& fragment, const std::string& section)
225        {
226            ArgumentCompletionList entryList;
227            SettingsConfigFile& settings = SettingsConfigFile::getInstance();
228            const std::string& sectionLC = getLowercase(section);
229
230            SettingsConfigFile::ContainerMap::const_iterator upper = settings.getContainerUpperBound(sectionLC);
231            for (SettingsConfigFile::ContainerMap::const_iterator it = settings.getContainerLowerBound(sectionLC); it != upper; ++it)
232                entryList.push_back(ArgumentCompletionListElement(it->second.second->getName(), it->second.first));
233
234            return entryList;
235        }
236
237        ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION(settingsvalue)(const std::string& fragment, const std::string& entry, const std::string& section)
238        {
239            ArgumentCompletionList oldValue;
240            SettingsConfigFile& settings = SettingsConfigFile::getInstance();
241            const std::string& sectionLC = getLowercase(section);
242            const std::string& entryLC = getLowercase(entry);
243
244            SettingsConfigFile::ContainerMap::const_iterator upper = settings.getContainerUpperBound(sectionLC);
245            for (SettingsConfigFile::ContainerMap::const_iterator it = settings.getContainerLowerBound(sectionLC); it != upper; ++it)
246            {
247                if (it->second.first == entryLC)
248                {
249                    const std::string& valuestring = it->second.second->toString();
250                    oldValue.push_back(ArgumentCompletionListElement(valuestring, getLowercase(valuestring), "Old value: " + valuestring));
251                }
252            }
253
254            return oldValue;
255        }
256
257        ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION(tclthreads)()
258        {
259            std::list<unsigned int> threadnumbers = TclThreadManager::getInstance().getThreadList();
260            ArgumentCompletionList threads;
261
262            for (std::list<unsigned int>::const_iterator it = threadnumbers.begin(); it != threadnumbers.end(); ++it)
263                threads.push_back(ArgumentCompletionListElement(multi_cast<std::string>(*it)));
264
265            return threads;
266        }
267    }
268}
Note: See TracBrowser for help on using the repository browser.