00001 #ifdef HAVE_CONFIG_H
00002 # include <config.h>
00003 #endif
00004
00005 #include <ctype.h>
00006 #include <gdk/gdkkeysyms.h>
00007 #include "objbrowse.h"
00008 #include "shapegroup.h"
00009 #include "shapefile.h"
00010 #include "studio.h"
00011 #include "exceptions.h"
00012
00013 using EStudio::Add_menu_item;
00014 using EStudio::Create_arrow_button;
00015
00016 Object_browser::Object_browser(Shape_group *grp, Shape_file_info *fi)
00017 : group(grp), file_info(fi), popup(0),
00018 selected(-1), vscroll(0), hscroll(0), find_text(0), index0(0),
00019 loc_down(0), loc_up(0),
00020 move_down(0), move_up(0), config_width(0), config_height(0)
00021 {
00022 widget = 0;
00023 }
00024
00025 Object_browser::~Object_browser()
00026 {
00027 if (popup)
00028 gtk_widget_destroy(popup);
00029 }
00030
00031 void Object_browser::set_widget(GtkWidget *w)
00032 {
00033 widget = w;
00034 }
00035
00036
00037
00038
00039
00040 bool Object_browser::search_name
00041 (
00042 const char *nm,
00043 const char *srch
00044 )
00045 {
00046 char first = tolower(*srch);
00047 while (*nm)
00048 {
00049 if (tolower(*nm) == first)
00050 {
00051 const char *np = nm + 1, *sp = srch + 1;
00052 while (*sp && tolower(*np) == tolower(*sp))
00053 {
00054 sp++;
00055 np++;
00056 }
00057 if (!*sp)
00058 return true;
00059 }
00060 nm++;
00061 }
00062 return false;
00063 }
00064
00065
00066 bool Object_browser::server_response(int , unsigned char *, int )
00067 {
00068 return false;
00069 }
00070
00071 void Object_browser::end_terrain_editing()
00072 {
00073 }
00074
00075 void Object_browser::set_background_color(guint32)
00076 {
00077 }
00078
00079 GtkWidget *Object_browser::get_widget()
00080 {
00081 return widget;
00082 }
00083
00084 void Object_browser::on_browser_group_add
00085 (
00086 GtkMenuItem *item,
00087 gpointer udata
00088 )
00089 {
00090 Object_browser *chooser = (Object_browser *) udata;
00091 Shape_group *grp = (Shape_group *) gtk_object_get_user_data(
00092 GTK_OBJECT(item));
00093 int id = chooser->get_selected_id();
00094 if (id >= 0)
00095 {
00096 grp->add(id);
00097 ExultStudio::get_instance()->update_group_windows(grp);
00098 }
00099 }
00100
00101
00102
00103
00104
00105 void Object_browser::add_group_submenu
00106 (
00107 GtkWidget *popup
00108 )
00109 {
00110
00111
00112 Shape_group_file *groups = group ? group->get_file()
00113 : ExultStudio::get_instance()->get_cur_groups();
00114 int gcnt = groups ? groups->size() : 0;
00115 if (gcnt > 1 ||
00116 (gcnt == 1 && !group))
00117 {
00118 GtkWidget *mitem = Add_menu_item(popup,
00119 "Add to group...");
00120 GtkWidget *group_menu = gtk_menu_new();
00121 gtk_menu_item_set_submenu(GTK_MENU_ITEM(mitem), group_menu);
00122 for (int i = 0; i < gcnt; i++)
00123 {
00124 Shape_group *grp = groups->get(i);
00125 if (grp == group)
00126 continue;
00127 GtkWidget *gitem = Add_menu_item(
00128 group_menu, grp->get_name(),
00129 GTK_SIGNAL_FUNC (
00130 Object_browser::on_browser_group_add),
00131 this);
00132
00133 gtk_object_set_user_data(GTK_OBJECT(gitem), grp);
00134 }
00135 }
00136 }
00137
00138
00139
00140
00141
00142 void File_selector_ok
00143 (
00144 GtkButton *btn,
00145 gpointer user_data
00146 )
00147 {
00148 GtkFileSelection *fsel = GTK_FILE_SELECTION(gtk_widget_get_toplevel(
00149 GTK_WIDGET(btn)));
00150 const char *fname = gtk_file_selection_get_filename(fsel);
00151 File_sel_okay_fun fun = (File_sel_okay_fun)
00152 gtk_object_get_user_data(GTK_OBJECT(fsel));
00153 if (fname && *fname && fun)
00154 (*fun)(fname, user_data);
00155 }
00156
00157
00158
00159
00160
00161 GtkFileSelection *Create_file_selection
00162 (
00163 const char *title,
00164 File_sel_okay_fun ok_handler,
00165 gpointer user_data
00166 )
00167 {
00168 GtkFileSelection *fsel = GTK_FILE_SELECTION(gtk_file_selection_new(
00169 title));
00170 gtk_window_set_modal(GTK_WINDOW(fsel), true);
00171 gtk_object_set_user_data(GTK_OBJECT(fsel), (void *)ok_handler);
00172 gtk_signal_connect(GTK_OBJECT(fsel->ok_button), "clicked",
00173 GTK_SIGNAL_FUNC(File_selector_ok), user_data);
00174
00175 gtk_signal_connect_object(GTK_OBJECT(fsel->ok_button), "clicked",
00176 GTK_SIGNAL_FUNC(gtk_widget_destroy),
00177 GTK_OBJECT(fsel));
00178 gtk_signal_connect_object(GTK_OBJECT(fsel->cancel_button), "clicked",
00179 GTK_SIGNAL_FUNC(gtk_widget_destroy),
00180 GTK_OBJECT(fsel));
00181 return fsel;
00182 }
00183
00184
00185
00186
00187
00188 void Object_browser::on_browser_file_save
00189 (
00190 GtkMenuItem *item,
00191 gpointer udata
00192 )
00193 {
00194 Object_browser *chooser = (Object_browser *) udata;
00195 if (!chooser->file_info)
00196 return;
00197 try {
00198 chooser->file_info->flush();
00199 } catch (const exult_exception& e) {
00200 EStudio::Alert(e.what());
00201 }
00202 }
00203
00204
00205
00206
00207
00208 void Object_browser::on_browser_file_revert
00209 (
00210 GtkMenuItem *item,
00211 gpointer udata
00212 )
00213 {
00214 Object_browser *chooser = (Object_browser *) udata;
00215 if (!chooser->file_info)
00216 return;
00217 char *msg = g_strdup_printf("Okay to throw away any changes to '%s'?",
00218 chooser->file_info->get_basename());
00219 if (EStudio::Prompt(msg, "Yes", "No") != 0)
00220 return;
00221 if (!chooser->file_info->revert())
00222 EStudio::Alert("Revert not yet implemented for this file");
00223 else
00224 {
00225 chooser->load();
00226 chooser->render();
00227 chooser->show();
00228 }
00229 }
00230
00231
00232
00233
00234
00235 GtkWidget *Object_browser::create_popup
00236 (
00237 )
00238 {
00239 if (popup)
00240 gtk_widget_destroy(popup);
00241 popup = gtk_menu_new();
00242
00243 GtkWidget *mitem = Add_menu_item(popup, "File...");
00244 GtkWidget *file_menu = gtk_menu_new();
00245 gtk_menu_item_set_submenu(GTK_MENU_ITEM(mitem), file_menu);
00246 Add_menu_item(file_menu, "Save",
00247 GTK_SIGNAL_FUNC(on_browser_file_save), this);
00248 Add_menu_item(file_menu, "Revert",
00249 GTK_SIGNAL_FUNC(on_browser_file_revert), this);
00250 if (selected >= 0)
00251 add_group_submenu(popup);
00252 return popup;
00253 }
00254
00255
00256
00257
00258 static void
00259 on_find_down (GtkButton *button,
00260 gpointer user_data)
00261 {
00262 Object_browser *chooser = (Object_browser *) user_data;
00263 chooser->search(gtk_entry_get_text(
00264 GTK_ENTRY(chooser->get_find_text())), 1);
00265 }
00266 static void
00267 on_find_up (GtkButton *button,
00268 gpointer user_data)
00269 {
00270 Object_browser *chooser = (Object_browser *) user_data;
00271 chooser->search(gtk_entry_get_text(
00272 GTK_ENTRY(chooser->get_find_text())), -1);
00273 }
00274 static gboolean
00275 on_find_key (GtkEntry *entry,
00276 GdkEventKey *event,
00277 gpointer user_data)
00278 {
00279 if (event->keyval == GDK_Return)
00280 {
00281 Object_browser *chooser = (Object_browser *) user_data;
00282 chooser->search(gtk_entry_get_text(
00283 GTK_ENTRY(chooser->get_find_text())), 1);
00284 return TRUE;
00285 }
00286 return FALSE;
00287 }
00288
00289 static void
00290 on_loc_down (GtkButton *button,
00291 gpointer user_data)
00292 {
00293 Object_browser *chooser = (Object_browser *) user_data;
00294 chooser->locate(false);
00295 }
00296 static void
00297 on_loc_up (GtkButton *button,
00298 gpointer user_data)
00299 {
00300 Object_browser *chooser = (Object_browser *) user_data;
00301 chooser->locate(true);
00302 }
00303
00304 static void
00305 on_move_down (GtkButton *button,
00306 gpointer user_data)
00307 {
00308 Object_browser *chooser = (Object_browser *) user_data;
00309 chooser->move(false);
00310 }
00311 static void
00312 on_move_up (GtkButton *button,
00313 gpointer user_data)
00314 {
00315 Object_browser *chooser = (Object_browser *) user_data;
00316 chooser->move(true);
00317 }
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327 GtkWidget *Object_browser::create_controls
00328 (
00329 int controls
00330 )
00331 {
00332 GtkWidget *topframe = gtk_frame_new (NULL);
00333 gtk_widget_show(topframe);
00334
00335
00336 GtkWidget *tophbox = gtk_hbox_new (FALSE, 0);
00337 gtk_widget_show (tophbox);
00338 gtk_container_add (GTK_CONTAINER (topframe), tophbox);
00339
00340
00341
00342 if (controls & (int) find_controls)
00343 {
00344 GtkWidget *frame = gtk_frame_new("Find");
00345 gtk_widget_show(frame);
00346 gtk_box_pack_start (GTK_BOX (tophbox), frame, FALSE, FALSE, 2);
00347
00348 GtkWidget *hbox2 = gtk_hbox_new (FALSE, 0);
00349 gtk_widget_show (hbox2);
00350 gtk_container_add (GTK_CONTAINER(frame), hbox2);
00351
00352 find_text = gtk_entry_new ();
00353 gtk_widget_show (find_text);
00354 gtk_box_pack_start(GTK_BOX(hbox2), find_text, FALSE, FALSE, 0);
00355 gtk_widget_set_usize (find_text, 110, -2);
00356
00357 GtkWidget *find_down = Create_arrow_button(
00358 GTK_ARROW_DOWN,
00359 GTK_SIGNAL_FUNC(on_find_down), this);
00360 gtk_box_pack_start(GTK_BOX(hbox2), find_down, FALSE, FALSE, 0);
00361
00362 GtkWidget *find_up = Create_arrow_button(GTK_ARROW_UP,
00363 GTK_SIGNAL_FUNC(on_find_up), this);
00364 gtk_box_pack_start(GTK_BOX(hbox2), find_up, FALSE, FALSE, 0);
00365 gtk_signal_connect (GTK_OBJECT(find_text), "key-press-event",
00366 GTK_SIGNAL_FUNC(on_find_key), this);
00367 }
00368
00369
00370
00371 if (controls & (int) locate_controls)
00372 {
00373 GtkWidget *frame = gtk_frame_new ("Locate");
00374 gtk_widget_show(frame);
00375 gtk_box_pack_start (GTK_BOX (tophbox), frame, FALSE, FALSE, 2);
00376 GtkWidget *bbox = gtk_hbox_new(TRUE, 0);
00377 gtk_widget_show (bbox);
00378 gtk_container_add (GTK_CONTAINER (frame), bbox);
00379
00380 loc_down = Create_arrow_button(GTK_ARROW_DOWN,
00381 GTK_SIGNAL_FUNC(on_loc_down), this);
00382 gtk_box_pack_start(GTK_BOX (bbox), loc_down, FALSE, FALSE, 0);
00383
00384 loc_up = Create_arrow_button(GTK_ARROW_UP,
00385 GTK_SIGNAL_FUNC(on_loc_up), this);
00386 gtk_box_pack_start(GTK_BOX (bbox), loc_up, FALSE, FALSE, 0);
00387 }
00388
00389
00390
00391 if (controls & (int) move_controls)
00392 {
00393 GtkWidget *frame = gtk_frame_new ("Move");
00394 gtk_widget_show(frame);
00395 gtk_box_pack_start(GTK_BOX (tophbox), frame, FALSE, FALSE, 2);
00396 GtkWidget *bbox = gtk_hbox_new(TRUE, 0);
00397 gtk_widget_show (bbox);
00398 gtk_container_add (GTK_CONTAINER (frame), bbox);
00399
00400 move_down = Create_arrow_button(GTK_ARROW_DOWN,
00401 GTK_SIGNAL_FUNC(on_move_down), this);
00402 gtk_box_pack_start(GTK_BOX (bbox), move_down, FALSE, FALSE, 0);
00403 move_up = Create_arrow_button(GTK_ARROW_UP,
00404 GTK_SIGNAL_FUNC(on_move_up), this);
00405 gtk_box_pack_start (GTK_BOX (bbox), move_up, FALSE, FALSE, 0);
00406 }
00407 return topframe;
00408 }
00409