]> git.xonotic.org Git - xonotic/netradiant.git/blob - radiant/help.cpp
Initial python support
[xonotic/netradiant.git] / radiant / help.cpp
1 /*
2    Copyright (C) 1999-2006 Id Software, Inc. and contributors.
3    For a list of contributors, see the accompanying CONTRIBUTORS file.
4
5    This file is part of GtkRadiant.
6
7    GtkRadiant is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11
12    GtkRadiant is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with GtkRadiant; if not, write to the Free Software
19    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20  */
21
22 #include "help.h"
23
24 #include "debugging/debugging.h"
25
26 #include <vector>
27 #include <list>
28
29 #include "libxml/parser.h"
30 #include "generic/callback.h"
31 #include "gtkutil/menu.h"
32 #include "stream/stringstream.h"
33 #include "os/file.h"
34
35 #include "url.h"
36 #include "preferences.h"
37 #include "mainframe.h"
38
39 /*!
40    the urls to fire up in the game packs help menus
41  */
42 namespace {
43     std::list<CopiedString> mHelpURLs;
44 }
45
46 /*!
47    needed for hooking in Gtk+
48  */
49 void HandleHelpCommand(CopiedString &str)
50 {
51     OpenURL(str.c_str());
52 }
53
54 void process_xlink(const char *filename, const char *menu_name, const char *base_url, ui::Menu menu)
55 {
56     if (file_exists(filename)) {
57         xmlDocPtr pDoc = xmlParseFile(filename);
58         if (pDoc) {
59             globalOutputStream() << "Processing .xlink file '" << filename << "'\n";
60             // create sub menu
61             auto menu_in_menu = create_sub_menu_with_mnemonic(menu, menu_name);
62             if (g_Layout_enableDetachableMenus.m_value) {
63                 menu_tearoff(menu_in_menu);
64             }
65             // start walking the nodes, find the 'links' one
66             xmlNodePtr pNode = pDoc->children;
67             while (pNode && strcmp((const char *) pNode->name, "links")) {
68                 pNode = pNode->next;
69             }
70             if (pNode) {
71                 pNode = pNode->children;
72                 while (pNode) {
73                     if (!strcmp((const char *) pNode->name, "item")) {
74                         // process the URL
75                         CopiedString url;
76
77                         xmlChar *prop = xmlGetProp(pNode, reinterpret_cast<const xmlChar *>( "url" ));
78                         ASSERT_NOTNULL(prop);
79                         if (strstr(reinterpret_cast<const char *>( prop ), "http://") ||
80                             strstr(reinterpret_cast<const char *>( prop ), "https://")) {
81                             // complete URL
82                             url = reinterpret_cast<const char *>( prop );
83                         } else {
84                             // relative URL
85                             StringOutputStream full(256);
86                             full << base_url << reinterpret_cast<const char *>( prop );
87                             url = full.c_str();
88                         }
89
90                         mHelpURLs.push_back(url);
91
92                         xmlFree(prop);
93
94                         prop = xmlGetProp(pNode, reinterpret_cast<const xmlChar *>( "name" ));
95                         ASSERT_NOTNULL(prop);
96                         create_menu_item_with_mnemonic(menu_in_menu, reinterpret_cast<const char *>( prop ),
97                                                        ReferenceCaller<CopiedString, void(), HandleHelpCommand>(
98                                                                mHelpURLs.back()));
99                         xmlFree(prop);
100                     }
101                     pNode = pNode->next;
102                 }
103             }
104             xmlFreeDoc(pDoc);
105         } else {
106             globalOutputStream() << "'" << filename << "' parse failed\n";
107         }
108     } else {
109         globalOutputStream() << "'" << filename << "' not found\n";
110     }
111 }
112
113 void create_game_help_menu(ui::Menu menu)
114 {
115     StringOutputStream filename(256);
116     filename << AppPath_get() << "global.xlink";
117     process_xlink(filename.c_str(), "General", AppPath_get(), menu);
118
119 #if 1
120     filename.clear();
121     filename << g_pGameDescription->mGameToolsPath.c_str() << "game.xlink";
122     process_xlink(filename.c_str(), g_pGameDescription->getRequiredKeyValue("name"),
123                   g_pGameDescription->mGameToolsPath.c_str(), menu);
124 #else
125     for ( std::list<CGameDescription *>::iterator iGame = g_GamesDialog.mGames.begin(); iGame != g_GamesDialog.mGames.end(); ++iGame )
126     {
127         filename.clear();
128         filename << ( *iGame )->mGameToolsPath.c_str() << "game.xlink";
129         process_xlink( filename.c_str(), ( *iGame )->getRequiredKeyValue( "name" ), ( *iGame )->mGameToolsPath.c_str(), menu );
130     }
131 #endif
132 }