File: selectlist.c

package info (click to toggle)
gtoaster 0.19991130-1
  • links: PTS
  • area: main
  • in suites: potato
  • size: 1,700 kB
  • ctags: 1,318
  • sloc: ansic: 12,739; sh: 353; makefile: 217; sed: 93
file content (315 lines) | stat: -rw-r--r-- 7,741 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
/* some helper functions for selection lists,
 * (used e.g. by filelist.c) */

#include "int.h"

#include <gtk/gtk.h>
#include <string.h>
#include <stdlib.h>

#include "main.h"
#include "dndsetup.h"
#include "selectlist.h"
#include "doubleclick.h"
#include "menusys.h"
#include "helpings.h"

/* uncomment for debugging */
/* #define DEBUG */

/* non-public callback functions */

void selectlist_drag(GtkWidget *w,
		     GdkDragContext *ct,
		     GtkSelectionData *data,
		     guint inf,
		     guint time,
		     selectlist_info *info)
{

   gtk_selection_data_set (data,
			   data->target,
			   8,
			   selectlist_getselection(info),
			   strlen(selectlist_getselection(info)));
   info->is_drag_source=1;
}
;

void selectlist_dragdone(GtkWidget *w,
			 GdkDragContext *c,
			 selectlist_info *info)
{
	gtk_clist_unselect_all(GTK_CLIST(w));
	info->is_drag_source=0;
}
;
	

void selectlist_drop(GtkWidget *w,
	      GdkDragContext *c,
	      gint x,
	      gint y,
	      GtkSelectionData *data,
	      guint inf,
	      guint time,
	      selectlist_info *info)
{
	if ((data->length>=0) && (data->format == 8) 
	    && (info->receiver!=NULL))
	  {
		  info->receiver((gchar*)data->data,x,y);
		  gtk_drag_finish (c,TRUE,FALSE,time);
		  return;
	  }
	;
	gtk_drag_finish (c,FALSE,FALSE,time);
}
;

void selectlist_appendselection(char *s,char *h,char *f) // selectionlist,header,file
{
	char *entry;
	char *cmpcopy;

/* #ifdef DEBUG
	printf ("adding selection \"%s%s\"\n to \"%s\"\n",h,f,s);
#endif 
 */
	cmpcopy=(char*)malloc(SELECTLIST_MAXSELSIZE);
	strcpy(cmpcopy,CRLF);
	strcat(cmpcopy,s);
	
	entry=(char*)malloc(1024);
	strcpy(entry,CRLF);
	strcat(entry,h);
	strcat(entry,f);       
	strcat(entry,CRLF); // entry=CRLF+header+file+CRLF
	
	if ((strstr(cmpcopy,entry)==NULL)&&
	    (strlen(h)+strlen(f)+strlen(CRLF)+strlen(s)<SELECTLIST_MAXSELSIZE))
	  {
		  strcat(s,h);
		  strcat(s,f);
		  strcat(s,CRLF);
	  }
	;
	free(entry);free(cmpcopy);
}
;

/* this function is currently unused - but it is a nice piece of code
 * which we may need again later,so let's just keep it for a while */
void selectlist_removeselection(char *s,char *h,char *f)  // see above
{
	char *entry;
	char *cmpcopy;
	char *foundpos;

   
/*#ifdef DEBUG
	printf ("removing selection %s%s\n",h,f);
#endif
*/	
	cmpcopy=(char*)malloc(SELECTLIST_MAXSELSIZE);
	strcpy(cmpcopy,CRLF);
	strcat(cmpcopy,s);
	
	entry=(char*)malloc(1024);
	strcpy(entry,CRLF);
	strcat(entry,h);
	strcat(entry,f);       
	strcat(entry,CRLF); // entry=CRLF+header+file+CRLF
		
	foundpos=strstr(cmpcopy,entry);
	while (foundpos!=NULL)
	  {
		  strcpy(foundpos,(char*)((int)foundpos+strlen(entry)-2));
		  foundpos=strstr(cmpcopy,entry);
	  }
	;
	strcpy(s,&cmpcopy[2]);        // cut leading cr+lf
	free(entry);free(cmpcopy);
}
;
	

void selectlist_select(GtkCList *clist,gint row,gint column,
		       GdkEventButton *event, selectlist_info *info)
{
   /* only mark row as selected if this has not already happened */
   if (g_list_find(info->selected_lines,(gpointer)row)==NULL)        
     info->selected_lines=g_list_append(info->selected_lines,(gpointer)row);
#ifdef DEBUG
   printf ("selectlist_select: selected row %i\n",row);
   printf ("selectlist.c: selectlist_select current selection:\n\"%s\"\n",
	   selectlist_getselection(info));
#endif
}
;

