objbrowse.cc

Go to the documentation of this file.
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  *  Search a name for a string, ignoring case.
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) // Matched to end of search string.
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;     // Not handled here.
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)      // Selected shape?
00095     {
00096     grp->add(id);   // Add & redisplay open windows.
00097     ExultStudio::get_instance()->update_group_windows(grp);
00098     }
00099   }
00100 
00101 /*
00102  *  Add an "Add to group..." submenu to a popup for our group.
00103  */
00104 
00105 void Object_browser::add_group_submenu
00106   (
00107   GtkWidget *popup
00108   )
00109   {
00110           // Use our group, or assume we're in
00111           //   the main window.
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 ||     // Groups besides ours?
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;// Skip ourself.
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           // Store group on menu item.
00133       gtk_object_set_user_data(GTK_OBJECT(gitem), grp);
00134       }
00135     }
00136   }
00137 
00138 /*
00139  *  Okay clicked in file-selector.
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  *  Create a modal file selector.
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           // Destroy when done.
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  *  Save file in browser.
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;     // Nothing to write to.
00197   try {
00198     chooser->file_info->flush();
00199   } catch (const exult_exception& e) {
00200     EStudio::Alert(e.what());
00201   }
00202   }
00203 
00204 /*
00205  *  Revert file in browser to what's on disk.
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;     // No file?
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();  // Reload from file.
00226     chooser->render();  // Repaint.
00227     chooser->show();
00228     }
00229   }
00230 
00231 /*
00232  *  Set up popup menu for shape browser.
00233  */
00234 
00235 GtkWidget *Object_browser::create_popup
00236   (
00237   )
00238   {
00239   if (popup)      // Clean out old.
00240     gtk_widget_destroy(popup);
00241   popup = gtk_menu_new();   // Create popup menu.
00242           // Add "File" submenu.
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)    // Item selected?  Add groups.
00251     add_group_submenu(popup);
00252   return popup;
00253   }
00254 
00255 /*
00256  *  Callbacks for controls:
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;     // Let parent handle it.
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  *  Create box with various controls.
00322  *
00323  *  Note: 'this' is passed as user-data to all the signal handlers,
00324  *    which call various virtual methods.
00325  */
00326 
00327 GtkWidget *Object_browser::create_controls
00328   (
00329   int controls      // Browser_control flags.
00330   )
00331   {
00332   GtkWidget *topframe = gtk_frame_new (NULL);
00333   gtk_widget_show(topframe);
00334 
00335           // Everything goes in here.
00336   GtkWidget *tophbox = gtk_hbox_new (FALSE, 0);
00337   gtk_widget_show (tophbox);
00338   gtk_container_add (GTK_CONTAINER (topframe), tophbox);
00339   /*
00340    *  The 'Find' controls.
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    *  The 'Locate' controls.
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    *  The 'Move' controls.
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 

Generated on Mon Jul 9 14:42:48 2007 for ExultEngine by  doxygen 1.5.1