Logo Search packages:      
Sourcecode: paul version File versions  Download package

gtkuti.c

/*****************************************************************************
 *                                                                           *
 * Program:   paul                                                           *
 *            (P)rogramm zur (A)uswertung und (U)mformung von                *
 *            (L)aserbildern                                                 *
 * Uses:      GTK+ 1.2                                                       *
 * Modul:     gtkuti.c                                                       *
 *            utilities to handle some gtk widgets                           *
 * Author:    Andreas Tille                                                  *
 * Date:      23.09.1998                                                     *
 * Copyright: Andreas Tille, 1999; GNU Public License                        *
 *                                                                           *
 *****************************************************************************/

#include <stdlib.h>
#include <sys/param.h>
#include "paul.h"
#include "callback.h"
#include "names.h"
 
/*****************************************************************************************
 * functions to update parameters                                                        *
 *****************************************************************************************/

void _ParameterChanged(GtkButton *button, gpointer data)
/* called when parameters were changed in menu
 * --- Parameter: ---
 * GtkButton *button: OK-Button of menu window, parameter structure connected
 * gpointer   data  : spin button which holds new value
 */
{
  register GtkWidget *zw;
  GtkTable           *table;
  ITEM               *para;
  register ITEM      *ap;
  GList              *pl;

  g_return_if_fail ( button ) ;
  g_return_if_fail ( GTK_IS_BUTTON(button) );
  g_return_if_fail ( (para = (ITEM *)gtk_object_get_user_data(GTK_OBJECT(button))) );
  g_return_if_fail ( (table  = GTK_TABLE(data)) );
  g_return_if_fail ( (pl   = (table)->children) );

  ap = para;
  while ( ap->name ) ap++ ;
   
  for ( --ap; ap >= para; ap-- ) {
    if ( pl && GTK_IS_SPIN_BUTTON(zw = ((GtkTableChild *)(pl->data))->widget) 
            && GTK_IS_LABEL(((GtkTableChild *)((pl->next)->data))->widget) ) 
      switch ( ap->typ ) {
      case P_UCHAR:  *((unsigned char *)(ap->val))
                        = (unsigned char)gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(zw));
                     break;
      case P_INT:    *((int *)(ap->val))
                        = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(zw));
                     break;
      case P_DOUBLE: *((double *)(ap->val)) 
                        = (double)gtk_spin_button_get_value_as_float(GTK_SPIN_BUTTON(zw));
                     break;
      default:       g_return_if_fail ( ap->typ == P_UCHAR );
      }
    else 
       g_warning(_("Can't obtain %s"), ap->name);
    if ( !(pl = (pl->next)->next) ) break;
  }
  FREE(para);
}

/*****************************************************************************************
 * Functions to build a table of parameter entries                                       *
 *****************************************************************************************/

static void ParameterTableEntry(GtkWidget *table, int i, ITEM *para)
/* build table of parameters
 * --- Parameter: ---
 * GtkWidget *table : table to draw in
 * int        i     : row to draw in
 * ITEM      *para  : parameter information
 */
{
  GtkWidget     *label, *spinner;
  gfloat         value = 0, step = 0;
  int            digits = 0, size = 100;

  label   = gtk_label_new(para->name);
  gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
  gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, i, i+1);

  switch ( para->typ ) {
    case P_UCHAR:  value  = (gfloat)(*((unsigned char *)(para->val)));
                   step   = 1;
                   digits = 0;
                   size   = 50;
                   break;
    case P_INT:    value  = (gfloat)(*((int *)(para->val))),
                   step   = 1;
                   digits = 0;
                   size   = 80;
                   break;
    case P_DOUBLE: value  = (gfloat)(*((double *)(para->val))),
                   step   = 0.1;
                   digits = 2;
                   size   = 100;
                   break;
    default:       g_return_if_fail ( para->typ == P_UCHAR );
  }

  para->adj = (GtkAdjustment *)gtk_adjustment_new(value, para->lower, para->upper, step, 0.0, 0.0);
  spinner   = gtk_spin_button_new(para->adj, step, digits);
  gtk_widget_set_usize(spinner, size, 0);
  gtk_spin_button_set_update_policy(GTK_SPIN_BUTTON(spinner), GTK_UPDATE_ALWAYS);
  if ( para->valchg ) {
    gtk_object_set_user_data(GTK_OBJECT(para->adj), para->val);
    if ( para->userdata ) gtk_object_set_user_data(GTK_OBJECT(spinner), para->userdata);
    gtk_signal_connect(GTK_OBJECT(para->adj), "value_changed", GTK_SIGNAL_FUNC(para->valchg), spinner);
  }
  gtk_table_attach_defaults(GTK_TABLE(table), spinner, 1, 2, i, i+1);
}