void selectlist_unselect(GtkCList *clist,gint row,gint column,
		       GdkEventButton *event, selectlist_info *info)
{
#ifdef DEBUG
   	printf ("selectlist_unselect: removing row %i\n",
		row);
#endif
	info->selected_lines=g_list_remove(info->selected_lines,
					   (gpointer)row);
#ifdef DEBUG
	printf ("selectlist.c: selectlist_unselect current selection:\n\"%s\"\n",
		selectlist_getselection(info));
#endif
}
;

/* FIXME: implement selectlist_info_destroy,
 * freeing the selected_lines G_List and our local headings copy */
selectlist_info *selectlist_info_create(char *header,int significant_column,
					selectlist_dropcallback receiver,
					int send,menusys_menu *popup,
					GtkSignalFunc doubleclick,
					char *headings[]
					)
{
   selectlist_info *sel;
	
   sel=(selectlist_info*)malloc(sizeof(selectlist_info));
   sel->selection[0]=0;
   sel->selected_lines=NULL; /* currently,no lines are selected */
   strcpy((char*)&sel->header,header);
   sel->significant_column=significant_column;
   sel->receiver=receiver;
   sel->send=send;
   sel->popup=popup;
   
   sel->doubleclick=doubleclick;
   sel->headings=helpings_translatestringlist(headings);
   
   return sel;
}
;

void selectlist_doubleclick(GtkWidget *w,GdkEventButton *event,
			   selectlist_info *info)
{
   /* react to first mouse button only */
	if ((info->doubleclick!=NULL)&&(event->button==1))
	  {
#ifdef DEBUG
		  printf ("selectlist_doubleclick: callback() with selection \"%s\"\n",
			  selectlist_getselection(info));
#endif		  
	    info->doubleclick(info);
	  }
	;
}
;

GtkWidget *selectlist_create(selectlist_info *sel,int columns)
{
	GtkWidget *selectlist;
	
	if (sel->headings) /* headings available? */
	  { 
	    selectlist=gtk_clist_new_with_titles(columns,
						 sel->headings);
	  }
	else
	    selectlist=gtk_clist_new(columns);

	sel->self=GTK_CLIST(selectlist);
	
	if (sel->send)           /* let the user specify if the current window should be sourced */
	    dndsetup_drag(selectlist,
			  GTK_SIGNAL_FUNC(selectlist_drag),
			  GTK_SIGNAL_FUNC(selectlist_dragdone),
			  sel);
	if (sel->receiver!=NULL) /* do not install drop handler if no handler is specified*/
	    dndsetup_drop(selectlist,GTK_SIGNAL_FUNC(selectlist_drop),sel);
	if (sel->popup!=NULL)
	    menusys_attachpopupmenu(selectlist,
				    sel->popup,
				    (gpointer)sel);
	
	gtk_signal_connect(GTK_OBJECT(selectlist),"select_row",
			   GTK_SIGNAL_FUNC(selectlist_select),sel);
	gtk_signal_connect(GTK_OBJECT(selectlist),"unselect_row",
			   GTK_SIGNAL_FUNC(selectlist_unselect),sel);
	doubleclick_connect(GTK_WIDGET(selectlist),
			    GTK_SIGNAL_FUNC(selectlist_doubleclick),
			    sel);
		
	

	return selectlist;
}
;
		  
char *selectlist_getselection(selectlist_info *info)
{
   GList *i;
   int row;
   char *filename;
   
   info->selection[0]=0; /* clear the selection string */
   /* create the selection string of all rows marked as selected */
   for (i=info->selected_lines;i!=NULL;i=i->next)
     {
	row=(int)i->data; /* get row */
   	/* if significant_column is set to -1,a string addressed by the
	 * hidden gpointer data field of the clist is taken as selection
	 * information */
	if (info->significant_column!=-1)
	  {
		  gtk_clist_get_text(info->self,
				     row,
				     info->significant_column,
				     &filename); 
	  }
	else
	    filename=(char*)gtk_clist_get_row_data(info->self,row);
	/* and finally append new selection entry */
	selectlist_appendselection((char*)&info->selection,
			           (char*)&info->header,filename);
     };
   /* return pointer to selection */
   return ((char*)&info->selection);
};

void selectlist_insert(selectlist_info *info,gint row,gchar *text[])
{
   GList *current;
   /* insert the new item */
   gtk_clist_insert(info->self,row,text);
   /* step through the list of selections */
   for (current=info->selected_lines;
	current!=NULL;
	current=current->next)
     {
	if ((int)current->data>=row)
	  current->data++;
     };
};

void selectlist_remove(selectlist_info *info,gint row)
{
   GList *current;
   /* remove an item */
   gtk_clist_remove(info->self,row);
   /* remove item from selection list */
   info->selected_lines=g_list_remove(info->selected_lines,(gpointer)row);
   /* step through the list of selections */
   for (current=info->selected_lines;
	current!=NULL;
	current=current->next)
     {
	if ((int)current->data>row)
	  current->data--;
     };
};