1 /*
2 * The ManaPlus Client
3 * Copyright (C) 2004-2009 The Mana World Development Team
4 * Copyright (C) 2009-2010 The Mana Developers
5 * Copyright (C) 2011-2019 The ManaPlus Developers
6 * Copyright (C) 2019-2021 Andrei Karas
7 *
8 * This file is part of The ManaPlus Client.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program. If not, see <http://www.gnu.org/licenses/>.
22 */
23
24 #include "gui/windows/helpwindow.h"
25
26 #include "configuration.h"
27
28 #include "enums/gui/layouttype.h"
29
30 #include "fs/paths.h"
31
32 #include "fs/virtfs/tools.h"
33
34 #include "gui/gui.h"
35
36 #include "gui/windows/setupwindow.h"
37
38 #include "gui/widgets/button.h"
39 #include "gui/widgets/staticbrowserbox.h"
40 #include "gui/widgets/layout.h"
41 #include "gui/widgets/scrollarea.h"
42
43 #include "input/inputmanager.h"
44
45 #include "utils/foreach.h"
46 #include "utils/gettext.h"
47 #include "utils/process.h"
48
49 #include "utils/translation/podict.h"
50 #include "utils/translation/translationmanager.h"
51
52 #include "debug.h"
53
54 HelpWindow *helpWindow = nullptr;
55
HelpWindow()56 HelpWindow::HelpWindow() :
57 // TRANSLATORS: help window name
58 Window(_("Help"), Modal_false, nullptr, "help.xml"),
59 LinkHandler(),
60 ActionListener(),
61 // TRANSLATORS: help window. button.
62 mDYKButton(new Button(this, _("Did you know..."), "DYK",
63 BUTTON_SKIN, this)),
64 mBrowserBox(new StaticBrowserBox(this, Opaque_true,
65 "browserbox.xml")),
66 mScrollArea(new ScrollArea(this, mBrowserBox,
67 Opaque_true, "help_background.xml")),
68 mTagFileMap()
69 {
70 setMinWidth(300);
71 setMinHeight(220);
72 setContentSize(455, 350);
73 setWindowName("Help");
74 setCloseButton(true);
75 setResizable(true);
76 setStickyButtonLock(true);
77
78 if (setupWindow != nullptr)
79 setupWindow->registerWindowForReset(this);
80
81 setDefaultSize(500, 400, ImagePosition::CENTER, 0, 0);
82
83 mBrowserBox->setOpaque(Opaque_false);
84
85 mBrowserBox->setLinkHandler(this);
86 if (gui != nullptr)
87 mBrowserBox->setFont(gui->getHelpFont());
88 mBrowserBox->setProcessVars(true);
89 mBrowserBox->setEnableImages(true);
90 mBrowserBox->setEnableKeys(true);
91 mBrowserBox->setEnableTabs(true);
92
93 place(4, 3, mDYKButton, 1, 1);
94 place(0, 0, mScrollArea, 5, 3).setPadding(3);
95
96 Layout &layout = getLayout();
97 layout.setRowHeight(0, LayoutType::SET);
98
99 loadWindowState();
100 loadTags();
101 enableVisibleSound(true);
102 widgetResized(Event(nullptr));
103 }
104
action(const ActionEvent & event)105 void HelpWindow::action(const ActionEvent &event)
106 {
107 if (event.getId() == "DYK")
108 inputManager.executeAction(InputAction::WINDOW_DIDYOUKNOW);
109 }
110
handleLink(const std::string & link,MouseEvent * const event A_UNUSED)111 void HelpWindow::handleLink(const std::string &link,
112 MouseEvent *const event A_UNUSED)
113 {
114 if (!strStartWith(link, "http://") && !strStartWith(link, "https://"))
115 {
116 // need use separate variable
117 const std::string helpFile = link; // NOLINT
118 loadHelp(helpFile);
119 }
120 else
121 {
122 openBrowser(link);
123 }
124 }
125
loadHelp(const std::string & helpFile)126 void HelpWindow::loadHelp(const std::string &helpFile)
127 {
128 if (!checkPath(helpFile))
129 return;
130 mBrowserBox->clearRows();
131 loadFile("header");
132 loadFile(helpFile);
133 loadFile("footer");
134 mScrollArea->setVerticalScrollAmount(0);
135 mBrowserBox->updateHeight();
136 setVisible(Visible_true);
137 }
138
loadHelpSimple(const std::string & helpFile)139 void HelpWindow::loadHelpSimple(const std::string &helpFile)
140 {
141 if (!checkPath(helpFile))
142 return;
143 mBrowserBox->clearRows();
144 loadFile(helpFile);
145 mScrollArea->setVerticalScrollAmount(0);
146 mBrowserBox->updateHeight();
147 setVisible(Visible_true);
148 }
149
loadFile(std::string file)150 void HelpWindow::loadFile(std::string file)
151 {
152 trim(file);
153 std::string helpPath = branding.getStringValue("helpPath");
154 if (helpPath.empty())
155 helpPath = paths.getStringValue("help");
156
157 StringVect lines;
158 TranslationManager::translateFile(pathJoin(helpPath, file).append(".txt"),
159 translator, lines);
160
161 for (size_t i = 0, sz = lines.size(); i < sz; ++i)
162 mBrowserBox->addRow(lines[i], false);
163 }
164
loadTags()165 void HelpWindow::loadTags()
166 {
167 std::string helpPath = branding.getStringValue("tagsPath");
168 if (helpPath.empty())
169 helpPath = paths.getStringValue("tags");
170
171 StringVect filesVect;
172 VirtFs::getFilesInDir(helpPath, filesVect, ".idx");
173 FOR_EACH (StringVectCIter, itVect, filesVect)
174 {
175 StringVect lines;
176 VirtFs::loadTextFile(*itVect, lines);
177 FOR_EACH (StringVectCIter, it, lines)
178 {
179 const std::string &str = *it;
180 const size_t idx = str.find('|');
181 if (idx != std::string::npos)
182 mTagFileMap[str.substr(idx + 1)].insert(str.substr(0, idx));
183 }
184 }
185 }
186
search(const std::string & text0)187 void HelpWindow::search(const std::string &text0)
188 {
189 std::string text = text0;
190 trim(text);
191 toLower(text);
192 if (mTagFileMap.find(text) == mTagFileMap.end())
193 {
194 loadHelp("searchnotfound");
195 }
196 else
197 {
198 const HelpNames &names = mTagFileMap[text];
199 if (names.size() == 1)
200 {
201 loadHelp(*names.begin());
202 }
203 else
204 {
205 if (translator == nullptr)
206 return;
207 mBrowserBox->clearRows();
208 loadFile("header");
209 loadFile("searchmany");
210 FOR_EACH (HelpNamesCIter, it, names)
211 {
212 const char *const str = (*it).c_str();
213 mBrowserBox->addRow(strprintf(" -> @@%s|%s@@", str,
214 translator->getChar(str)),
215 false);
216 }
217 loadFile("footer");
218 mScrollArea->setVerticalScrollAmount(0);
219 mBrowserBox->updateHeight();
220 setVisible(Visible_true);
221 }
222 }
223 }
224