GtkWidget *BuildParameterTable(ITEM *para, int np)
/* Build a table of parameters
 * --- Parameter: ---
 * ITEM      *para                 : parameters
 * int        np                   : number of parameters
 * --- Return: ---
 * GtkWidget *BuildParameterTable(): created table widget to obtain values later on
 */
{
  GtkWidget *table;     /* Stack the items inside subsections */
  int        i;

  table = gtk_table_new(2, np, FALSE);
  gtk_container_set_border_width(GTK_CONTAINER(table), 5);

  for ( i = 0; i < np; i++ ) ParameterTableEntry(table, i, para + i);
  return table;
}

void BuildParameterInput(GtkWidget *box, const char *title, const char *frame_title, void *data, 
                         GtkSignalFunc chg_func, void *chg_data,
                         GtkSignalFunc add_func, void *add_data)
/* Universal parameter entry widget
 * --- Parameter: ---
 * GtkWidget     *box        : box to insert into frame in dialog vbox
 * char          *title      : title of parameter dialog window
 * char          *frame_title: title of frame inside parameter dialog window
 * void          *data       : data to set as user data of OK button
 * GtkSignalFunc  chg_func   : function to call when parameter has changed
 * void          *chg_data   : data to submit to change function
 * GtkSignalFunc  add_func   : if != NULL, do this func after parameter change
 *                             (only needed for animation at this time)
 * void          *add_data   : this is PAUL *p when animation parameter is changed
 */
{
  static GtkWidget *window = NULL;
  GtkWidget        *frame, *hbox, *button;
   
  if ( window ) {
    gtk_widget_destroy(window);
    window = NULL;
  }

  window = gtk_dialog_new();
  gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_MOUSE);
  gtk_signal_connect(GTK_OBJECT(window), "destroy", GTK_SIGNAL_FUNC(gtk_widget_destroyed),
                     &window);
  if ( title ) gtk_window_set_title(GTK_WINDOW(window), title);

  gtk_container_set_border_width(GTK_CONTAINER(GTK_DIALOG(window)->vbox), 5);

  frame = gtk_frame_new(frame_title);
  gtk_container_add(GTK_CONTAINER(GTK_DIALOG(window)->vbox), frame);
  hbox = gtk_hbox_new(FALSE, 0);
  gtk_container_add(GTK_CONTAINER(frame), hbox);

  gtk_box_pack_start(GTK_BOX(hbox), box, TRUE, FALSE, 0);
      
  hbox = gtk_hbox_new (FALSE, 0);
  gtk_container_add(GTK_CONTAINER(GTK_DIALOG(window)->action_area), hbox);
  
  button = CreateOkButton(window, hbox, data, GTK_SIGNAL_FUNC(chg_func), chg_data, add_func, add_data);
  gtk_widget_grab_default(button);
  CreateCancelButton(window, hbox);

  gtk_widget_show_all(window);
}

/*****************************************************************************************
 * Functions to build radiobuttons to select parameters                                  *
 *****************************************************************************************/

void _RadioParameterChanged(GtkButton *button, unsigned char *val)
/* called when parameters were changed in menu
 * --- Parameter: ---
 * GtkButton     *button : OK-Button of radio button widget, RADIO parameters set as user data
 * unsigned char *val    : address to store the selected value
 */
{
  RADIO *para, *ap;
   
  g_return_if_fail ( button );
  g_return_if_fail ( GTK_IS_BUTTON(button) );
  g_return_if_fail ( (para = gtk_object_get_user_data(GTK_OBJECT(button))) );

  for ( ap = para; ap->name; ap++ )
    if ( (ap->val & 0x80) ) *val = ap->val & (~0x80);
   
  FREE(para);
}

