Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 255 lines (215 sloc) 5.91 kB
0991a5c @tbradshaw The GtkRadiant sources as originally released under the GPL license.
tbradshaw authored
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 "mru.h"
23
24 #include <string.h>
25 #include <stdio.h>
26 #include <gtk/gtklabel.h>
27
28 #include "os/file.h"
29 #include "generic/callback.h"
30 #include "stream/stringstream.h"
31 #include "convert.h"
32
33 #include "gtkutil/menu.h"
34 #include "map.h"
35 #include "qe3.h"
36
37 #define MRU_MAX 4
38 namespace {
39 GtkMenuItem *MRU_items[MRU_MAX];
40 std::size_t MRU_used;
41 typedef CopiedString MRU_filename_t;
42 MRU_filename_t MRU_filenames[MRU_MAX];
43 typedef const char* MRU_key_t;
44 MRU_key_t MRU_keys[MRU_MAX] = { "File0", "File1", "File2", "File3" };
45 }
46
47 inline const char* MRU_GetText(std::size_t index)
48 {
49 return MRU_filenames[index].c_str();
50 }
51
52 class EscapedMnemonic
53 {
54 StringBuffer m_buffer;
55 public:
56 EscapedMnemonic(std::size_t capacity) : m_buffer(capacity)
57 {
58 m_buffer.push_back('_');
59 }
60 const char* c_str() const
61 {
62 return m_buffer.c_str();
63 }
64 void push_back(char c) // not escaped
65 {
66 m_buffer.push_back(c);
67 }
68 std::size_t write(const char* buffer, std::size_t length)
69 {
70 for(const char* end = buffer + length; buffer != end; ++buffer)
71 {
72 if(*buffer == '_')
73 {
74 m_buffer.push_back('_');
75 }
76
77 m_buffer.push_back(*buffer);
78 }
79 return length;
80 }
81 };
82
83 template<typename T>
84 inline EscapedMnemonic& operator<<(EscapedMnemonic& ostream, const T& t)
85 {
86 return ostream_write(ostream, t);
87 }
88
89
90 void MRU_updateWidget(std::size_t index, const char *filename)
91 {
92 EscapedMnemonic mnemonic(64);
93 mnemonic.push_back('_');
94 mnemonic << Unsigned(index + 1) << "- " << ConvertLocaleToUTF8(filename);
95 gtk_label_set_text_with_mnemonic(GTK_LABEL(gtk_bin_get_child(GTK_BIN(MRU_items[index]))), mnemonic.c_str());
96 }
97
98 void MRU_SetText(std::size_t index, const char *filename)
99 {
100 MRU_filenames[index] = filename;
101 MRU_updateWidget(index, filename);
102 }
103
104 void MRU_AddFile (const char *str)
105 {
106 std::size_t i;
107 const char* text;
108
109 // check if file is already in our list
110 for (i = 0; i < MRU_used; i++)
111 {
112 text = MRU_GetText (i);
113
114 if (strcmp (text, str) == 0)
115 {
116 // reorder menu
117 for(; i > 0; i--)
118 MRU_SetText(i, MRU_GetText (i-1));
119
120 MRU_SetText(0, str);
121
122 return;
123 }
124 }
125
126 if (MRU_used < MRU_MAX)
127 MRU_used++;
128
129 // move items down
130 for (i = MRU_used-1; i > 0; i--)
131 MRU_SetText (i, MRU_GetText (i-1));
132
133 MRU_SetText (0, str);
134 gtk_widget_set_sensitive(GTK_WIDGET(MRU_items[0]), TRUE);
135 gtk_widget_show(GTK_WIDGET(MRU_items[MRU_used-1]));
136 }
137
138 void MRU_Init()
139 {
140 if(MRU_used > MRU_MAX)
141 MRU_used = MRU_MAX;
142 }
143
144 void MRU_AddWidget(GtkMenuItem *widget, std::size_t pos)
145 {
146 if(pos < MRU_MAX)
147 {
148 MRU_items[pos] = widget;
149 if(pos < MRU_used)
150 {
151 MRU_updateWidget(pos, MRU_GetText(pos));
152 gtk_widget_set_sensitive(GTK_WIDGET(MRU_items[0]), TRUE);
153 gtk_widget_show(GTK_WIDGET(MRU_items[pos]));
154 }
155 }
156 }
157
158 void MRU_Activate (std::size_t index)
159 {
160 char text[1024];
161 strcpy(text, MRU_GetText(index));
162
163 if (file_readable(text)) //\todo Test 'map load succeeds' instead of 'file is readable'.
164 {
165 MRU_AddFile (text);
166 Map_RegionOff();
167 Map_Free();
168 Map_LoadFile (text);
169 }
170 else
171 {
172 MRU_used--;
173
174 for (std::size_t i = index; i < MRU_used; i++)
175 MRU_SetText (i, MRU_GetText (i+1));
176
177 if (MRU_used == 0)
178 {
179 gtk_label_set_text(GTK_LABEL(GTK_BIN(MRU_items[0])->child), "Recent Files");
180 gtk_widget_set_sensitive(GTK_WIDGET(MRU_items[0]), FALSE);
181 }
182 else
183 {
184 gtk_widget_hide(GTK_WIDGET(MRU_items[MRU_used]));
185 }
186 }
187 }
188
189
190 class LoadMRU
191 {
192 std::size_t m_number;
193 public:
194 LoadMRU(std::size_t number)
195 : m_number(number)
196 {
197 }
198 void load()
199 {
200 if (ConfirmModified("Open Map"))
201 {
202 MRU_Activate(m_number - 1);
203 }
204 }
205 };
206
207 typedef MemberCaller<LoadMRU, &LoadMRU::load> LoadMRUCaller;
208
209 LoadMRU g_load_mru1(1);
210 LoadMRU g_load_mru2(2);
211 LoadMRU g_load_mru3(3);
212 LoadMRU g_load_mru4(4);
213
214 void MRU_constructMenu(GtkMenu* menu)
215 {
216 {
217 GtkMenuItem* item = create_menu_item_with_mnemonic(menu, "Recent Files", LoadMRUCaller(g_load_mru1));
218 gtk_widget_set_sensitive(GTK_WIDGET(item), FALSE);
219 MRU_AddWidget(item, 0);
220 }
221 {
222 GtkMenuItem* item = create_menu_item_with_mnemonic(menu, "2", LoadMRUCaller(g_load_mru2));
223 gtk_widget_hide(GTK_WIDGET(item));
224 MRU_AddWidget(item, 1);
225 }
226 {
227 GtkMenuItem* item = create_menu_item_with_mnemonic(menu, "3", LoadMRUCaller(g_load_mru3));
228 gtk_widget_hide(GTK_WIDGET(item));
229 MRU_AddWidget(item, 2);
230 }
231 {
232 GtkMenuItem* item = create_menu_item_with_mnemonic(menu, "4", LoadMRUCaller(g_load_mru4));
233 gtk_widget_hide(GTK_WIDGET(item));
234 MRU_AddWidget(item, 3);
235 }
236 }
237
238 #include "preferencesystem.h"
239 #include "stringio.h"
240
241 void MRU_Construct()
242 {
243 GlobalPreferenceSystem().registerPreference("Count", SizeImportStringCaller(MRU_used), SizeExportStringCaller(MRU_used));
244
245 for(std::size_t i = 0; i != MRU_MAX; ++i)
246 {
247 GlobalPreferenceSystem().registerPreference(MRU_keys[i], CopiedStringImportStringCaller(MRU_filenames[i]), CopiedStringExportStringCaller(MRU_filenames[i]));
248 }
249
250 MRU_Init();
251 }
252 void MRU_Destroy()
253 {
254 }
Something went wrong with that request. Please try again.