]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - radiant/findtexturedialog.cpp
Merge branch 'master' into master-merge
[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 <gtk/gtk.h>
31
32 #include "debugging/debugging.h"
33
34 #include "ishaders.h"
35
36 #include "gtkutil/window.h"
37 #include "stream/stringstream.h"
38
39 #include "commands.h"
40 #include "dialog.h"
41 #include "select.h"
42 #include "textureentry.h"
43
44
45
46 class FindTextureDialog : public Dialog
47 {
48 public:
49 WindowPositionTracker m_position_tracker;
50 static void setReplaceStr( const char* name );
51 static void setFindStr( const char* name );
52 static bool isOpen();
53 static void show();
54 typedef FreeCaller<void(), &FindTextureDialog::show> ShowCaller;
55 static void updateTextures( const char* name );
56
57 FindTextureDialog();
58 virtual ~FindTextureDialog();
59 ui::Window BuildDialog();
60
61 void constructWindow( ui::Window parent ){
62         m_parent = parent;
63         Create();
64 }
65 void destroyWindow(){
66         Destroy();
67 }
68
69
70 bool m_bSelectedOnly;
71 CopiedString m_strFind;
72 CopiedString m_strReplace;
73 };
74
75 FindTextureDialog g_FindTextureDialog;
76 static bool g_bFindActive = true;
77
78 namespace
79 {
80 void FindTextureDialog_apply(){
81         StringOutputStream find( 256 );
82         StringOutputStream replace( 256 );
83
84         find << "textures/" << g_FindTextureDialog.m_strFind.c_str();
85         replace << "textures/" << g_FindTextureDialog.m_strReplace.c_str();
86         FindReplaceTextures( find.c_str(), replace.c_str(), g_FindTextureDialog.m_bSelectedOnly );
87 }
88
89 static void OnApply( ui::Widget widget, gpointer data ){
90         g_FindTextureDialog.exportData();
91         FindTextureDialog_apply();
92 }
93
94 static void OnFind( ui::Widget widget, gpointer data ){
95         g_FindTextureDialog.exportData();
96         FindTextureDialog_apply();
97 }
98
99 static void OnOK( ui::Widget widget, gpointer data ){
100         g_FindTextureDialog.exportData();
101         FindTextureDialog_apply();
102         g_FindTextureDialog.HideDlg();
103 }
104
105 static void OnClose( ui::Widget widget, gpointer data ){
106         g_FindTextureDialog.HideDlg();
107 }
108
109
110 static gint find_focus_in( ui::Widget widget, GdkEventFocus *event, gpointer data ){
111         g_bFindActive = true;
112         return FALSE;
113 }
114
115 static gint replace_focus_in( ui::Widget widget, GdkEventFocus *event, gpointer data ){
116         g_bFindActive = false;
117         return FALSE;
118 }
119 }
120
121 // =============================================================================
122 // FindTextureDialog class
123
124 FindTextureDialog::FindTextureDialog(){
125         m_bSelectedOnly = FALSE;
126         m_position_tracker.setPosition( WindowPosition( -1, -1, 0, 0 ) );
127 }
128
129 FindTextureDialog::~FindTextureDialog(){
130 }
131
132 ui::Window FindTextureDialog::BuildDialog(){
133     ui::Widget label{ui::null};
134         ui::Widget button{ui::null};
135         ui::Entry entry{ui::null};
136
137         auto dlg = ui::Window(create_floating_window( "Find / Replace Texture(s)", m_parent ));
138
139         m_position_tracker.connect( dlg );
140
141         auto hbox = ui::HBox( FALSE, 5 );
142         hbox.show();
143         dlg.add(hbox);
144         gtk_container_set_border_width( GTK_CONTAINER( hbox ), 5 );
145
146         auto vbox = ui::VBox( FALSE, 5 );
147         vbox.show();
148         hbox.pack_start( vbox, TRUE, TRUE, 0 );
149
150     auto table = ui::Table(2, 2, FALSE);
151         table.show();
152         vbox.pack_start( table, TRUE, TRUE, 0 );
153     gtk_table_set_row_spacings(table, 5);
154     gtk_table_set_col_spacings(table, 5);
155
156         label = ui::Label( "Find:" );
157         label.show();
158     table.attach(label, {0, 1, 0, 1}, {GTK_FILL, 0});
159         gtk_misc_set_alignment( GTK_MISC( label ), 0, 0.5 );
160
161         label = ui::Label( "Replace:*" );
162         gtk_widget_set_tooltip_text( label, "Empty = search mode" );
163         label.show();
164     table.attach(label, {0, 1, 1, 2}, {GTK_FILL, 0});
165         gtk_misc_set_alignment( GTK_MISC( label ), 0, 0.5 );
166
167         entry = ui::Entry(ui::New);
168         entry.show();
169     table.attach(entry, {1, 2, 0, 1}, {GTK_EXPAND | GTK_FILL, 0});
170         entry.connect( "focus_in_event",
171                                           G_CALLBACK( find_focus_in ), 0 );
172         AddDialogData( entry, m_strFind );
173         GlobalTextureEntryCompletion::instance().connect( entry );
174
175         entry = ui::Entry(ui::New);
176         gtk_widget_set_tooltip_text( entry, "Empty = search mode" );
177         entry.show();
178     table.attach(entry, {1, 2, 1, 2}, {GTK_EXPAND | GTK_FILL, 0});
179         entry.connect( "focus_in_event",
180                                           G_CALLBACK( replace_focus_in ), 0 );
181         AddDialogData( entry, m_strReplace );
182         GlobalTextureEntryCompletion::instance().connect( entry );
183
184         auto check = ui::CheckButton( "Within selected brushes only" );
185         check.show();
186         vbox.pack_start( check, TRUE, TRUE, 0 );
187         AddDialogData( check, m_bSelectedOnly );
188
189         vbox = ui::VBox( FALSE, 5 );
190         vbox.show();
191         hbox.pack_start( vbox, FALSE, FALSE, 0 );
192
193         button = ui::Button( "Apply" );
194         button.show();
195         vbox.pack_start( button, FALSE, FALSE, 0 );
196         button.connect( "clicked",
197                                           G_CALLBACK( OnApply ), 0 );
198         button.dimensions(60, -1);
199
200         button = ui::Button( "Close" );
201         button.show();
202         vbox.pack_start( button, FALSE, FALSE, 0 );
203         button.connect( "clicked",
204                                           G_CALLBACK( OnClose ), 0 );
205         button.dimensions(60, -1);
206
207         return dlg;
208 }
209
210 void FindTextureDialog::updateTextures( const char* name ){
211         if ( isOpen() ) {
212                 if ( g_bFindActive ) {
213                         setFindStr( name + 9 );
214                 }
215                 else
216                 {
217                         setReplaceStr( name + 9 );
218                 }
219         }
220 }
221
222 bool FindTextureDialog::isOpen(){
223         return g_FindTextureDialog.GetWidget().visible();
224 }
225
226 void FindTextureDialog::setFindStr( const char* name ){
227         g_FindTextureDialog.exportData();
228         g_FindTextureDialog.m_strFind = name;
229         g_FindTextureDialog.importData();
230 }
231
232 void FindTextureDialog::setReplaceStr( const char* name ){
233         g_FindTextureDialog.exportData();
234         g_FindTextureDialog.m_strReplace = name;
235         g_FindTextureDialog.importData();
236 }
237
238 void FindTextureDialog::show(){
239         // workaround for strange gtk behaviour - modifying the contents of a window while it is not visible causes the window position to change without sending a configure_event
240         g_FindTextureDialog.m_position_tracker.sync( g_FindTextureDialog.GetWidget() );
241         g_FindTextureDialog.ShowDlg();
242         gtk_window_present( g_FindTextureDialog.GetWidget() );
243 }
244
245
246 void FindTextureDialog_constructWindow( ui::Window main_window ){
247         g_FindTextureDialog.constructWindow( main_window );
248 }
249
250 void FindTextureDialog_destroyWindow(){
251         g_FindTextureDialog.destroyWindow();
252 }
253
254 bool FindTextureDialog_isOpen(){
255         return g_FindTextureDialog.isOpen();
256 }
257
258 void FindTextureDialog_selectTexture( const char* name ){
259         g_FindTextureDialog.updateTextures( name );
260 }
261
262 #include "preferencesystem.h"
263
264 void FindTextureDialog_Construct(){
265         GlobalCommands_insert( "FindReplaceTextures", FindTextureDialog::ShowCaller() );
266         GlobalPreferenceSystem().registerPreference( "FindReplacehWnd",  make_property_string<WindowPositionTracker_String>( g_FindTextureDialog.m_position_tracker ) );
267 }
268
269 void FindTextureDialog_Destroy(){
270 }