static void _ButtonFunc(GtkWidget *button, unsigned char *val)
{
  RADIO *para, *ap;
   
  g_return_if_fail ( button );
  g_return_if_fail ( GTK_IS_RADIO_BUTTON(button) );
  g_return_if_fail ( (para = gtk_object_get_user_data(GTK_OBJECT(button))) );

  for ( ap = para; ap->name; ap++ ) {
    ap->val &= ~0x80;
    if ( ap->val == *val ) ap->val |= 0x80;
  }
}

GtkWidget *BuildRadioTable(RADIO *para, int np, unsigned char init)
/* build table of radio button parameters to insert in universal parameter entry widget 
 * (BuildParameterInput())
 * --- Parameter: ---
 * RADIO         *para_in          : structure with parameters to change
 * int            np               : number of choices there are
 * unsigned char  init             : value to choose
 * --- Return: ---
 * GtkWidget     *BuildRadioTable(): created radio button widget to obtain values later on
 */
{
  GtkWidget    *vbox,      /* box containing radio buttons */
               *button;    /* Radio buttons                */
  unsigned char i;

  vbox = gtk_vbox_new(FALSE, 5);

  gtk_container_set_border_width(GTK_CONTAINER(vbox), 10);

  button = NULL;
  for ( i = 0; i < np; i++ ) {
    button = gtk_radio_button_new_with_label( 
                     button ? gtk_radio_button_group(GTK_RADIO_BUTTON(button)) : NULL, 
                    (para+i)->name);
    gtk_box_pack_start(GTK_BOX(vbox), button, TRUE, TRUE, 0);
    gtk_object_set_user_data(GTK_OBJECT(button), para);
    gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(_ButtonFunc), &((para+i)->val));
    (para+i)->val &= ~0x80;
    if ( i == init ) {
      gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(button), TRUE);
      (para+i)->val |= 0x80;
    }
  }
  return vbox;
}


/*****************************************************************************************
 * Functions to manipulate image file list                                               *
 *****************************************************************************************/

void UpdateFileList(GList *piclist, GtkCList *filelist)
/* It's necessary to refresh all filelist data (picture list) if the          
 * picture list was changed.  Also all filenames are updated just to be sure. 
 * --- Parameters: ---
 * GList    *piclist  : new picture list
 * GtkCList *filelist : filelist to set with new data
 */
{
  int      row;
  GList   *pl;
  gchar   *buf;
  PICTURE *bild;
   
  if ( !piclist ) return;
  g_return_if_fail ( GTK_IS_CLIST(filelist) );

  gtk_clist_freeze(filelist);
  for ( row = 0, pl = piclist; pl; pl = pl->next, row++ ) {
    g_return_if_fail ( (bild =  BILD(pl)) );
    buf = ImgFileName(bild);
    gtk_clist_set_text(filelist, row, 0, buf);
    gtk_clist_set_row_data(filelist, row, pl);
    FREE(buf);
  }
  gtk_clist_thaw(filelist);
}

void FileListAppend(PAUL *p, PICTURE *bild)
/* append an image to the piclist and update clist entries in the filelist
 * --- Parameters: ---
 * PAUL     *p        : PAUL structure with the list
 * PICTURE  *bild     : picture to append
 */
{
  gchar *buf;
   
  g_return_if_fail ( IS_PAUL(p) );
  g_return_if_fail ( IS_PICTURE(bild) );
  p->piclist = g_list_append(p->piclist, bild);

  if ( !p->filelist ) {
    if ( !gtk_main_level() ) return;
    CreateGtkListOfImages(p);
    return;
  }
  buf = ImgFileName(bild);
  g_return_if_fail ( gtk_clist_append(GTK_CLIST(p->filelist), &buf) >= 0 );
  FREE(buf);
  UpdateFileList(p->piclist, GTK_CLIST(p->filelist));
}

