integrated x86_64 patch from LordHavoc
[xonotic/netradiant.git] / radiant / findtexturedialog.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 //
23 // Find/Replace textures dialogs
24 //
25 // Leonardo Zide (leo@lokigames.com)
26 //
27
28 #include "findtexturedialog.h"
29
30 #include "debugging/debugging.h"
31
32 #include "ishaders.h"
33
34 #include <gtk/gtkhbox.h>
35 #include <gtk/gtkentry.h>
36 #include <gtk/gtkvbox.h>
37 #include <gtk/gtkframe.h>
38 #include <gtk/gtklabel.h>
39 #include <gtk/gtktable.h>
40 #include <gtk/gtkbutton.h>
41 #include <gtk/gtktogglebutton.h>
42 #include <gtk/gtkcheckbutton.h>
43 #include <gtk/gtkmenuitem.h>
44 #include <gtk/gtkarrow.h>
45
46 #include "gtkutil/window.h"
47 #include "stream/stringstream.h"
48
49 #include "commands.h"
50 #include "dialog.h"
51 #include "select.h"
52 #include "textureentry.h"
53
54
55
56 class FindTextureDialog : public Dialog
57 {
58  public:
59   static void setReplaceStr(const char* name);
60   static void setFindStr(const char* name);
61   static bool isOpen();
62   static void show();
63   typedef FreeCaller<&FindTextureDialog::show> ShowCaller;
64   static void updateTextures(const char* name);
65
66   FindTextureDialog();
67   virtual ~FindTextureDialog();
68   GtkWindow* BuildDialog();
69
70   void constructWindow(GtkWindow* parent)
71   {
72     m_parent = parent;
73     Create();
74   }
75   void destroyWindow()
76   {
77     Destroy();
78   }
79
80
81   bool m_bSelectedOnly;
82   CopiedString m_strFind;
83   CopiedString m_strReplace;
84 };
85
86 FindTextureDialog g_FindTextureDialog;
87 static bool g_bFindActive = true;
88
89 namespace
90 {
91   void FindTextureDialog_apply()
92   {
93     StringOutputStream find(256);
94     find << "textures/" << g_FindTextureDialog.m_strFind.c_str();
95     StringOutputStream replace(256);
96     replace << "textures/" << g_FindTextureDialog.m_strReplace.c_str();
97     FindReplaceTextures(find.c_str(), replace.c_str(), g_FindTextureDialog.m_bSelectedOnly);
98   }
99
100   static void OnApply(GtkWidget* widget, gpointer data) 
101   {
102     g_FindTextureDialog.exportData();
103     FindTextureDialog_apply();
104   }
105
106   static void OnFind(GtkWidget* widget, gpointer data) 
107   {
108     g_FindTextureDialog.exportData();
109     FindTextureDialog_apply();
110   }
111
112   static void OnOK(GtkWidget* widget, gpointer data) 
113   {
114     g_FindTextureDialog.exportData();
115     FindTextureDialog_apply();
116     g_FindTextureDialog.HideDlg();
117   }
118
119   static void OnClose(GtkWidget* widget, gpointer data) 
120   {
121     g_FindTextureDialog.HideDlg();
122   }
123
124
125   static gint find_focus_in (GtkWidget* widget, GdkEventFocus *event, gpointer data)
126   {
127     g_bFindActive = true;
128     return FALSE;
129   }
130
131   static gint replace_focus_in (GtkWidget* widget, GdkEventFocus *event, gpointer data)
132   {
133     g_bFindActive = false;
134     return FALSE;
135   }
136 }
137
138 // =============================================================================
139 // FindTextureDialog class
140
141 FindTextureDialog::FindTextureDialog()
142 {
143   m_bSelectedOnly = FALSE;
144 }
145
146 FindTextureDialog::~FindTextureDialog()
147 {
148 }
149
150 GtkWindow* FindTextureDialog::BuildDialog()
151 {
152   GtkWidget* vbox, *hbox, *table, *label;
153   GtkWidget* button, *check, *entry;
154
155   GtkWindow* dlg = create_floating_window("Find / Replace Texture(s)", m_parent);
156
157   hbox = gtk_hbox_new (FALSE, 5);
158   gtk_widget_show (hbox);
159   gtk_container_add(GTK_CONTAINER(dlg), GTK_WIDGET(hbox));
160   gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
161
162   vbox = gtk_vbox_new (FALSE, 5);
163   gtk_widget_show (vbox);
164   gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(vbox), TRUE, TRUE, 0);
165
166   table = gtk_table_new (2, 2, FALSE);
167   gtk_widget_show (table);
168   gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET(table), TRUE, TRUE, 0);
169   gtk_table_set_row_spacings (GTK_TABLE (table), 5);
170   gtk_table_set_col_spacings (GTK_TABLE (table), 5);
171
172   label = gtk_label_new ("Find:");
173   gtk_widget_show (label);
174   gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1,
175                     (GtkAttachOptions) (GTK_FILL),
176                     (GtkAttachOptions) (0), 0, 0);
177   gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
178
179   label = gtk_label_new ("Replace:");
180   gtk_widget_show (label);
181   gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2,
182                     (GtkAttachOptions) (GTK_FILL),
183                     (GtkAttachOptions) (0), 0, 0);
184   gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
185
186   entry = gtk_entry_new();
187   gtk_widget_show (entry);
188   gtk_table_attach (GTK_TABLE (table), entry, 1, 2, 0, 1,
189                     (GtkAttachOptions) (GTK_EXPAND|GTK_FILL),
190                     (GtkAttachOptions) (0), 0, 0);
191   g_signal_connect(G_OBJECT(entry), "focus_in_event",
192                       G_CALLBACK(find_focus_in), 0);
193   AddDialogData(*GTK_ENTRY(entry), m_strFind);
194   GlobalTextureEntryCompletion::instance().connect(GTK_ENTRY(entry));
195
196   entry = gtk_entry_new();
197   gtk_widget_show (entry);
198   gtk_table_attach (GTK_TABLE (table), entry, 1, 2, 1, 2,
199                     (GtkAttachOptions) (GTK_EXPAND|GTK_FILL),
200                     (GtkAttachOptions) (0), 0, 0);
201   g_signal_connect(G_OBJECT(entry), "focus_in_event",
202                       G_CALLBACK(replace_focus_in), 0);
203   AddDialogData(*GTK_ENTRY(entry), m_strReplace);
204   GlobalTextureEntryCompletion::instance().connect(GTK_ENTRY(entry));
205
206   check = gtk_check_button_new_with_label ("Within selected brushes only");
207   gtk_widget_show (check);
208   gtk_box_pack_start(GTK_BOX(vbox), check, TRUE, TRUE, 0);
209   AddDialogData(*GTK_TOGGLE_BUTTON(check), m_bSelectedOnly);
210
211   vbox = gtk_vbox_new (FALSE, 5);
212   gtk_widget_show (vbox);
213   gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(vbox), FALSE, FALSE, 0);
214
215   button = gtk_button_new_with_label ("Apply");
216   gtk_widget_show (button);
217   gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0);
218   g_signal_connect(G_OBJECT(button), "clicked",
219                       G_CALLBACK(OnApply), 0);
220   gtk_widget_set_usize (button, 60, -2);
221
222   button = gtk_button_new_with_label ("Close");
223   gtk_widget_show (button);
224   gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0);
225   g_signal_connect(G_OBJECT(button), "clicked",
226                       G_CALLBACK(OnClose), 0);
227   gtk_widget_set_usize (button, 60, -2);
228
229   return dlg;
230 }
231
232 void FindTextureDialog::updateTextures(const char* name)
233 {
234   if (isOpen())
235   {
236     if (g_bFindActive)
237     {
238       setFindStr(name + 9);
239     }
240     else
241     {
242       setReplaceStr(name + 9);
243     }
244   }
245 }
246
247 bool FindTextureDialog::isOpen()
248 {
249   return GTK_WIDGET_VISIBLE(g_FindTextureDialog.GetWidget()) == TRUE;
250 }
251
252 void FindTextureDialog::setFindStr(const char* name)
253 {
254   g_FindTextureDialog.exportData();
255   g_FindTextureDialog.m_strFind = name;
256   g_FindTextureDialog.importData();
257 }
258
259 void FindTextureDialog::setReplaceStr(const char* name)
260 {
261   g_FindTextureDialog.exportData();
262   g_FindTextureDialog.m_strReplace = name;
263   g_FindTextureDialog.importData();
264 }
265
266 void FindTextureDialog::show()
267 {
268   g_FindTextureDialog.ShowDlg();
269 }
270
271
272 void FindTextureDialog_constructWindow(GtkWindow* main_window)
273 {
274   g_FindTextureDialog.constructWindow(main_window);
275 }
276
277 void FindTextureDialog_destroyWindow()
278 {
279   g_FindTextureDialog.destroyWindow();
280 }
281
282 bool FindTextureDialog_isOpen()
283 {
284   return g_FindTextureDialog.isOpen();
285 }
286
287 void FindTextureDialog_selectTexture(const char* name)
288 {
289   g_FindTextureDialog.updateTextures(name);
290 }
291
292 void FindTextureDialog_Construct()
293 {
294   GlobalCommands_insert("FindReplaceTextures", FindTextureDialog::ShowCaller());
295 }
296
297 void FindTextureDialog_Destroy()
298 {
299 }
300