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

gdl_ctree.c

/* dc_gui2 - a GTK+2 GUI for DCTC
 * Copyright (C) 2002 Eric Prevoteau
 *
 * gdl_ctree.c: Copyright (C) Eric Prevoteau <www@a2pb.gotdns.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */
/*
$Id: gdl_ctree.c,v 1.5 2003/12/26 14:35:04 uid68112 Exp $
*/

#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <gnome.h>

#include "gtkcellrenderertextx.h"
#include "gtkcellrendererpixbufx.h"
#include "misc_gtk.h"
#include "gdl_ctree.h"
#include "main.h"
#include "gui_define.h"
#include "macro.h"
#include "dctc_process.h"
#include "global_user.h"

/*********************************/
/* force refresh of the GDL list */
/*********************************/
static void update_lists_force_gdl(const GString *s)
{
      send_data_to_gdl_dctc("/GDLLST\n");
}


/* ------------------------------------------------------------------------------------------------------------- */
/*************************************/
/* kill the given entry of the ctree */
/*************************************/
/* GTK2: to test */
/*****************/
static void kill_this_gdl_entry(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
{
      guint ct_type;

      gtk_tree_model_get(model,iter,GCC_TYPE,&ct_type,-1);

      switch(ct_type)
      {
            case GDL_ROOT:
                                          /* GDL ID level */
                                          {
                                                GString *str;
                                                gulong gdl_id;
                                                gtk_tree_model_get(model,iter,GCC_ID,&gdl_id,-1);

                                                str=g_string_new("/GDLEND ");
                                                g_string_sprintfa(str,"%lu\n",gdl_id);
                                                send_data_to_gdl_dctc(str->str);
                                                g_string_free(str,TRUE);
                                          }
                                          break;

            case GDL_SEARCH_PATTERN:
                                          {
                                                GtkTreeIter parent_iter;
                                                guint parent_ct_type;

                                                if(gtk_tree_model_iter_parent (model,&parent_iter,iter))
                                                {
                                                      gtk_tree_model_get(model,&parent_iter,GCC_TYPE,&parent_ct_type,-1);
                                                      if(parent_ct_type==GDL_ROOT)
                                                      {
                                                            GString *str;
                                                            gulong gdl_id;
                                                            gulong autoscan_id;
      
                                                            gtk_tree_model_get(model,&parent_iter,GCC_ID,&gdl_id,-1);
                                                            gtk_tree_model_get(model,iter,GCC_ID,&autoscan_id,-1);

                                                            str=g_string_new("");
                                                            g_string_sprintf(str,"/GDLAS- %lu|%lu\n",gdl_id,autoscan_id);
                                                            send_data_to_gdl_dctc(str->str);
                                                            g_string_free(str,TRUE);
                                                      }
                                                }
                                          }
                                          break;

            case GDL_ACTIVE_SEGMENT:
                                          {
                                                guint parent_ct_type;
                                                GtkTreeIter parent_iter;

                                                if(gtk_tree_model_iter_parent (model,&parent_iter,iter))
                                                {
                                                      gtk_tree_model_get(model,&parent_iter,GCC_TYPE,&parent_ct_type,-1);
                                                      if(parent_ct_type==GDL_ROOT)
                                                      {
                                                            GString *str;
                                                            gulong gdl_id;
                                                            GLOB_USER *gu;
                                                            char *remote_filename;
            
                                                            gtk_tree_model_get(model,&parent_iter,GCC_ID,&gdl_id,-1);
                                                            gtk_tree_model_get(model,iter,GCC_MISC_POINTER,&gu,GCC_STR2,&remote_filename,-1);

                                                            str=g_string_new("");
                                                            g_string_sprintf(str,"/GDLDEL %lu|%s|%s\n",gdl_id, gu->unfmt_nick, remote_filename);
                                                            send_data_to_gdl_dctc(str->str);
                                                            g_string_free(str,TRUE);
                                                            free(remote_filename);
                                                      }
                                                }
                                          }
                                          break;
      
            case GDL_STORED_SEGMENT:            /* nothing can be done here*/
                                          break;

            case GDL_RENAME_AT_END:
                                          {
                                                guint parent_ct_type;
                                                GtkTreeIter parent_iter;

                                                if(gtk_tree_model_iter_parent (model,&parent_iter,iter))
                                                {
                                                      gtk_tree_model_get(model,&parent_iter,GCC_TYPE,&parent_ct_type,-1);
                                                      if(parent_ct_type==GDL_ROOT)
                                                      {
                                                            GString *str;
                                                            gulong gdl_id;
      
                                                            gtk_tree_model_get(model,&parent_iter,GCC_ID,&gdl_id,-1);
      
                                                            str=g_string_new("");
                                                            g_string_sprintf(str,"/GDLNORENAME %lu\n",gdl_id);
                                                            send_data_to_gdl_dctc(str->str);
                                                            g_string_free(str,TRUE);
                                                      }
                                                }
                                          }
                                          break;

            case GDL_SCRIPT_AT_END:
                                          {
                                                guint parent_ct_type;
                                                GtkTreeIter parent_iter;

                                                if(gtk_tree_model_iter_parent (model,&parent_iter,iter))
                                                {
                                                      gtk_tree_model_get(model,&parent_iter,GCC_TYPE,&parent_ct_type,-1);
                                                      if(parent_ct_type==GDL_ROOT)
                                                      {
                                                            GString *str;
                                                            gulong gdl_id;
      
                                                            gtk_tree_model_get(model,&parent_iter,GCC_ID,&gdl_id,-1);

                                                            str=g_string_new("");
                                                            g_string_sprintf(str,"/GDLNOSCRIPT %lu\n",gdl_id);
                                                            send_data_to_gdl_dctc(str->str);
                                                            g_string_free(str,TRUE);
                                                      }
                                                }
                                          }
                                          break;

            default:                break;
      }
}

/* ------------------------------------------------------------------------------------------------------------- */
/*****************************/
/* kill selected GDL entries */
/*****************************/
/* GTK2: to test */
/*****************/
void kill_selected_gdl_entry(void)
{
      GtkWidget *w;
      GtkTreeSelection *slc;

      /* get the nickname of the remote side of the private chat */
      w=get_widget_by_widget_name(main_window,"gdl_ctree");
      if(w==NULL)
            return;

      slc=gtk_tree_view_get_selection(GTK_TREE_VIEW(w));
      gtk_tree_selection_selected_foreach(slc,kill_this_gdl_entry,NULL);

      update_lists_force_gdl(NULL);
}

/* ------------------------------------------------------------------------------------------------------------- */
/***************************************/
/* detach the given entry of the ctree */
/***************************************/
/* GTK2: to test */
/*****************/
static void detach_this_gdl_entry(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
{
      guint ct_type;
      gulong gdl_id;

      gtk_tree_model_get(model,iter,GCC_TYPE,&ct_type,GCC_ID,&gdl_id,-1);
      if(ct_type==GDL_ROOT)
      {
            GString *str;

            str=g_string_new("/GDLDETACH ");
            g_string_sprintfa(str,"%lu\n",gdl_id);
            send_data_to_gdl_dctc(str->str);
            g_string_free(str,TRUE);
      }
}

/* ------------------------------------------------------------------------------------------------------------- */
/*******************************/
/* detach selected GDL entries */
/*******************************/
void detach_selected_gdl_entry(void)
{
      GtkWidget *w;
      GtkTreeSelection *slc;

      /* get the nickname of the remote side of the private chat */
      w=get_widget_by_widget_name(main_window,"gdl_ctree");
      if(w==NULL)
            return;

      slc=gtk_tree_view_get_selection(GTK_TREE_VIEW(w));
      gtk_tree_selection_selected_foreach(slc,detach_this_gdl_entry,NULL);

      update_lists_force_gdl(NULL);
}

/* ---------------------------------------------------------------------------------------------------- */
typedef struct
{
      void (**fnc)(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data);   /* fnc is an array of GDL_NUMBER_OF_GDL_CT_TYPE function addresses */
      void *data;
} TMP_GSGEL_CALL;

/*********************************************/
/* for each selected GDL entry, apply a task */
/*********************************************/
/* GTK2: to test */
/*****************/
static void for_a_selected_gdl_ctree_row(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
{
      guint type;
      TMP_GSGEL_CALL *tgc=data;

      gtk_tree_model_get(model,iter,GCC_TYPE,&type,-1);
      if(tgc->fnc[type]!=NULL)
            (*(tgc->fnc[type]))(model,path,iter,tgc->data);
}

/**************************************************************************************/
/* this function calls the given fnc for each selected entry of the "gdl_ctree" clist */
/**************************************************************************************/
/* fnc is an array of GDL_NUMBER_OF_GDL_CT_TYPE pointers, 1 pointer per GDL_CT_TYPE */
/* a NULL pointer means the entry is not processed                                  */
/************************************************************************************/
/* GTK2: to test */
/*****************/
void generic_selected_gdl_entry_list_calls(void (*fnc[GDL_NUMBER_OF_GDL_CT_TYPE])(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data), void *data)
{
   GtkWidget *w;
      GtkTreeSelection *slc;
      TMP_GSGEL_CALL tgc;

   w=get_widget_by_widget_name(main_window,"gdl_ctree");
   if(w==NULL)
      return;

      tgc.fnc=fnc;
      tgc.data=data;

      slc=gtk_tree_view_get_selection(GTK_TREE_VIEW(w));
      gtk_tree_selection_selected_foreach(slc,for_a_selected_gdl_ctree_row,&tgc);
}


/* ---------------------------------------------------------------------------------------------------- */
static inline int gce_comp_gulong(GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, int comp_col)
{
      gulong va,vb;
      gtk_tree_model_get(model,a,comp_col,&va,-1);
      gtk_tree_model_get(model,b,comp_col,&vb,-1);
      if(va<vb)
            return -1;
      if(va>vb)
            return 1;
      return 0;
}

static inline int gce_comp_str(GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, int comp_col)
{
      char *va,*vb;
      int ret;

      gtk_tree_model_get(model,a,comp_col,&va,-1);
      gtk_tree_model_get(model,b,comp_col,&vb,-1);
      ret=strcmp(va,vb);
      free(va);
      free(vb);
      return ret;
}

static inline int gce_comp_glob_user(GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, int comp_col)
{
      GLOB_USER *va, *vb;
      int ret;

      gtk_tree_model_get(model,a,comp_col,&va,-1);
      gtk_tree_model_get(model,b,comp_col,&vb,-1);
      ret=strcmp(va->unfmt_nick,vb->unfmt_nick);
      return ret;
}

/*****************************************************/
/* handle special column sorting for gcl_tree column */
/*****************************************************/
static gint gce_sort(GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer user_data)
{
      gint col=GPOINTER_TO_INT(user_data);
      guint typea,typeb;
      int v;

      gtk_tree_model_get(model,a,GCC_TYPE,&typea,-1);
      gtk_tree_model_get(model,b,GCC_TYPE,&typeb,-1);

      /* type must be comparable */
      if(typea!=typeb)
      {
            if(typea<typeb)
                  return -1;
            return 1;
      }

      switch(typea)
      {
            case GDL_ROOT:
                                                            switch(col)
                                                            {
                                                                  case GCC_GID_NICK_COL:  return gce_comp_gulong(model,a,b,GCC_ID);
                                                                  case GCC_FULL_PATH_COL: return gce_comp_str(model,a,b,GCC_STR1);
                                                                  case GCC_SIZE_COL:      return gce_comp_gulong(model,a,b,GCC_VAL1);
                                                                  case GCC_STATUS_COL:    return gce_comp_gulong(model,a,b,GCC_RECEIVED_BYTES);
                                                            }
                                                            break;
            case GDL_SEARCH_PATTERN:
                                                            switch(col)
                                                            {
                                                                  case GCC_GID_NICK_COL:  return gce_comp_gulong(model,a,b,GCC_ID);
                                                                                    
                                                                  case GCC_SIZE_COL:
                                                                  case GCC_STATUS_COL:
                                                                  case GCC_FULL_PATH_COL:
                                                                                    v=gce_comp_gulong(model,a,b,GCC_VAL1);
                                                                                    if(v)
                                                                                          return v;
                                                                                    return gce_comp_str(model,a,b,GCC_STR1);
                                                            }
                                                            break;

            case GDL_ACTIVE_SEGMENT:
                                                            switch(col)
                                                            {
                                                                  case GCC_GID_NICK_COL:  return gce_comp_glob_user(model,a,b,GCC_MISC_POINTER);
                                                                  case GCC_FULL_PATH_COL: return gce_comp_str(model,a,b,GCC_STR2);
                                                                  case GCC_SIZE_COL:      return gce_comp_gulong(model,a,b,GCC_VAL1);
                                                                  case GCC_STATUS_COL:    return gce_comp_str(model,a,b,GCC_STR3);
                                                            }
                                                            break;

            case GDL_STORED_SEGMENT:
                                                            switch(col)
                                                            {
                                                                  case GCC_FULL_PATH_COL: return gce_comp_str(model,a,b,GCC_STR1);

                                                                  case GCC_GID_NICK_COL:
                                                                  case GCC_SIZE_COL:
                                                                  case GCC_STATUS_COL:    
                                                                                                {
                                                                                                      char *va,*vb;
                                                                                                      int ret=0;

                                                                                                      gtk_tree_model_get(model,a,GCC_STR2,&va,-1);
                                                                                                      gtk_tree_model_get(model,b,GCC_STR2,&vb,-1);
                                                                                                      if((va[0]=='[')&&(vb[0]=='['))
                                                                                                            ret=atoi(va+1)-atoi(vb+1);
                                                                                                      else
                                                                                                            printf("gdl_ctree_sort_fnc: ???\n");
                                                                                                      free(va);
                                                                                                      free(vb);
                                                                                                      return ret;
                                                                                                }
                                                            }
                                                            break;

            case GDL_RENAME_AT_END: /* column is not meaningful here */
                                                            return gce_comp_str(model,a,b,GCC_STR2);
                                                            break;

            default:                                  break;
      }
      return 0;
}


/************************************************/
/* update user information using GLOB_USER data */
/************************************************/
static void gdl_ctree_user_info_update_row(GtkTreeModel *gtm, GtkTreePath *gtp, GtkTreeIter *gti, gpointer user_data)
{
      GLOB_USER *gu;
      guint type;

      /* get GLOB_USER entry to use */
      gtk_tree_model_get(gtm,gti,GCC_TYPE,&type,GCC_MISC_POINTER,&gu,-1);

      if(type!=GDL_ACTIVE_SEGMENT)
            return;

      /* block the update signal on this function */
      g_signal_handlers_block_matched (G_OBJECT(gtm),G_SIGNAL_MATCH_FUNC,0,0,NULL,gdl_ctree_user_info_update_row,NULL);

      /* update user info */
      gtk_tree_store_set(GTK_TREE_STORE(gtm),gti,
                                                                        GCC_GID_NICK_COL,gu->fmt_nick,
                                                                        GCC_LINE_BACKGROUND,gu->back_present_color,
                                                                        GCC_LINE_FOREGROUND,gu->front_color,
                                                                        -1);

      /* unblock the update signal on this function */
      g_signal_handlers_unblock_matched (G_OBJECT(gtm),G_SIGNAL_MATCH_FUNC,0,0,NULL,gdl_ctree_user_info_update_row,NULL);
}

/*******************************************/
/* build modele and view for the gdl ctree */
/*******************************************/
void bmav4_gdl_ctree(void)
{
      GtkTreeStore *model;
      GtkWidget *view;
      GtkCellRenderer *rend;
      GtkTreeSelection *slc;

      model=gtk_tree_store_new(NB_GCC_COL,G_TYPE_STRING,G_TYPE_BOOLEAN,G_TYPE_BOOLEAN,G_TYPE_STRING,GDK_TYPE_PIXBUF,G_TYPE_STRING,
                                                                              G_TYPE_STRING,G_TYPE_FLOAT,G_TYPE_STRING,
                                                                              G_TYPE_STRING,
                                                                              G_TYPE_UINT, G_TYPE_ULONG,G_TYPE_STRING,
                                                                              G_TYPE_ULONG,G_TYPE_STRING,G_TYPE_STRING,
                                                                              G_TYPE_ULONG,G_TYPE_ULONG,G_TYPE_UINT64,
                                                                              G_TYPE_ULONG, G_TYPE_POINTER, G_TYPE_BOOLEAN);
      g_signal_connect_after(G_OBJECT(model),"row-changed",G_CALLBACK(gdl_ctree_user_info_update_row),NULL);

      gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(model),GCC_GID_NICK_COL,gce_sort,GINT_TO_POINTER(GCC_GID_NICK_COL),NULL);
      gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(model),GCC_FULL_PATH_COL,gce_sort,GINT_TO_POINTER(GCC_FULL_PATH_COL),NULL);
      gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(model),GCC_SIZE_COL,gce_sort,GINT_TO_POINTER(GCC_SIZE_COL),NULL);
      gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(model),GCC_STATUS_COL,gce_sort,GINT_TO_POINTER(GCC_STATUS_COL),NULL);

      view=get_widget_by_widget_name(main_window,"gdl_ctree");

      gtk_tree_view_set_model(GTK_TREE_VIEW(view),GTK_TREE_MODEL(model));
      gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(view),TRUE);

      slc=gtk_tree_view_get_selection(GTK_TREE_VIEW(view));
      gtk_tree_selection_set_mode(slc,GTK_SELECTION_MULTIPLE);

      /* the first column of the view display the first column of the model, and so on. The 4th entry of the model is not displayed */
      {
            GtkTreeViewColumn *MYcol;                                                                                                       

            MYcol=gtk_tree_view_column_new();
            gtk_tree_view_column_set_title(MYcol,_("GID/nickname"));
            gtk_tree_view_column_set_resizable(MYcol,TRUE);
            gtk_tree_view_column_set_sort_column_id(MYcol,GCC_GID_NICK_COL);

            /* pack the pixbuf */
            rend=gtk_cell_renderer_pixbufx_new();
            g_object_set(rend,"rowspacing",TRUE,NULL);
            gtk_tree_view_column_pack_end(MYcol,rend,TRUE);
            gtk_tree_view_column_add_attribute(MYcol,rend,"pixbuf",GCC_PIXBUF);
            gtk_tree_view_column_add_attribute(MYcol,rend,"visible",GCC_GID_NICK_NOT_VISI);
            gtk_tree_view_column_add_attribute(MYcol,rend,"background",GCC_LINE_BACKGROUND);

            /* and the image */
            rend=gtk_cell_renderer_textx_new();
            g_object_set(rend,"rowspacing",TRUE,NULL);
            gtk_tree_view_column_pack_end(MYcol,rend,TRUE);
            gtk_tree_view_column_add_attribute(MYcol,rend,"background",GCC_LINE_BACKGROUND);
            gtk_tree_view_column_add_attribute(MYcol,rend,"foreground",GCC_LINE_FOREGROUND);
            gtk_tree_view_column_add_attribute(MYcol,rend,"text",GCC_GID_NICK_COL);
            gtk_tree_view_column_add_attribute(MYcol,rend,"visible",GCC_GID_NICK_VISI);

            gtk_tree_view_insert_column(GTK_TREE_VIEW(view),MYcol,GCC_GID_NICK_COL);                                                             
            gtk_tree_view_set_expander_column(GTK_TREE_VIEW(view),MYcol);
      }

      {
            GtkTreeViewColumn *MYcol;                                                                                                       

            MYcol=gtk_tree_view_column_new();
            gtk_tree_view_column_set_title(MYcol,_("Filename"));
            gtk_tree_view_column_set_resizable(MYcol,TRUE);
            gtk_tree_view_column_set_sort_column_id(MYcol,GCC_FULL_PATH_COL);

            rend=gtk_cell_renderer_textx_new();
            g_object_set(rend,"rowspacing",TRUE,NULL);
            gtk_tree_view_column_pack_end(MYcol,rend,TRUE);
            gtk_tree_view_column_add_attribute(MYcol,rend,"text",GCC_FULL_PATH_COL);
            gtk_tree_view_column_add_attribute(MYcol,rend,"background",GCC_LINE_BACKGROUND);
            gtk_tree_view_column_add_attribute(MYcol,rend,"foreground",GCC_LINE_FOREGROUND);

            gtk_tree_view_insert_column(GTK_TREE_VIEW(view),MYcol,GCC_FULL_PATH_COL);                                                            
      }

      rend=gtk_cell_renderer_textx_new();
      g_object_set(rend,"rowspacing",TRUE,NULL);
      MY_RS_gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(view),GCC_SIZE_COL,_("Size"),rend,"text",GCC_SIZE_COL,"xalign",GCC_SIZE_RIGHT_ALIGN,"foreground",GCC_LINE_FOREGROUND,"background",GCC_LINE_BACKGROUND,NULL);

      rend=gtk_cell_renderer_textx_new();
      g_object_set(rend,"rowspacing",TRUE,NULL);
      MY_RS_gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(view),GCC_STATUS_COL,_("Status"),rend,"text",GCC_STATUS_COL,"foreground",GCC_LINE_FOREGROUND,"background",GCC_LINE_BACKGROUND,NULL);


      /* The view now holds a reference.  We can get rid of our own
       * reference */
      g_object_unref (G_OBJECT (model));
}


Generated by  Doxygen 1.6.0   Back to index