void FileListRemove(PAUL *p, GList *remove)
/* remove an image from the piclist and update clist entries in the filelist
 * --- Parameters: ---
 * PAUL     *p        : PAUL structure with the list
 * GList    *remove   : list with picture to remove
 */
{
  g_return_if_fail ( IS_PAUL(p) );
  g_return_if_fail ( CheckPicList(p->piclist) );
  g_return_if_fail ( CheckPicList(remove) );
  
  if ( p->filelist ) {
    int row;

    g_return_if_fail ( GTK_IS_CLIST(p->filelist) );
    g_return_if_fail ( (row = ROW(p, remove)) >= 0 );
    gtk_clist_remove(GTK_CLIST(p->filelist), row);
  }
  p->piclist = g_list_remove_link(p->piclist, remove);
  if ( !p->filelist ) return;
  
  UpdateFileList(p->piclist, GTK_CLIST(p->filelist));
}

void AddImageToFilelist(PAUL *p, PICTURE *bild)
/* Add one image name to pauls list of images
 */
{
  g_return_if_fail ( IS_PAUL(p) );
  g_return_if_fail ( IS_PICTURE(bild) );
  
  FileListAppend(p, bild);
  if ( !(p->piclist) || !(p->show) ) {
    CreateShowPixmaps(p->activ = p->piclist);
    CreatePicture(p);
  } else {
    GList *pl;
    
    if ( NBILDER(p->piclist) == 2 ) SetAnimateControl(p);

    pl = p->piclist;
    do { 
      gtk_clist_unselect_row(GTK_CLIST(p->filelist), ROW(p, pl), 0); 
    } while ( (pl = pl->next) ) ;
    p->activ   = g_list_last(p->piclist);
  }

  if ( !(bild->im) ) 
     g_return_if_fail ( (bild->im = at_imlib_set_image_from_data(&(bild->DATA), bild->W, bild->H)) );

  SelectAndUpdateInfo(p);
  MenueSensitive(p);
}

void RemoveActivImageFromFilelist(PAUL *p)
/* Remove activ image from pauls list of images
 * --- Parameter: ---
 * PAUL *p              : 
 */
{
  GList   *zl, *pl;
  PICTURE *bild;

  g_return_if_fail ( IS_PAUL(p) );

  if ( !(zl = (p->activ)->next) ) zl = (p->activ)->prev;
  if ( !RemoveImageFromFilelist(p, p->activ) ) {
    p->activ = NULL;
    return;
  }
  /* if there aren't any selected files, select the first */
  for ( bild = BILD(pl = p->piclist); pl && bild; bild = BILD(pl = pl->next) ) 
    if ( bild->mark ) break;
  if ( !pl || !bild ) p->activ = p->piclist;
  else if ( zl ) p->activ = zl;
       else      p->activ = p->piclist;

  SelectAndUpdateInfo(p);
}

GList *RemoveImageFromFilelist(PAUL *p, GList *pl)
/* Remove certain image from pauls list of images
 * --- Parameter: ---
 * PAUL  *p                        : structure with all images
 * GList *pl                       : image to remove
 * --- Return: ---
 * GList *RemoveImageFromFilelist(): following image if exist, else the image before if exist, 
 *                                   else NULL
 */
{
  GList *zl;
   
  g_return_val_if_fail ( IS_PAUL(p), NULL );
  g_return_val_if_fail ( pl, NULL );
   
  if ( !(zl = pl->next) ) zl = pl->prev;
  FileListRemove(p, pl);

  if ( !(p->piclist) || NBILDER(p->piclist) == 1) {
    if ( !p->piclist ) {
      gtk_widget_destroy(p->show);
      p->show = NULL;
      if ( Info(p->opt->f) ) FileInfo(p);
    }
    SetAnimateControl(p);
  }
  MenueSensitive(p);
  return zl;
}

