[PATCH] Drag&Drop support for GnomeICU
- From: Daniel Burrows <Daniel_Burrows brown edu>
- To: gnome-list gnome org
- Subject: [PATCH] Drag&Drop support for GnomeICU
- Date: Wed, 31 Mar 1999 13:07:11 -0500
This patch adds some support for drag-and-drop in GnomeICU; specifically, you
can drag URLs from Netscape onto the user list and files from gmc. There are
also a few modifications to how the (non-functional) file request code is
structured--I tried to remove the dialog display from the backend and clean it
up a little, although it's a little like trying to empty the desert of sand...
The patch actually adds two short files, dragdrop.[ch], which I've attached
here (how do you get cvs to add new-file info to patches?).
Daniel
--
If you wish to live wisely, ignore sayings--including this one.
? dragdrop.c
? dragdrop.h
? gnomeicu
Index: Makefile.am
===================================================================
RCS file: /cvs/gnome/gnomeicu/src/Makefile.am,v
retrieving revision 1.2
diff -u -r1.2 Makefile.am
--- Makefile.am 1999/03/01 01:17:08 1.2
+++ Makefile.am 1999/03/31 18:04:40
@@ -16,6 +16,7 @@
changename.c \
chatdlg.c \
dialog.c \
+ dragdrop.c \
flash.c \
gnomecfg.c \
gnomeicu.c \
Index: gnomeicu.c
===================================================================
RCS file: /cvs/gnome/gnomeicu/src/gnomeicu.c,v
retrieving revision 1.8
diff -u -r1.8 gnomeicu.c
--- gnomeicu.c 1999/03/25 23:47:13 1.8
+++ gnomeicu.c 1999/03/31 18:04:40
@@ -12,6 +12,7 @@
#endif
#include "gnomeicu.h"
+#include "dragdrop.h"
#include "datatype.h"
#include <stdio.h>
#include <stdlib.h>
@@ -184,6 +185,12 @@
int hide_ch_window( GtkWidget *widget, GdkEvent *event, GtkWidget *window );
void Check_Endian( void );
+gint hide_dont_kill( GtkWidget *widget )
+{
+ gtk_widget_hide(widget);
+ return TRUE;
+}
+
void ready_set( void )
{
char *sts = NULL;
@@ -1208,12 +1215,17 @@
gtk_widget_realize( app );
gnome_app_create_menus( GNOME_APP( app ), mainmenu );
- /* Changed from "delete_event" to "destroy" because it is right :) [PEL]
- * Now it doesn't segfault when closed by the WM */
-
- /* EKP 3.10.99 - changed icq_quit_object to icq_quit */
- gtk_signal_connect( GTK_OBJECT( app ), "destroy",
- GTK_SIGNAL_FUNC( icq_quit ), (gpointer)&sal );
+ if( applet_toggle==FALSE ) {
+ /* Changed from "delete_event" to "destroy" because it is right :) [PEL]
+ * Now it doesn't segfault when closed by the WM */
+
+ /* EKP 3.10.99 - changed icq_quit_object to icq_quit */
+ gtk_signal_connect( GTK_OBJECT( app ), "destroy",
+ GTK_SIGNAL_FUNC( icq_quit ), (gpointer)&sal );
+ } else {
+ gtk_signal_connect( GTK_OBJECT( app ), "delete_event",
+ GTK_SIGNAL_FUNC( hide_dont_kill ), 0 );
+ }
gtk_widget_set_usize( app, WindowWidth, WindowHeight );
@@ -1247,6 +1259,8 @@
gtk_signal_connect( GTK_OBJECT( sal.lb_userwin ), "button_press_event",
GTK_SIGNAL_FUNC( icq_sendmessage_window ), &sal );
+
+ init_contact_list_drag_drop( sal.lb_userwin, &sal );
gtk_signal_connect( GTK_OBJECT( sal.lb_userwin ), "key_press_event",
GTK_SIGNAL_FUNC( icq_sendmessage_window ), &sal );
Index: gtkfunc.c
===================================================================
RCS file: /cvs/gnome/gnomeicu/src/gtkfunc.c,v
retrieving revision 1.8
diff -u -r1.8 gtkfunc.c
--- gtkfunc.c 1999/03/25 23:47:15 1.8
+++ gtkfunc.c 1999/03/31 18:04:40
@@ -414,8 +414,13 @@
gtk_text_thaw( GTK_TEXT( Contacts[ cx ].log_list ) );
}
-void send_url_window( GtkWidget *widget, struct sokandlb *data )
+void send_url_window_default( GtkWidget *widget, struct sokandlb *data )
{
+ send_url_window(widget, data, "");
+}
+
+void send_url_window( GtkWidget *widget, struct sokandlb *data, char *defaulturl )
+{
int cx;
GtkCList *clist = GTK_CLIST( data->lb_userwin );
@@ -477,6 +482,7 @@
urlinfo->url = gtk_entry_new();
gtk_table_attach( GTK_TABLE( table ), urlinfo->url, 1, 2, 0, 1, 0, 0, 0, 10 );
+ gtk_entry_set_text( GTK_ENTRY( urlinfo->url ), defaulturl );
gtk_widget_show( urlinfo->url );
urlinfo->desc = gtk_entry_new();
@@ -533,11 +539,60 @@
TCPSendChatRequest( Contacts[ cx ].uin, "Chat", data );
}
+
+typedef struct
+{
+ GtkWidget *dlg;
+ GtkWidget *msg;
+ GtkWidget *file;
+ struct sokandlb *data;
+ int uin;
+} file_request_info;
+
+void send_file_request(GtkWidget *widget, file_request_info *data)
+{
+ TCPSendFileRequest( data->uin,
+ gtk_entry_get_text(GTK_ENTRY(data->msg)),
+ gtk_entry_get_text(GTK_ENTRY(data->file)),
+ data->data );
+
+ gtk_widget_destroy(data->dlg);
+
+ g_free(data);
+}
+
+void file_chooser_set_retval( GtkWidget *widget, file_request_info *data)
+{
+ GtkFileSelection *filesel=GTK_FILE_SELECTION(widget->parent->parent);
+ gtk_entry_set_text(GTK_ENTRY(data->file),
+ gtk_file_selection_get_filename(filesel));
+ gtk_widget_destroy(GTK_WIDGET(filesel));
+}
+
+void file_choose( GtkWidget *widget, file_request_info *data )
+{
+ GtkWidget *filesel;
+#ifdef TRACE_FUNCTION
+ printf( "file_choose\n" );
+#endif
+
+ filesel = gtk_file_selection_new("GnomeICU: File Transfer");
+
+ gtk_file_selection_set_filename(GTK_FILE_SELECTION(filesel),
+ gtk_entry_get_text(GTK_ENTRY(data->file)));
+ gtk_signal_connect(GTK_OBJECT(filesel), "destroy", GTK_SIGNAL_FUNC(gtk_widget_destroy), NULL);
+ gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(filesel)->ok_button), "clicked", GTK_SIGNAL_FUNC(file_chooser_set_retval), data );
+ gtk_signal_connect_object(GTK_OBJECT (GTK_FILE_SELECTION (filesel)->cancel_button), "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT( filesel ) );
+
+ gtk_widget_show(filesel);
+}
-void request_file( GtkWidget *widget, struct sokandlb *data )
+void request_file( GtkWidget *widget, struct sokandlb *data, char *defaultfile )
{
int cx;
GtkCList *clist = GTK_CLIST( data->lb_userwin );
+ GtkWidget *button,*table,*box;
+ file_request_info *request;
#ifdef TRACE_FUNCTION
printf( "request_file\n" );
@@ -550,7 +605,61 @@
break;
}
- TCPSendFileRequest( Contacts[ cx ].uin, "foo.txt", data );
+ request=g_new(file_request_info,1);
+
+ request->dlg=gtk_dialog_new();
+ gtk_window_set_title(GTK_WINDOW(request->dlg),"Send file");
+
+ table=gtk_table_new(1,1,FALSE);
+
+ request->file=gtk_entry_new();
+ gtk_entry_set_text(GTK_ENTRY(request->file), defaultfile);
+
+ request->msg=gtk_entry_new();
+
+ gtk_table_attach_defaults(GTK_TABLE(table), gtk_label_new("Message:"), 0, 1, 0, 1);
+ gtk_table_attach_defaults(GTK_TABLE(table), request->msg, 1, 2, 0, 1);
+
+ gtk_table_attach_defaults(GTK_TABLE(table), gtk_label_new("File:"), 0, 1, 1, 2);
+
+ box=gtk_hbox_new(FALSE, 2);
+ button=gtk_button_new_with_label("Choose...");
+ gtk_signal_connect(GTK_OBJECT(button), "clicked", file_choose, request);
+
+ gtk_container_add(GTK_CONTAINER(box), request->file);
+ gtk_container_add(GTK_CONTAINER(box), button);
+
+ gtk_table_attach_defaults(GTK_TABLE(table), box, 1, 2, 1, 2);
+
+ gtk_table_set_col_spacings(GTK_TABLE(table), 4);
+ gtk_table_set_row_spacings(GTK_TABLE(table), 4);
+
+ gtk_container_set_border_width(GTK_CONTAINER(table), 4);
+
+ gtk_container_add(GTK_CONTAINER(GTK_DIALOG(request->dlg)->vbox), table);
+
+ button=gtk_button_new_with_label("Send");
+ gtk_signal_connect(GTK_OBJECT(button), "clicked", send_file_request, request);
+
+ gtk_container_add(GTK_CONTAINER(GTK_DIALOG(request->dlg)->action_area),
+ button);
+
+ button=gtk_button_new_with_label("Cancel");
+ gtk_signal_connect_object(GTK_OBJECT(button),
+ "clicked",
+ GTK_SIGNAL_FUNC(gtk_widget_destroy),
+ GTK_OBJECT(request->dlg));
+
+ gtk_container_add(GTK_CONTAINER(GTK_DIALOG(request->dlg)->action_area),
+ button);
+
+ gtk_widget_show_all(request->dlg);
+ gtk_widget_show(request->dlg);
+}
+
+void request_file_default( GtkWidget *widget, struct sokandlb *data )
+{
+ request_file( widget, data, "" );
}
void remove_user( GtkWidget *widget, struct sokandlb *data )
@@ -1951,8 +2060,9 @@
if( nick == NULL )
return FALSE;
- /* This is VERY BAD, because if you have two people with the same
- nick, you'll send the message to the first on the list - BAD! */
+ /* FIXME: This is VERY BAD, because if you have two people with the
+ * same nick, you'll send the message to the first on the list - BAD!
+ */
for( cx = 0; cx < Num_Contacts; cx ++ )
{
@@ -2006,7 +2116,7 @@
gtk_widget_show( item_box );
gtk_menu_append( GTK_MENU( personal_menu ), item );
gtk_signal_connect( GTK_OBJECT( item ), "activate",
- GTK_SIGNAL_FUNC( send_url_window ),
+ GTK_SIGNAL_FUNC( send_url_window_default ),
data );
gtk_widget_show( item );
@@ -2038,7 +2148,7 @@
gtk_widget_show( item_box );
gtk_menu_append( GTK_MENU( personal_menu ), item );
gtk_signal_connect( GTK_OBJECT( item ), "activate",
- GTK_SIGNAL_FUNC( request_file ),
+ GTK_SIGNAL_FUNC( request_file_default ),
data );
gtk_widget_show( item );
Index: gtkfunc.h
===================================================================
RCS file: /cvs/gnome/gnomeicu/src/gtkfunc.h,v
retrieving revision 1.3
diff -u -r1.3 gtkfunc.h
--- gtkfunc.h 1999/03/19 18:58:51 1.3
+++ gtkfunc.h 1999/03/31 18:04:40
@@ -1,6 +1,8 @@
#ifndef _GTKFUNC_H
#define _GTKFUNC_H
+#include "datatype.h"
+
struct sokandlb
{
int sok;
@@ -45,8 +47,13 @@
struct sokandlb *data );
#endif
void request_chat( GtkWidget *widget, struct sokandlb *data );
-void request_file( GtkWidget *widget, struct sokandlb *data );
-void send_url_window( GtkWidget *widget, struct sokandlb *data );
+
+void request_file( GtkWidget *widget, struct sokandlb *data, char *defaultfile );
+void request_file_default( GtkWidget *widget, struct sokandlb *data );
+
+void send_url_window( GtkWidget *widget, struct sokandlb *data, char *defaulturl );
+void send_url_window_default( GtkWidget *widget, struct sokandlb *data );
+
void remove_user( GtkWidget *widget, struct sokandlb *data );
void show_info_new( SOK_T sok, int uin );
void retrieve_away_message( GtkWidget *widget, struct sokandlb *data );
Index: tcp.c
===================================================================
RCS file: /cvs/gnome/gnomeicu/src/tcp.c,v
retrieving revision 1.6
diff -u -r1.6 tcp.c
--- tcp.c 1999/03/25 23:47:18 1.6
+++ tcp.c 1999/03/31 18:04:41
@@ -2096,38 +2096,15 @@
return 1;
}
-int TCPSendFileRequest( DWORD uin, char *msg, struct sokandlb *data )
+int TCPSendFileRequest( DWORD uin, char *msg, char *file, struct sokandlb *data )
{
#ifdef TRACE_FUNCTION
printf( "TCPSendChatRequest\n" );
#endif
- file_choose();
- return 1;
-}
-
-void file_choose( void )
-{
-#ifdef TRACE_FUNCTION
- printf( "file_choose\n" );
-#endif
-
- filesel = gtk_file_selection_new("GnomeICU: File Transfer");
- gtk_signal_connect(GTK_OBJECT(filesel), "destroy", GTK_SIGNAL_FUNC(gtk_widget_destroy), NULL);
- gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(filesel)->ok_button), "clicked", GTK_SIGNAL_FUNC(file_xfer_got_name), NULL );
- gtk_signal_connect_object(GTK_OBJECT (GTK_FILE_SELECTION (filesel)->cancel_button), "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT( filesel ) );
- gtk_widget_show(filesel);
-}
+ printf("About to send file: %s\n",file);
-void file_xfer_got_name( GtkWidget *widget, gpointer data )
-{
-#ifdef TRACE_FUNCTION
- printf( "file_xfer_got_name\n" );
-#endif
-
- printf( "About to send file: %s\n",
- gtk_file_selection_get_filename( GTK_FILE_SELECTION( filesel ) ) );
- gtk_widget_destroy( filesel );
+ return 1;
}
void chat_save( void )
Index: tcp.h
===================================================================
RCS file: /cvs/gnome/gnomeicu/src/tcp.h,v
retrieving revision 1.3
diff -u -r1.3 tcp.h
--- tcp.h 1999/03/25 23:47:19 1.3
+++ tcp.h 1999/03/31 18:04:41
@@ -42,7 +42,7 @@
int TCPChatSend( GtkWidget *widget, GdkEventKey *ev, int sock );
void TCPTerminateChat( GtkWidget *widget, gpointer data );
int TCPRetrieveAwayMessage( int cindex, struct sokandlb *data );
-int TCPSendFileRequest( DWORD uin, char *msg, struct sokandlb *data );
+int TCPSendFileRequest( DWORD uin, char *msg, char *filename, struct sokandlb *data );
void chat_save_got_name( GtkWidget *widget, gpointer data );
void chat_save( void );
/* dragdrop.c
*
* GnomeICU DnD support
*
* Much help from gnome-core/panel/panel.c on this one.
*/
#include "dragdrop.h"
#include <ctype.h>
#include <libgnome/libgnome.h>
#include <string.h>
enum
{
TARGET_URL,
TARGET_NETSCAPE_URL
};
static GtkTargetEntry contact_list_drop_types[]=
{
{ "_NETSCAPE_URL", 0, TARGET_NETSCAPE_URL },
{ "text/uri-list", 0, TARGET_URL },
{ "x-url/http", 0, TARGET_NETSCAPE_URL },
{ "x-url/ftp", 0, TARGET_NETSCAPE_URL },
{ "text/plain",0,TARGET_NETSCAPE_URL, }
/* ?? For some reason Netscape wants to send me stuff as text/plain */
};
static gint n_contact_list_drop_types=
sizeof(contact_list_drop_types)/sizeof(contact_list_drop_types[0]);
static void contact_list_dnd_drop(GtkWidget *widget,
GdkDragContext *context,
gint x,
gint y,
GtkSelectionData *selection_data,
guint info,
guint time,
struct sokandlb *data)
{
GtkCList *list;
int row;
int column;
printf("Got drop: %s\n",(char*)selection_data->data);
g_return_if_fail(widget);
g_return_if_fail(GTK_IS_CLIST(widget));
list=GTK_CLIST(widget);
gtk_clist_get_selection_info(list, x, y, &row, &column);
gtk_clist_select_row(list, row, column);
switch(info)
{
case TARGET_URL:
// We got a bunch of file names
{
GList *files=gnome_uri_list_extract_filenames(selection_data->data),*tmp;
for(tmp=files; tmp; tmp=g_list_next(tmp))
{
printf("Got URL: %s\n",(char*)tmp->data);
request_file(widget, data, (char *)tmp->data);
}
gnome_uri_list_free_strings(files);
}
break;
case TARGET_NETSCAPE_URL:
{
GString *type=g_string_new("");
char *url=(char*) selection_data->data;
char *tmp=url;
printf("Got Netscape URL: %s\n",url);
while(isalpha(*tmp))
type=g_string_append_c(type,*tmp++);
printf("Type is %s\n",type->str);
if(!strcmp(type->str,""))
/* Assume it's a straight filename */
{
request_file(widget, data, tmp);
g_string_free(type,1);
return;
}
if(!strcmp(type->str,"file"))
{
if(*tmp++!=':')
{
fprintf(stderr,"Badly formed URL: %s\n",url);
g_string_free(type,1);
return;
}
if(tmp[0]=='/'&&tmp[1]=='/')
// file://host/loationc handling.
// If it's of the form file://localhost/stuff, do a file transfer
// on stuff, otherwise continue.
{
tmp+=2;
if(strstr(tmp,"localhost")==tmp)
{
tmp+=strlen("localhost");
printf("Sending file request for %s\n",tmp);
request_file(widget, data, tmp);
g_string_free(type,1);
return;
}
}
else /* Of the form file:... */
{
request_file(widget, data, tmp);
g_string_free(type,1);
return;
}
}
printf("Sending URL request for %s\n",url);
send_url_window( widget, data, url );
g_string_free(type,1);
break;
}
}
}
void init_contact_list_drag_drop(GtkWidget *list, struct sokandlb *data)
{
printf("Initializing drag&drop with %i types\n",n_contact_list_drop_types);
gtk_signal_connect(GTK_OBJECT(list),
"drag_data_received",
GTK_SIGNAL_FUNC(contact_list_dnd_drop),
data);
gtk_drag_dest_set(GTK_WIDGET(list),
GTK_DEST_DEFAULT_MOTION |
GTK_DEST_DEFAULT_HIGHLIGHT |
GTK_DEST_DEFAULT_DROP,
contact_list_drop_types,
n_contact_list_drop_types,
GDK_ACTION_COPY);
}
/* dragdrop.h
*
* Support for drag-and-drop in GnomeICU
*
* Written with much help from gnome-core/panel/panel.c :-)
*/
#ifndef DRAGDROP_H
#define DRAGDROP_H
#include <gtk/gtk.h>
#include "gtkfunc.h"
void init_contact_list_drag_drop(GtkWidget *widget, struct sokandlb *data);
#endif
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]