/
MRU.cpp
263 lines (212 loc) · 6.17 KB
/
MRU.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
#include "MRU.h"
#include "i18n.h"
#include "ieventmanager.h"
#include "imainframe.h"
#include "icommandsystem.h"
#include "ipreferencesystem.h"
#include "iuimanager.h"
#include "string/string.h"
#include "os/file.h"
#include "registry/registry.h"
#include "wxutil/dialog/MessageBox.h"
#include "wxutil/IConv.h"
#include <wx/menuitem.h>
#include "map/Map.h"
namespace ui {
namespace {
const std::string RKEY_MAP_ROOT = "user/ui/map";
const std::string RKEY_MAP_MRUS = RKEY_MAP_ROOT + "/MRU";
const std::string RKEY_MRU_LENGTH = RKEY_MAP_ROOT + "/numMRU";
const std::string RKEY_LOAD_LAST_MAP = RKEY_MAP_ROOT + "/loadLastMap";
const char* const RECENT_FILES_CAPTION = N_("Recently used Maps");
}
MRU::MRU() :
_numMaxFiles(registry::getValue<int>(RKEY_MRU_LENGTH)),
_loadLastMap(registry::getValue<bool>(RKEY_LOAD_LAST_MAP)),
_list(_numMaxFiles),
_emptyMenuItem(_(RECENT_FILES_CAPTION), *this, 0)
{
GlobalRegistry().signalForKey(RKEY_MRU_LENGTH).connect(
sigc::mem_fun(this, &MRU::keyChanged)
);
// Add the preference settings
constructPreferences();
// Create _numMaxFiles menu items
for (unsigned int i = 0; i < _numMaxFiles; i++) {
_menuItems.push_back(MRUMenuItem(string::to_string(i), *this, i+1));
MRUMenuItem& item = (*_menuItems.rbegin());
const std::string commandName = std::string("MRUOpen") + string::to_string(i+1);
// Connect the command to the last inserted menuItem
GlobalCommandSystem().addCommand(
commandName,
std::bind(&MRUMenuItem::activate, &item, std::placeholders::_1)
);
GlobalEventManager().addCommand(commandName, commandName);
}
}
void MRU::loadRecentFiles()
{
// Loads the registry values from the last to the first (recentMap4 ... recentMap1) and
// inserts them. After everything is loaded, the file list is sorted correctly.
for (std::size_t i = _numMaxFiles; i > 0; i--)
{
const std::string key = RKEY_MAP_MRUS + "/map" + string::to_string(i);
const std::string fileName = GlobalRegistry().get(key);
// Insert the filename
insert(fileName);
}
}
void MRU::saveRecentFiles()
{
// Delete all existing MRU/element nodes
GlobalRegistry().deleteXPath(RKEY_MAP_MRUS);
std::size_t counter = 1;
// Now wade through the list and save them in the correct order
for (MRUList::const_iterator i = _list.begin(); i != _list.end(); ++counter, ++i)
{
const std::string key = RKEY_MAP_MRUS + "/map" + string::to_string(counter);
// Save the string into the registry
GlobalRegistry().set(key, (*i));
}
}
void MRU::loadMap(const std::string& fileName)
{
if (GlobalMap().askForSave(_("Open Map")))
{
if (os::fileIsReadable(fileName))
{
// Shut down the current map
GlobalMap().freeMap();
// Load the file
GlobalMap().load(fileName);
// Update the MRU list with this file
insert(fileName);
}
else
{
wxutil::Messagebox::ShowError(
(boost::format(_("Could not read map file: %s")) % fileName).str());
}
}
}
void MRU::keyChanged()
{
// greebo: Don't load the new number of maximum files from the registry,
// this would mess up the existing widgets, wait for the DarkRadiant restart instead
//_numMaxFiles = registry::getValue<int>(RKEY_MRU_LENGTH);
_loadLastMap = registry::getValue<bool>(RKEY_LOAD_LAST_MAP);
}
// Construct the MRU preference page and add it to the given group
void MRU::constructPreferences()
{
IPreferencePage& page = GlobalPreferenceSystem().getPage(_("Settings/Map Files"));
page.appendEntry(_("Number of most recently used files"), RKEY_MRU_LENGTH);
page.appendCheckBox(_("Open last map on startup"), RKEY_LOAD_LAST_MAP);
}
void MRU::initialise()
{
// Construct the MRU commands and menu structure
constructMenu();
// Initialise the most recently used files list
loadRecentFiles();
updateMenu();
}
bool MRU::loadLastMap() const {
return _loadLastMap;
}
std::string MRU::getLastMapName()
{
if (_list.empty())
{
return "";
}
return *_list.begin();
}
void MRU::insert(const std::string& fileName) {
if (!fileName.empty())
{
// Insert the item into the filelist
_list.insert(fileName);
// Update the widgets
updateMenu();
}
}
void MRU::updateMenu()
{
// Get the menumanager
IMenuManager& menuManager = GlobalUIManager().getMenuManager();
for (std::size_t i = _numMaxFiles; i > 0; i--)
{
menuManager.remove("main/file/MRU" + string::to_string(i));
}
menuManager.remove("main/file/mruempty");
if (_list.empty())
{
// Create the "empty" MRU menu item (the desensitised one)
menuManager.insert(
"main/file/mruseparator",
"mruempty",
ui::menuItem,
RECENT_FILES_CAPTION,
"", // empty icon
"" // empty event
);
}
else
{
// Set the iterator to the first filename in the list
MRUList::iterator i = _list.begin();
// Add all the created widgets to the menu
for (MenuItems::iterator m = _menuItems.begin(); m != _menuItems.end(); ++m)
{
// The default string to be loaded into the widget (i.e. "inactive")
std::string filename = "";
// If the end of the list is reached, do nothing, otherwise increase the iterator
if (i != _list.end())
{
filename = (*i);
i++;
}
if (filename.empty())
{
continue;
}
MRUMenuItem& item = (*m);
std::string label = string::to_string(m->getIndex()) + " - " + filename;
const std::string commandName = std::string("MRUOpen") + string::to_string(item.getIndex());
// Create the toplevel menu item
menuManager.insert(
"main/file/mruseparator",
"MRU" + string::to_string(item.getIndex()),
ui::menuItem,
label,
"", // empty icon
commandName
);
item.setMapFilename(filename);
}
}
}
void MRU::constructMenu()
{
// Get the menumanager
IMenuManager& menuManager = GlobalUIManager().getMenuManager();
// Insert the last separator to split the MRU file list from the "Exit" command.
menuManager.insert(
"main/file/exit",
"mruseparator",
ui::menuSeparator,
"", // empty caption
"", // empty icon
"" // empty command
);
// Call the update routine to load the values into the widgets
updateMenu();
}
// -------------------------------------------------------------------------------------
} // namespace ui
// The accessor function to the MRU instance
ui::MRU& GlobalMRU() {
static ui::MRU _mruInstance;
return _mruInstance;
}