void CreateGtkListOfImages(PAUL *p)
/* Create filelist from picture list
 * --- Parameters: ---
 * PAUL    *p : PAUl structure containing list of images
 */
{
  GList *pl;
  gint   row;
  gchar *buf;
  
  g_return_if_fail ( IS_PAUL(p) );
  
  if ( p->filelist && GTK_IS_CLIST(p->filelist) ) {
     gtk_clist_clear( GTK_CLIST(p->filelist) );
     gtk_widget_destroy(GTK_WIDGET(p->filelist));
  }
  
  p->filelist = (GtkWidget *)gtk_clist_new(1);
  gtk_widget_show(p->filelist);
  gtk_clist_set_selection_mode(GTK_CLIST(p->filelist), GTK_SELECTION_BROWSE);
  gtk_object_set_user_data(GTK_OBJECT(p->filelist), p);
  gtk_clist_set_shadow_type(GTK_CLIST(p->filelist), GTK_SHADOW_IN);
  gtk_clist_set_column_width(GTK_CLIST(p->filelist), 0, 150);

  gtk_clist_freeze(GTK_CLIST(p->filelist));
  for ( pl = p->piclist; pl; pl = pl->next ) {
    buf = ImgFileName(BILD(pl));
    g_return_if_fail ( (row = gtk_clist_append(GTK_CLIST(p->filelist), &buf)) >= 0 );
    FREE(buf);
    gtk_clist_set_row_data(GTK_CLIST(p->filelist), row, pl);
    MarkFilename(p->filelist, row, BILD(pl)->mark);
  }
  gtk_clist_thaw(GTK_CLIST(p->filelist));
  gtk_signal_connect(GTK_OBJECT(p->filelist), "select_row", (GtkSignalFunc) FileListSelectChild, p);
  gtk_signal_connect(GTK_OBJECT(p->filelist), "button_press_event", 
                     (GtkSignalFunc) FileListButtonPressed, p);
}

GList *GetListFromSelection(GList *piclist)
/* obtain image list of given selections in file list
 * --- Parameter: ---
 * GList *piclist                : piclist with images
 * --- Return: ---
 * GList *GetListFromSelection() : List of selected images
 */
{
  GList   *sel = NULL, *pl;
  PICTURE *bild;
   
  g_return_val_if_fail ( CheckPicList(piclist), NULL );

  for ( bild = BILD(pl = piclist); pl && bild; bild = BILD(pl = pl->next) ) 
    if ( bild->mark ) sel = g_list_append(sel, bild);

  return sel;
}

void MakeNewFileList(PAUL *p)
/* Creates a really new filelist (think twice about if this is necessary or if it is
 * enouth to go the way of ApplyPaulFunc()) and creates new gdk_imlib structures
 * (once more: think about if this is necessary)
 * This function makes sense when moving images, because all images were changed
 * completely
 */
{
  g_return_if_fail ( IS_PAUL(p) );
  if ( !(p->filelist) ) return;
  g_return_if_fail ( GTK_IS_CLIST(p->filelist) );
  
  gtk_widget_destroy(GTK_WIDGET(p->filelist));
  CreateGtkListOfImages(p);
  gtk_container_add(GTK_CONTAINER(p->w), (GtkWidget *)p->filelist);

  CreateShowPixmaps(p->piclist);
  if ( !(p->activ) ) p->activ = p->piclist;
  UPDATE_IMAGE = 1;

  SelectAndUpdateInfo(p);
}

/*****************************************************************************************
 * Functions which are useful for almost all callbacks                                   *
 *****************************************************************************************/

static gint ClistFindRowFromImage(GtkCList *clist, PICTURE *bild)
/* This is a changed gtk_clist_find_row_from_data() 
 * It was necessary due to the fact, that we work with a changed piclist for marked images
 * and so the GList-typed data of the filelist doesn't work with the temporary piclist
 * That's why we compare the real image data of the GLists here
 * --- Parameter: ---
 * GtkCList *clist                  : filelist
 * PICTURE  *bild                   : image to search in filelist
 * --- Return: ---
 * gint      ClistFindRowFromImage(): row of the image
 */
{
  GList *list;
  gint   n;

  g_return_val_if_fail ( clist != NULL , -1);
  g_return_val_if_fail ( GTK_IS_CLIST(clist) , -1);
  g_return_val_if_fail ( IS_PICTURE(bild), -1 );

  for (n = 0, list = clist->row_list; list; n++, list = list->next)
    if ( ((GList *)(GTK_CLIST_ROW(list)->data))->data == bild)
      return n;

  return -1;
}

