Project Homepage Sourceforge Page CVS Repository Freshmeat.net Page Download project Author's Homepage

callbacks.c

Go to the documentation of this file.
00001 /*!\file callbacks.c
00002   \brief callback function deffinitions
00003 */
00004 /* NOTICE:
00005     Copyright (C) 2004  Karl N. Redman (SleepingStill.com)
00006 
00007     This program is free software; you can redistribute it and/or modify
00008     it under the terms of the GNU General Public License as published by
00009     the Free Software Foundation; either version 2 of the License, or
00010     (at your option) any later version.
00011 
00012     This program is distributed in the hope that it will be useful,
00013     but WITHOUT ANY WARRANTY; without even the implied warranty of
00014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015     GNU General Public License for more details.
00016 
00017     You should have received a copy of the GNU General Public License
00018     along with this program; if not, write to the Free Software
00019     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00020 
00021     For further information contact: parasyte@sleepingstill.com
00022 */
00023 
00024 #ifdef HAVE_CONFIG_H
00025 #  include <config.h>
00026 #endif
00027 
00028 #include <gtk/gtk.h>
00029 #include <gtk/gtkcombo.h>
00030 #include <gdk/gdkkeysyms.h>
00031 
00032 #include <string.h>
00033 #include <stdio.h>
00034 #include <stdlib.h>
00035 #include <unistd.h>
00036 #include <sys/types.h>
00037 
00038 #include "callbacks.h"
00039 #include "interface.h"
00040 #include "support.h"
00041 
00042 #include "comboHandlers.h"
00043 #include "comboBox.h"
00044 #include "main.h"
00045 
00046 /// whether the "options" box is up (disabled)
00047 gboolean vbox2Up = FALSE;
00048 
00049 /** 
00050     \brief called when the main window is destroyed
00051 
00052     \author Karl N. Redman
00053 
00054     \par Purpose: 
00055         cleans up before exiting
00056 */
00057 void
00058 on_mainWindow_destroy                  (GtkObject       *object,
00059                                         gpointer         user_data)
00060 {
00061   //cleanup
00062   freeList(cbitems);
00063   g_free(history_file);
00064   g_free(home_directory);
00065   g_free(command);
00066   g_free(terminal_path);
00067 
00068   //die
00069   gtk_main_quit();
00070 }
00071 
00072 
00073 void
00074 on_combo_entry1_changed                (GtkEditable     *editable,
00075                                         gpointer         user_data)
00076 {
00077 
00078 }
00079 
00080 gboolean 
00081 on_combo_key_press_event                (GtkWidget       *widget,
00082                                         GdkEventKey     *event,
00083                                         gpointer         user_data)
00084 {
00085   return TRUE;
00086 }
00087 
00088 /** 
00089     \brief handle when a keypress event occures in the combo box.
00090 
00091     \author Karl N. Redman
00092 
00093     \note
00094     This is a lengthy function for now. run-free 3.0 will handle this
00095     better in the futue. For now we just handle the common
00096     functionality of the application from here
00097 */
00098 gboolean
00099 on_combo_entry1_key_press_event        (GtkWidget       *widget,
00100                                         GdkEventKey     *event,
00101                                         gpointer         user_data)
00102 {
00103   //save the previous key press (for control chars)
00104   static unsigned int prevKey =0;
00105 
00106   if(event->keyval == GDK_Return ||
00107      event->keyval == GDK_KP_Enter) // run command
00108     {
00109       if(strcmp(gtk_entry_get_text(GTK_ENTRY( GTK_COMBO(combo1)->entry)), "") !=0 &&
00110          gtk_entry_get_text(GTK_ENTRY( GTK_COMBO(combo1)->entry)) != NULL)
00111         {
00112           writeHistory(gtk_entry_get_text(GTK_ENTRY( GTK_COMBO(combo1)->entry)), history_file);
00113           run_command(gtk_entry_get_text(GTK_ENTRY( GTK_COMBO(combo1)->entry)));
00114 
00115           gtk_widget_grab_focus(GTK_WIDGET(GTK_COMBO (combo1)->entry));
00116         }
00117       return TRUE;
00118     }
00119   else if(event->keyval == GDK_u)
00120     {
00121       if(prevKey == GDK_Alt_L || prevKey == GDK_Alt_R)
00122         {
00123           if(die)
00124             die=FALSE;
00125           else
00126             die=TRUE;
00127         }
00128       }
00129   else if(event->keyval == GDK_y)
00130     {
00131       if(prevKey == GDK_Alt_L || prevKey == GDK_Alt_R)
00132         {
00133           if(keep_open)
00134             keep_open=FALSE;
00135           else
00136             keep_open=TRUE;
00137         }
00138       }
00139   else if(event->keyval == GDK_h)
00140     {
00141       if(prevKey == GDK_Alt_L || prevKey == GDK_Alt_R)
00142         {
00143           keystrokes_dialog();
00144         }
00145       }
00146   if(event->keyval == GDK_space)
00147   {
00148       if(prevKey == GDK_Control_L || prevKey == GDK_Control_R ||
00149         prevKey == GDK_Alt_L || prevKey == GDK_Alt_R)
00150         {
00151           gint x =0, y =0, 
00152             height =0, width =0, 
00153             old_height =0, old_width =0; 
00154 
00155           //we have to grab the combo position
00156           gtk_combo_get_pos(GTK_COMBO(combo1), &x, &y, &height, &width);
00157 
00158           //see if we have the focus
00159           if (!GTK_WIDGET_HAS_FOCUS (GTK_COMBO(combo1)->entry))
00160             gtk_widget_grab_focus (GTK_COMBO(combo1)->entry);
00161           
00162           //deliver all events to the popwin
00163           gtk_grab_add (GTK_COMBO(combo1)->popwin);
00164 
00165           //grab ponter (mouse) and all other events
00166           gdk_pointer_grab (GTK_COMBO(combo1)->popwin->window, TRUE,
00167                             GDK_BUTTON_PRESS_MASK | 
00168                             GDK_BUTTON_RELEASE_MASK |
00169                             GDK_POINTER_MOTION_MASK, 
00170                             NULL, NULL, GDK_CURRENT_TIME);
00171 
00172           /* I don't know why this is being evil but the widget needs
00173              to be resized...
00174            */
00175           if (width != old_width || height != old_height)
00176             {
00177               gtk_widget_hide (GTK_SCROLLED_WINDOW
00178                                (GTK_COMBO(combo1)->popup)->hscrollbar);
00179 
00180               gtk_widget_hide (GTK_SCROLLED_WINDOW
00181                                (GTK_COMBO(combo1)->popup)->vscrollbar);
00182             }
00183           
00184           //set the position of the listbox
00185           gtk_widget_set_uposition (GTK_COMBO(combo1)->popwin, x, y);
00186           gtk_widget_set_usize (GTK_COMBO(combo1)->popwin, width, height);
00187           gtk_widget_realize (GTK_COMBO(combo1)->popwin);
00188           gdk_window_resize (GTK_COMBO(combo1)->popwin->window, width, height);
00189           
00190           gtk_widget_show(GTK_COMBO(combo1)->popwin);
00191         }
00192       return FALSE;
00193   } 
00194   else
00195     if(event->keyval == GDK_Control_L || event->keyval == GDK_Control_R ||
00196        event->keyval == GDK_Alt_L || event->keyval ==GDK_Alt_R)
00197       prevKey = event->keyval;
00198     else
00199       prevKey = 0;
00200     
00201   return FALSE;
00202 }
00203 
00204 
00205 void
00206 on_browseButton_clicked                (GtkButton       *button,
00207                                         gpointer         user_data)
00208 {
00209   gtk_widget_show (fileselection);
00210 }
00211 
00212 
00213 /** 
00214     \brief handle setting the run_in_term mode
00215 
00216     \author Karl N. Redman
00217 
00218     \par Purpose: 
00219         Toggle between run_in_term and normal (exit) modes of
00220     operation
00221 */
00222 void
00223 on_checkbutton_toggled                 (GtkToggleButton *togglebutton,
00224                                         gpointer         user_data)
00225 {
00226   if(!run_in_term)
00227     run_in_term = TRUE;
00228   else
00229     run_in_term = FALSE;
00230 }
00231 
00232 
00233 /** 
00234     \brief Handle the OK button clicked in the fileselection dialog.
00235 
00236     \author Karl N. Redman
00237 
00238     \par Purpose: 
00239         Sets the combo box entry and hides the fileselection
00240     dialog.
00241 */
00242 void
00243 on_ok_button1_clicked                  (GtkButton       *button,
00244                                         gpointer         user_data)
00245 {
00246   //space and null are the +1's
00247   char s[strlen(gtk_entry_get_text(GTK_ENTRY( GTK_COMBO(combo1)->entry)))
00248          +1 
00249          + strlen( gtk_file_selection_get_filename(GTK_FILE_SELECTION(fileselection)))
00250          +1]; 
00251   
00252   //set the combo box string
00253   sprintf(s, "%s %s", gtk_entry_get_text(GTK_ENTRY( GTK_COMBO(combo1)->entry)), gtk_file_selection_get_filename(GTK_FILE_SELECTION(fileselection)));
00254 
00255   //set the entry
00256   gtk_entry_set_text(GTK_ENTRY( GTK_COMBO(combo1)->entry), s);
00257 
00258   //hide the file dialog
00259   gtk_widget_hide (fileselection);
00260 
00261   /**\todo 
00262      clear the file selection by stripping off the file name ?
00263    */
00264   
00265 }
00266 
00267 
00268 void
00269 on_cancel_button1_clicked              (GtkButton       *button,
00270                                         gpointer         user_data)
00271 {
00272   gtk_widget_hide (fileselection);
00273 }
00274 
00275 
00276 gboolean
00277 on_fileselection_key_press_event       (GtkWidget       *widget,
00278                                         GdkEventKey     *event,
00279                                         gpointer         user_data)
00280 {
00281   if(event->keyval == GDK_Escape) // quit
00282     {
00283       //cancel operations
00284       gtk_button_clicked(GTK_BUTTON(GTK_FILE_SELECTION(widget)->cancel_button));
00285     }
00286   return FALSE;
00287 }
00288 
00289 
00290 /** 
00291     \brief Handle a keypress event at the toplevel window level
00292 
00293     \author Karl N. Redman
00294 
00295     \par Purpose: 
00296         Takes care of default keystrokes (closing the App. etc.).
00297 */
00298 gboolean
00299 on_mainWindow_key_press_event          (GtkWidget       *widget,
00300                                         GdkEventKey     *event,
00301                                         gpointer         user_data)
00302 {
00303   static unsigned int prevKey =0;
00304 
00305   //return on_combo_entry1_key_press_event(widget, event, user_data);
00306   if(event->keyval == GDK_Escape) // quit
00307     {
00308       //cancel operations -"destroy"
00309       gtk_main_quit();
00310     }
00311   else if(event->keyval ==GDK_c)
00312     {
00313       gtk_widget_grab_focus(GTK_WIDGET(GTK_COMBO (combo1)->entry));
00314     }
00315   else if(event->keyval == GDK_m) // history mode -should be anaccelerator
00316     {
00317       if(prevKey == GDK_Control_L || prevKey == GDK_Control_R)
00318         {
00319           if(combo_mode < RF_MAX_MODE)
00320             combo_mode++;
00321           else if(combo_mode >= RF_MAX_MODE)
00322             combo_mode = RF_HISTORY_MODE;
00323         
00324           combo_init(combo_mode);
00325         }
00326     }
00327   else if(event->keyval == GDK_h)
00328     {
00329       if(prevKey == GDK_Alt_L || prevKey == GDK_Alt_R)
00330         {
00331           keystrokes_dialog();
00332         }
00333       }
00334   else
00335     if(event->keyval == GDK_Control_L || event->keyval == GDK_Control_R)
00336       prevKey = event->keyval;
00337     else
00338       prevKey = 0;
00339   return FALSE;
00340 }
00341 
00342 /** 
00343     \brief Execute the command in the combo entry box.
00344 
00345     \author Karl N. Redman
00346 
00347     \par Purpose: 
00348         Write to the history file and execute the command in the
00349     entry box.
00350 */
00351 void
00352 on_runButton_clicked                    (GtkButton       *button,
00353                                          gpointer         user_data)
00354 {
00355   if(strcmp(gtk_entry_get_text(GTK_ENTRY( GTK_COMBO(combo1)->entry)), "") !=0 &&
00356      gtk_entry_get_text(GTK_ENTRY( GTK_COMBO(combo1)->entry)) != NULL)
00357     {
00358       writeHistory(gtk_entry_get_text(GTK_ENTRY( GTK_COMBO(combo1)->entry)), history_file);
00359       run_command(gtk_entry_get_text(GTK_ENTRY( GTK_COMBO(combo1)->entry)));
00360     }
00361 }
00362 
00363 /** 
00364     \brief Handle the options mode selection
00365 
00366     \author Karl N. Redman
00367 
00368     \par Purpose: 
00369         Resize the main window and display the options allowed by
00370     the options mode of operation.
00371 */
00372 void
00373 on_optionsButton_clicked               (GtkButton       *button,
00374                                         gpointer         user_data)
00375 {
00376   //TODO (this needs to be made more intuitive!!!)
00377   static gboolean up = TRUE;
00378 
00379   /*! \note in order to resize the window we have to mess with the
00380     window policy of the mainWindow. This is pretty clumbsy here.
00381   */
00382   if(up)
00383     gtk_window_set_policy (GTK_WINDOW (mainWindow), FALSE, FALSE, FALSE);
00384   else
00385     gtk_window_set_policy (GTK_WINDOW (mainWindow), FALSE, FALSE, TRUE);
00386 
00387   handle_options_display();
00388   gtk_window_set_policy (GTK_WINDOW (mainWindow), TRUE, TRUE, TRUE);
00389 
00390   if(up)
00391     up=TRUE;
00392   else
00393     up=FALSE;
00394 }
00395 /** 
00396     \brief Handle options display
00397 
00398     \author Karl N. Redman
00399 
00400     \par Purpose: 
00401         Handle mainWindow resizing when Options are desired
00402 */
00403 void handle_options_display()
00404 {
00405   if(vbox2Up)
00406     {
00407       int x;
00408       int y;
00409 
00410       ///set the focus to the combo box
00411       gtk_widget_grab_focus(GTK_WIDGET(GTK_COMBO (combo1)->entry));
00412       
00413       ///hide the vbox
00414       gtk_widget_hide (vbox2);
00415 
00416       /// resize the main window
00417       gdk_window_get_origin(mainWindow->window, &x, &y);
00418       gdk_window_move (mainWindow->window, x, y);
00419       
00420       //set the flag
00421       vbox2Up = FALSE;
00422     }
00423   else
00424     {
00425       //show the vbox
00426       gtk_widget_show (vbox2);
00427       vbox2Up = TRUE;
00428     }
00429 }
00430 
00431 
00432 void
00433 on_whoEntry_grab_focus                 (GtkWidget       *widget,
00434                                         gpointer         user_data)
00435 {
00436   if(!vbox2Up)
00437     handle_options_display();
00438 }
00439 
00440 
00441 void
00442 on_passwordEntry_grab_focus            (GtkWidget       *widget,
00443                                         gpointer         user_data)
00444 {
00445   if(!vbox2Up)
00446     handle_options_display();
00447 }
00448 
00449 gboolean
00450 on_fileselection_delete_event          (GtkWidget       *widget,
00451                                         GdkEvent        *event,
00452                                         gpointer         user_data)
00453 {
00454   gtk_widget_hide (fileselection);
00455   return TRUE;
00456 }
00457 
00458 
00459 
00460 
00461 #define EMPTY_LIST_HEIGHT   (15)
00462 /** 
00463     \brief figure out the combo box positions
00464 
00465     \author NOT ME! whoever wrote gtkhacks...
00466     
00467     \warning This function is "borrowed" from gtkhacks of glade (i think)
00468     
00469     
00470     \par Purpose: 
00471     grab the position of the combo box
00472     
00473     \todo 
00474     REDO THIS FUNCTION! This function is not mine! (see gtkhacks)
00475         
00476 */
00477 
00478 static void
00479 gtk_combo_get_pos (GtkCombo * combo,
00480                    gint * x,
00481                    gint * y,
00482                    gint * height,
00483                    gint * width)
00484 {
00485         GtkBin *popwin;
00486         GtkWidget *widget;
00487         GtkScrolledWindow *popup;
00488 
00489         gint real_height;
00490         GtkRequisition list_requisition;
00491         gboolean show_hscroll = FALSE;
00492         gboolean show_vscroll = FALSE;
00493         gint avail_height;
00494         gint min_height;
00495         gint alloc_width;
00496         gint work_height;
00497         gint old_height;
00498         gint old_width;
00499 
00500         widget = GTK_WIDGET(combo);
00501         popup  = GTK_SCROLLED_WINDOW (combo->popup);
00502         popwin = GTK_BIN (combo->popwin);
00503 
00504         gtk_widget_realize(GTK_WIDGET(combo->entry));
00505         gdk_window_get_origin (combo->entry->window, x, y);
00506         real_height = MIN (combo->entry->requisition.height,
00507                            combo->entry->allocation.height);
00508         *y += real_height;
00509         avail_height = gdk_screen_height () - *y;
00510 
00511         gtk_widget_size_request (combo->list, &list_requisition);
00512         min_height = MIN (list_requisition.height,
00513                           popup->vscrollbar->requisition.height);
00514         if (!GTK_LIST (combo->list)->children)
00515                 list_requisition.height += EMPTY_LIST_HEIGHT;
00516 
00517         alloc_width = (widget->allocation.width -
00518              2 * popwin->child->style->klass->xthickness -
00519              2 * GTK_CONTAINER (popwin->child)->border_width -
00520              2 * GTK_CONTAINER (combo->popup)->border_width -
00521              2 * GTK_CONTAINER (GTK_BIN (popup)->child)->border_width -
00522              2 * GTK_BIN (popup)->child->style->klass->xthickness);
00523 
00524         work_height = (2 * popwin->child->style->klass->ythickness +
00525              2 * GTK_CONTAINER (popwin->child)->border_width +
00526              2 * GTK_CONTAINER (combo->popup)->border_width +
00527              2 * GTK_CONTAINER (GTK_BIN (popup)->child)->border_width +
00528              2 * GTK_BIN (popup)->child->style->klass->xthickness);
00529 
00530         do {
00531                 old_width = alloc_width;
00532                 old_height = work_height;
00533 
00534                 if (!show_hscroll &&
00535                     alloc_width < list_requisition.width) {
00536                           work_height += popup->hscrollbar->requisition.height
00537                                          + GTK_SCROLLED_WINDOW_CLASS
00538                                            (GTK_OBJECT (combo->popup)->klass)->scrollbar_spacing;
00539                           show_hscroll = TRUE;
00540                 }
00541             if (!show_vscroll &&
00542                 work_height + list_requisition.height > avail_height) {
00543                     if (work_height + min_height > avail_height &&
00544                         *y - real_height > avail_height) {
00545                                 *y -= (work_height +
00546                                        list_requisition.height +
00547                                        real_height);
00548                                 break;
00549                     }
00550                     alloc_width -= popup->vscrollbar->requisition.width +
00551                                    GTK_SCROLLED_WINDOW_CLASS
00552                                   (GTK_OBJECT (combo->popup)->klass)->scrollbar_spacing;
00553                     show_vscroll = TRUE;
00554             }
00555         } while (old_width != alloc_width || old_height != work_height);
00556 
00557         *width = widget->allocation.width;
00558         if (show_vscroll)
00559                 *height = avail_height;
00560         else
00561                 *height = work_height + list_requisition.height;
00562 
00563         if (*x < 0)
00564                 *x = 0;
00565 }
00566 
00567 void
00568 dialog_ok_clicked                       (GtkButton       *button,
00569                                         gpointer         user_data)
00570 {
00571   gtk_widget_destroy(GTK_WIDGET(user_data));
00572 }

Generated on Thu Mar 18 07:26:17 2004 for run-free by doxygen 1.3.5