void RefreshImage(GtkCList *list, GList *pl)
/* make new entry in filelist and inform imlib about changes
 * --- Parameter: ---
 * GtkCList *list : list of image file names
 * GList    *pl   : pl->data = PICTURE structure
 */
{
  PICTURE *bild;
  gchar   *buf;
  gint     row;

  g_return_if_fail ( list ) ;
  g_return_if_fail ( GTK_IS_CLIST(list) ) ;
  g_return_if_fail ( pl ) ;
  g_return_if_fail ( (bild = BILD(pl)) ) ;

  g_return_if_fail ( (buf = ImgFileName(bild)) );
  g_return_if_fail ( (row = ClistFindRowFromImage(GTK_CLIST(list), bild)) >= 0 ) ;
  gtk_clist_set_text(list, row, 0, buf);
  FREE(buf);
  if ( bild->im ) gdk_imlib_changed_image(bild->im);
  else g_return_if_fail ((bild->im = at_imlib_set_image_from_data(&(bild->DATA), bild->W, bild->H)));
}

void ApplyPaulFunc(PAUL *p, void *func, int func_type, int which, int freeze)
/* apply function to activ image, marked images or all of PAUL
 * --- Parameters: ---
 * PAUL *p         : PAUL structure with images
 * void *func      : function to apply
 * int   func_type : type of function (whether to pass PAUL structure or only picture list as parameter
 * int   which     : which image(s) should be handled
 * int   freeze    : flag wether to set p->w insensitive or not (to give a hint for longer
 *                   working process
 */
{
  GList *pl = NULL, *ml = NULL;

  g_return_if_fail ( IS_PAUL(p) ) ;
  if ( !(p->piclist) ) return ;
  g_return_if_fail ( CheckPicList(p->piclist) ) ;
  g_return_if_fail ( p->filelist ) ;
  g_return_if_fail ( GTK_IS_CLIST(p->filelist) ) ;
  
  if ( freeze ) gtk_widget_set_sensitive(GTK_WIDGET(p->w), FALSE);

  if ( which == MARK )      pl = ml = GetListFromSelection(p->piclist);
  else if ( which == THIS ) pl = g_list_append(NULL, BILD(p->activ));
  /* if ( which == ALL ) pl remains NULL !!! */
   
  if ( func_type == PAUL_FUNC_TYPE ) {
    if ( pl ) {
      if ( p->spiclist ) {
        g_warning(_("Please wait until your previous operation is finished."));
        return;
      }
      p->spiclist = p->piclist;
      p->piclist  = pl;
    }
    if ( RET_SPECIAL == ((PAUL_FUNC)func)(p) ) return;
    if ( pl && p->spiclist ) {
      p->piclist  = p->spiclist;
      p->spiclist = NULL;
    }
  } else {
    if ( pl ) ((PICLIST_FUNC)func)(pl);
    else      ((PICLIST_FUNC)func)(p->piclist);  /* this is done for ALL */
  }

/* wenn cutimage hier schluß machen und vorher nicht freigeben */  
  switch ( which ) {
    case MARK: 
      if ( (pl = ml) ) {
        do {
          RefreshImage(GTK_CLIST(p->filelist), pl);
        } while ( (pl = pl->next) );
        g_list_free(ml);
      }
      break;
      
    case ALL:
      pl = p->piclist;
      do {
        RefreshImage(GTK_CLIST(p->filelist), pl);
      } while ( (pl = pl->next) );
      break;
      
    case THIS:
      RefreshImage(GTK_CLIST(p->filelist), p->activ);
      if ( pl ) g_list_free(pl);
      break;
      
    default:
      g_return_if_fail ( which == THIS );
      return;
  }
  ApplyPicture(p->show->window, BILD(p->activ));
  if ( freeze ) gtk_widget_set_sensitive(GTK_WIDGET(p->w), TRUE);
  if ( Info(p->opt->f) ) FileInfo(p);
}

void SelectAndShowActiv(PAUL *p)
/* while selecting the row of the active image it is displayed because of the callback
 * functions in the clist
 * This is mainly a wrapper function
 */ 
{ 
  register int i;
   
  g_return_if_fail ( IS_PAUL(p) ) ;
  g_return_if_fail ( p->filelist ) ;
  g_return_if_fail ( GTK_IS_CLIST(p->filelist) ) ;
  g_return_if_fail ( CheckPicList(p->activ) );
  
  UPDATE_IMAGE = 1;
  gtk_clist_select_row(GTK_CLIST(p->filelist), i = ACT_ROW(p), 0);
  if ( gtk_clist_row_is_visible(GTK_CLIST(p->filelist), i) < 2 ) 
    gtk_clist_moveto(GTK_CLIST(p->filelist), i, 0, 0.5, 0.0);
}

void SelectAndUpdateInfo(PAUL *p)
/* In FileInfo there is a call to SelectAndShowActive().  That's why we make sure
 * that it isn't called twice (especially because the second call is suspected to
 * have wrong data in some cases!!!)
 */ 
{ 
  g_return_if_fail ( IS_PAUL(p) ) ;

  if ( Info(p->opt->f) ) FileInfo(p);
  else                   SelectAndShowActiv(p);
}

/*****************************************************************************************
 * Miscellaneous functions                                                               *
 *****************************************************************************************/

int NumSelections(GList *piclist)
/* returns number of selected images
 */
{
  GList *pl;
  PICTURE *bild;
  int      n = 0;
   
  for ( bild = BILD(pl = piclist); pl && bild; bild = BILD(pl = pl->next)) 
    if ( bild->mark ) n++;

  return n;
}

void MenueSensitive(PAUL *p)
/* Make animate button sensitive or insensitive
 */
{
#define NUM_SENSITIVE_MENUS 7
  char            *text, *strip;
  int              i;
  typedef struct { 
    GtkWidget     *menu;
    GtkTooltips   *tooltips;
  } MENU_SENS;
  
  MENU_SENS       *mp;
  static MENU_SENS menusens[NUM_SENSITIVE_MENUS];
  const char      *main_menue[NUM_SENSITIVE_MENUS] = { This, This, Marked, All, This, Marked, All },
                  *item[NUM_SENSITIVE_MENUS] = { _Insert, _Difference, _Difference, _Difference,
                                                 Mo_ve, Mo_ve, Mo_ve },
              *tt[NUM_SENSITIVE_MENUS]   = { InsertTta, DifferenceTta, DifferenceTma, DifferenceTaa,
                                                 MoveTta, MoveTma, MoveTaa };
                                         
  g_return_if_fail ( IS_PAUL(p) ) ;
  g_return_if_fail ( p->items ) ;
  g_return_if_fail ( GTK_IS_ITEM_FACTORY(p->items) ) ;

  for ( mp = menusens, i = 0; i < NUM_SENSITIVE_MENUS; mp++, i++ ) {
    if ( !(mp->menu) ) {
      text     = g_strdup_printf("/%s/%s", main_menue[i], item[i]);
      strip    = RemoveUnderscore(text);
      mp->menu = gtk_item_factory_get_widget(p->items, strip);
      FREE(text);
      FREE(strip);
      g_return_if_fail ( mp->menu ) ;
    }
    g_return_if_fail ( GTK_IS_WIDGET(mp->menu) ) ;

    if ( !(mp->tooltips) ) {
      GdkColor bg, fg;

      mp->tooltips = gtk_tooltips_new();
      fg.red       = fg.green = fg.blue = 0;
      gdk_color_alloc(gtk_widget_get_colormap(mp->menu), &fg);
      bg.red       = 61669;
      bg.green     = 59113;
      bg.blue      = 35979;
      gdk_color_alloc(gtk_widget_get_colormap(mp->menu), &bg);
      gtk_tooltips_set_colors(mp->tooltips, &bg, &fg);
    }
  
    g_return_if_fail ( GTK_IS_WIDGET(mp->menu) ) ;

/* Telling the user *what* to insert would be nice but did not work this way.
   The menue isn't updated despite the widget name changed correctly.
   Furthermore an else branch is neccessary!! ... Possibly we do it inside the
   if ( p->opi ... ) - else - branch
    if ( IS_PICTURE(p->op) ) {
      if ( (strip = gtk_widget_get_name(menu)) &&
           (text  = strchr(strip, ' ') ) ) {
        *text = 0;
        text = g_strdup_printf(_("%s %s"), strip, p->op->file);
        gtk_widget_set_name(menu, text);
        gtk_widget_show(menu);
        FREE(text);
      }
    }
 */
  
    if ( p->opi && GTK_IS_WINDOW(p->opi) && IS_PICTURE(p->op) && p->piclist ) {
      g_return_if_fail ( CheckPicList(p->piclist) ) ;
      text = g_strdup_printf(tt[i], p->op->file);
      gtk_tooltips_set_tip(mp->tooltips, mp->menu, text, NULL);
      FREE(text);
   
      gtk_widget_set_sensitive(mp->menu, TRUE);
    } else
      gtk_widget_set_sensitive(mp->menu, FALSE);
  }
/* printf("%s(%i)\n", __FILE__, __LINE__); */
  
}

/*****************************************************************************************
 * Functions to handle animate button                                                    *
 *****************************************************************************************/

int SetAnimateControl(PAUL *p)
/* Set/Unset button at bottom line
 * --- Parameter: ---
 * PAUL          *p     :
 */
{
  g_return_val_if_fail ( IS_PAUL(p), RET_ERR ) ;
  g_return_val_if_fail ( p->ctrl, RET_ERR ) ;
  g_return_val_if_fail ( GTK_IS_NOTEBOOK(p->ctrl), RET_ERR ) ;

  if ( NBILDER(p->piclist) < 2 ) {
    if ( GTK_WIDGET_VISIBLE(p->ctrl) ) gtk_widget_hide(p->ctrl);
    return RET_OK;
  }

  gtk_notebook_set_page(GTK_NOTEBOOK(p->ctrl), 0);
  gtk_widget_show_all(p->ctrl);
  return RET_OK;
}

int ButtonSensitive(PAUL *p)
/* Make animate button sensitive or insensitive
 */
{
  GtkWidget *bb, *bs, *bf;
   
  g_return_val_if_fail ( IS_PAUL(p), RET_ERR ) ;
  g_return_val_if_fail ( p->ctrl, RET_ERR ) ;
  g_return_val_if_fail ( GTK_IS_NOTEBOOK(p->ctrl), RET_ERR ) ;
  g_return_val_if_fail ( (bb = gtk_object_get_user_data(GTK_OBJECT(p->ctrl))), RET_ERR );
  g_return_val_if_fail ( GTK_IS_BUTTON(bb), RET_ERR ) ;
  g_return_val_if_fail ( (bs = gtk_object_get_user_data(GTK_OBJECT(bb))), RET_ERR );
  g_return_val_if_fail ( GTK_IS_BUTTON(bs), RET_ERR ) ;
  g_return_val_if_fail ( (bf = gtk_object_get_user_data(GTK_OBJECT(bs))), RET_ERR );
  g_return_val_if_fail ( GTK_IS_BUTTON(bf), RET_ERR ) ;
  g_return_val_if_fail ( bb == gtk_object_get_user_data(GTK_OBJECT(bf)), RET_ERR );

  if ( NumSelections(p->piclist) > 1 ) {
    gtk_widget_set_sensitive(bb, TRUE);
    gtk_widget_set_sensitive(bf, TRUE);
  } else {
    gtk_widget_set_sensitive(bb, FALSE);
    gtk_widget_set_sensitive(bf, FALSE);
  } 
  gtk_widget_set_sensitive(bs, FALSE);
  return RET_OK;
}




Generated by  Doxygen 1.6.0   Back to index