mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-11-10 10:50:10 +00:00
Add DND support to GtkCalendar. The selected date is dragged as text,
* gtk/gtkcalendar.c: Add DND support to GtkCalendar. The selected date is dragged as text, formatted via strftime %x. Text drops are accepted if g_date_set_parse() can make sense of the text. A dedicated data format for date DND has not been introduced yet, since there didn't seem to be sufficient consensus on such a format on xdg-list. (#117297)
This commit is contained in:
parent
6e1e7d30fc
commit
e26259ddea
@ -12,6 +12,12 @@
|
||||
the locale using another instance of the "magic translated string" technique.
|
||||
Ignore the display option GTK_CALENDAR_WEEK_START_MONDAY with a warning. (#87977)
|
||||
|
||||
* gtk/gtkcalendar.c: Add DND support to GtkCalendar. The selected date is dragged
|
||||
as text, formatted via strftime %x. Text drops are accepted if g_date_set_parse()
|
||||
can make sense of the text. A dedicated data format for date DND has not been
|
||||
introduced yet, since there didn't seem to be sufficient consensus on such a format
|
||||
on xdg-list. (#117297)
|
||||
|
||||
2003-08-08 Matthias Clasen <maclas@gmx.de>
|
||||
|
||||
* gdk/gdkregion-generic.c (gdk_region_spans_intersect_foreach): Fix
|
||||
|
@ -12,6 +12,12 @@
|
||||
the locale using another instance of the "magic translated string" technique.
|
||||
Ignore the display option GTK_CALENDAR_WEEK_START_MONDAY with a warning. (#87977)
|
||||
|
||||
* gtk/gtkcalendar.c: Add DND support to GtkCalendar. The selected date is dragged
|
||||
as text, formatted via strftime %x. Text drops are accepted if g_date_set_parse()
|
||||
can make sense of the text. A dedicated data format for date DND has not been
|
||||
introduced yet, since there didn't seem to be sufficient consensus on such a format
|
||||
on xdg-list. (#117297)
|
||||
|
||||
2003-08-08 Matthias Clasen <maclas@gmx.de>
|
||||
|
||||
* gdk/gdkregion-generic.c (gdk_region_spans_intersect_foreach): Fix
|
||||
|
@ -12,6 +12,12 @@
|
||||
the locale using another instance of the "magic translated string" technique.
|
||||
Ignore the display option GTK_CALENDAR_WEEK_START_MONDAY with a warning. (#87977)
|
||||
|
||||
* gtk/gtkcalendar.c: Add DND support to GtkCalendar. The selected date is dragged
|
||||
as text, formatted via strftime %x. Text drops are accepted if g_date_set_parse()
|
||||
can make sense of the text. A dedicated data format for date DND has not been
|
||||
introduced yet, since there didn't seem to be sufficient consensus on such a format
|
||||
on xdg-list. (#117297)
|
||||
|
||||
2003-08-08 Matthias Clasen <maclas@gmx.de>
|
||||
|
||||
* gdk/gdkregion-generic.c (gdk_region_spans_intersect_foreach): Fix
|
||||
|
@ -12,6 +12,12 @@
|
||||
the locale using another instance of the "magic translated string" technique.
|
||||
Ignore the display option GTK_CALENDAR_WEEK_START_MONDAY with a warning. (#87977)
|
||||
|
||||
* gtk/gtkcalendar.c: Add DND support to GtkCalendar. The selected date is dragged
|
||||
as text, formatted via strftime %x. Text drops are accepted if g_date_set_parse()
|
||||
can make sense of the text. A dedicated data format for date DND has not been
|
||||
introduced yet, since there didn't seem to be sufficient consensus on such a format
|
||||
on xdg-list. (#117297)
|
||||
|
||||
2003-08-08 Matthias Clasen <maclas@gmx.de>
|
||||
|
||||
* gdk/gdkregion-generic.c (gdk_region_spans_intersect_foreach): Fix
|
||||
|
@ -12,6 +12,12 @@
|
||||
the locale using another instance of the "magic translated string" technique.
|
||||
Ignore the display option GTK_CALENDAR_WEEK_START_MONDAY with a warning. (#87977)
|
||||
|
||||
* gtk/gtkcalendar.c: Add DND support to GtkCalendar. The selected date is dragged
|
||||
as text, formatted via strftime %x. Text drops are accepted if g_date_set_parse()
|
||||
can make sense of the text. A dedicated data format for date DND has not been
|
||||
introduced yet, since there didn't seem to be sufficient consensus on such a format
|
||||
on xdg-list. (#117297)
|
||||
|
||||
2003-08-08 Matthias Clasen <maclas@gmx.de>
|
||||
|
||||
* gdk/gdkregion-generic.c (gdk_region_spans_intersect_foreach): Fix
|
||||
|
@ -40,6 +40,7 @@
|
||||
#include <glib/gprintf.h>
|
||||
|
||||
#include "gtkcalendar.h"
|
||||
#include "gtkdnd.h"
|
||||
#include "gtkintl.h"
|
||||
#include "gtkmain.h"
|
||||
#include "gtkmarshalers.h"
|
||||
@ -273,10 +274,16 @@ struct _GtkCalendarPrivateData
|
||||
|
||||
guint need_timer : 1;
|
||||
|
||||
guint in_drag : 1;
|
||||
guint drag_highlight : 1;
|
||||
|
||||
guint32 timer;
|
||||
gint click_child;
|
||||
|
||||
gint week_start;
|
||||
|
||||
gint drag_start_x;
|
||||
gint drag_start_y;
|
||||
};
|
||||
|
||||
#define GTK_CALENDAR_PRIVATE_DATA(widget) (((GtkCalendarPrivateData*)(GTK_CALENDAR (widget)->private_data)))
|
||||
@ -346,6 +353,32 @@ static gint left_x_for_column (GtkCalendar *calendar,
|
||||
static gint top_y_for_row (GtkCalendar *calendar,
|
||||
gint row);
|
||||
|
||||
static void gtk_calendar_drag_data_get (GtkWidget *widget,
|
||||
GdkDragContext *context,
|
||||
GtkSelectionData *selection_data,
|
||||
guint info,
|
||||
guint time);
|
||||
static void gtk_calendar_drag_data_received (GtkWidget *widget,
|
||||
GdkDragContext *context,
|
||||
gint x,
|
||||
gint y,
|
||||
GtkSelectionData *selection_data,
|
||||
guint info,
|
||||
guint time);
|
||||
static gboolean gtk_calendar_drag_motion (GtkWidget *widget,
|
||||
GdkDragContext *context,
|
||||
gint x,
|
||||
gint y,
|
||||
guint time);
|
||||
static void gtk_calendar_drag_leave (GtkWidget *widget,
|
||||
GdkDragContext *context,
|
||||
guint time);
|
||||
static gboolean gtk_calendar_drag_drop (GtkWidget *widget,
|
||||
GdkDragContext *context,
|
||||
gint x,
|
||||
gint y,
|
||||
guint time);
|
||||
|
||||
static char *default_abbreviated_dayname[7];
|
||||
static char *default_monthname[12];
|
||||
|
||||
@ -411,6 +444,12 @@ gtk_calendar_class_init (GtkCalendarClass *class)
|
||||
widget_class->state_changed = gtk_calendar_state_changed;
|
||||
widget_class->grab_notify = gtk_calendar_grab_notify;
|
||||
|
||||
widget_class->drag_data_get = gtk_calendar_drag_data_get;
|
||||
widget_class->drag_motion = gtk_calendar_drag_motion;
|
||||
widget_class->drag_leave = gtk_calendar_drag_leave;
|
||||
widget_class->drag_drop = gtk_calendar_drag_drop;
|
||||
widget_class->drag_data_received = gtk_calendar_drag_data_received;
|
||||
|
||||
class->month_changed = NULL;
|
||||
class->day_selected = NULL;
|
||||
class->day_selected_double_click = NULL;
|
||||
@ -558,6 +597,17 @@ gtk_calendar_class_init (GtkCalendarClass *class)
|
||||
G_TYPE_NONE, 0);
|
||||
}
|
||||
|
||||
enum
|
||||
{
|
||||
TARGET_TEXT,
|
||||
};
|
||||
|
||||
static const GtkTargetEntry target_table[] = {
|
||||
{ "TEXT", 0, TARGET_TEXT },
|
||||
{ "STRING", 0, TARGET_TEXT },
|
||||
{ "UTF8_STRING", 0, TARGET_TEXT },
|
||||
};
|
||||
|
||||
static void
|
||||
gtk_calendar_init (GtkCalendar *calendar)
|
||||
{
|
||||
@ -637,6 +687,14 @@ gtk_calendar_init (GtkCalendar *calendar)
|
||||
private_data->timer = 0;
|
||||
private_data->click_child = -1;
|
||||
|
||||
private_data->in_drag = 0;
|
||||
private_data->drag_highlight = 0;
|
||||
|
||||
gtk_drag_dest_set (widget,
|
||||
0,
|
||||
target_table, G_N_ELEMENTS (target_table),
|
||||
GDK_ACTION_COPY);
|
||||
|
||||
private_data->year_before = 0;
|
||||
|
||||
/* Translate to calendar:YM if you want years to be displayed
|
||||
@ -968,12 +1026,14 @@ gtk_calendar_main_button (GtkWidget *widget,
|
||||
GdkEventButton *event)
|
||||
{
|
||||
GtkCalendar *calendar;
|
||||
GtkCalendarPrivateData *private_data;
|
||||
gint x, y;
|
||||
gint row, col;
|
||||
gint day_month;
|
||||
gint day;
|
||||
|
||||
calendar = GTK_CALENDAR (widget);
|
||||
private_data = GTK_CALENDAR_PRIVATE_DATA (widget);
|
||||
|
||||
x = (gint) (event->x);
|
||||
y = (gint) (event->y);
|
||||
@ -1001,9 +1061,13 @@ gtk_calendar_main_button (GtkWidget *widget,
|
||||
|
||||
gtk_calendar_select_and_focus_day (calendar, day);
|
||||
|
||||
private_data->in_drag = 1;
|
||||
private_data->drag_start_x = x;
|
||||
private_data->drag_start_y = y;
|
||||
}
|
||||
else if (event->type == GDK_2BUTTON_PRESS)
|
||||
{
|
||||
private_data->in_drag = 0;
|
||||
if (day_month == MONTH_CURRENT)
|
||||
g_signal_emit (calendar,
|
||||
gtk_calendar_signals[DAY_SELECTED_DOUBLE_CLICK_SIGNAL],
|
||||
@ -2741,9 +2805,20 @@ static gboolean
|
||||
gtk_calendar_button_release (GtkWidget *widget,
|
||||
GdkEventButton *event)
|
||||
{
|
||||
GtkCalendar *calendar;
|
||||
GtkCalendarPrivateData *private_data;
|
||||
|
||||
calendar = GTK_CALENDAR (widget);
|
||||
private_data = GTK_CALENDAR_PRIVATE_DATA (widget);
|
||||
|
||||
if (event->button == 1)
|
||||
{
|
||||
stop_spinning (widget);
|
||||
|
||||
if (private_data->in_drag)
|
||||
private_data->in_drag = 0;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -2765,6 +2840,26 @@ gtk_calendar_motion_notify (GtkWidget *widget,
|
||||
if (event->window == private_data->main_win)
|
||||
{
|
||||
|
||||
if (private_data->in_drag)
|
||||
{
|
||||
if (gtk_drag_check_threshold (widget,
|
||||
private_data->drag_start_x, private_data->drag_start_y,
|
||||
event->x, event->y))
|
||||
{
|
||||
GdkDragContext *context;
|
||||
GtkTargetList *target_list = gtk_target_list_new (target_table, G_N_ELEMENTS (target_table));
|
||||
context = gtk_drag_begin (widget, target_list, GDK_ACTION_COPY,
|
||||
1, (GdkEvent *)event);
|
||||
|
||||
|
||||
private_data->in_drag = 0;
|
||||
|
||||
gtk_target_list_unref (target_list);
|
||||
gtk_drag_set_icon_default (context);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
row = row_from_y (calendar, event_y);
|
||||
col = column_from_x (calendar, event_x);
|
||||
|
||||
@ -2786,6 +2881,7 @@ gtk_calendar_motion_notify (GtkWidget *widget,
|
||||
gtk_calendar_paint_day (widget, row, col);
|
||||
}
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -3287,3 +3383,181 @@ gtk_calendar_get_property (GObject *object,
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_calendar_drag_data_get (GtkWidget *widget,
|
||||
GdkDragContext *context,
|
||||
GtkSelectionData *selection_data,
|
||||
guint info,
|
||||
guint time)
|
||||
{
|
||||
GtkCalendar *calendar = GTK_CALENDAR (widget);
|
||||
GDate *date;
|
||||
gchar str[128];
|
||||
gsize len;
|
||||
|
||||
date = g_date_new_dmy (calendar->selected_day, calendar->month, calendar->year);
|
||||
len = g_date_strftime (str, 127, "%x", date);
|
||||
gtk_selection_data_set_text (selection_data, str, len);
|
||||
|
||||
g_free (date);
|
||||
}
|
||||
|
||||
/* Get/set whether drag_motion requested the drag data and
|
||||
* drag_data_received should thus not actually insert the data,
|
||||
* since the data doesn't result from a drop.
|
||||
*/
|
||||
static void
|
||||
set_status_pending (GdkDragContext *context,
|
||||
GdkDragAction suggested_action)
|
||||
{
|
||||
g_object_set_data (G_OBJECT (context),
|
||||
"gtk-calendar-status-pending",
|
||||
GINT_TO_POINTER (suggested_action));
|
||||
}
|
||||
|
||||
static GdkDragAction
|
||||
get_status_pending (GdkDragContext *context)
|
||||
{
|
||||
return GPOINTER_TO_INT (g_object_get_data (G_OBJECT (context),
|
||||
"gtk-calendar-status-pending"));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_calendar_drag_leave (GtkWidget *widget,
|
||||
GdkDragContext *context,
|
||||
guint time)
|
||||
{
|
||||
GtkCalendarPrivateData *private_data;
|
||||
|
||||
private_data = GTK_CALENDAR_PRIVATE_DATA (widget);
|
||||
private_data->drag_highlight = 0;
|
||||
gtk_drag_unhighlight (widget);
|
||||
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_calendar_drag_motion (GtkWidget *widget,
|
||||
GdkDragContext *context,
|
||||
gint x,
|
||||
gint y,
|
||||
guint time)
|
||||
{
|
||||
GtkCalendarPrivateData *private_data;
|
||||
GdkAtom target;
|
||||
|
||||
private_data = GTK_CALENDAR_PRIVATE_DATA (widget);
|
||||
|
||||
if (!private_data->drag_highlight)
|
||||
{
|
||||
private_data->drag_highlight = 1;
|
||||
gtk_drag_highlight (widget);
|
||||
}
|
||||
|
||||
target = gtk_drag_dest_find_target (widget, context, NULL);
|
||||
if (target == GDK_NONE)
|
||||
gdk_drag_status (context, 0, time);
|
||||
else {
|
||||
set_status_pending (context, context->suggested_action);
|
||||
gtk_drag_get_data (widget, context, target, time);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_calendar_drag_drop (GtkWidget *widget,
|
||||
GdkDragContext *context,
|
||||
gint x,
|
||||
gint y,
|
||||
guint time)
|
||||
{
|
||||
GdkAtom target;
|
||||
|
||||
target = gtk_drag_dest_find_target (widget, context, NULL);
|
||||
if (target != GDK_NONE)
|
||||
{
|
||||
gtk_drag_get_data (widget, context,
|
||||
target,
|
||||
time);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_calendar_drag_data_received (GtkWidget *widget,
|
||||
GdkDragContext *context,
|
||||
gint x,
|
||||
gint y,
|
||||
GtkSelectionData *selection_data,
|
||||
guint info,
|
||||
guint time)
|
||||
{
|
||||
GtkCalendar *calendar = GTK_CALENDAR (widget);
|
||||
guint day, month, year;
|
||||
gchar *str;
|
||||
GDate *date;
|
||||
GdkDragAction suggested_action;
|
||||
|
||||
suggested_action = get_status_pending (context);
|
||||
|
||||
if (suggested_action)
|
||||
{
|
||||
set_status_pending (context, 0);
|
||||
|
||||
/* We are getting this data due to a request in drag_motion,
|
||||
* rather than due to a request in drag_drop, so we are just
|
||||
* supposed to call drag_status, not actually paste in the
|
||||
* data.
|
||||
*/
|
||||
str = gtk_selection_data_get_text (selection_data);
|
||||
if (str)
|
||||
{
|
||||
date = g_date_new ();
|
||||
g_date_set_parse (date, str);
|
||||
if (!g_date_valid (date))
|
||||
suggested_action = 0;
|
||||
g_date_free (date);
|
||||
g_free (str);
|
||||
}
|
||||
else
|
||||
suggested_action = 0;
|
||||
|
||||
gdk_drag_status (context, suggested_action, time);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
date = g_date_new ();
|
||||
str = gtk_selection_data_get_text (selection_data);
|
||||
if (str)
|
||||
{
|
||||
g_date_set_parse (date, str);
|
||||
g_free (str);
|
||||
}
|
||||
|
||||
if (!g_date_valid (date))
|
||||
{
|
||||
g_warning ("Received invalid date data\n");
|
||||
g_date_free (date);
|
||||
gtk_drag_finish (context, FALSE, FALSE, time);
|
||||
return;
|
||||
}
|
||||
|
||||
day = g_date_get_day (date);
|
||||
month = g_date_get_month (date);
|
||||
year = g_date_get_year (date);
|
||||
g_date_free (date);
|
||||
|
||||
gtk_drag_finish (context, TRUE, FALSE, time);
|
||||
|
||||
|
||||
g_object_freeze_notify (G_OBJECT (calendar));
|
||||
if (!(calendar->display_flags & GTK_CALENDAR_NO_MONTH_CHANGE)
|
||||
&& (calendar->display_flags & GTK_CALENDAR_SHOW_HEADING))
|
||||
gtk_calendar_select_month (calendar, month, year);
|
||||
gtk_calendar_select_day (calendar, day);
|
||||
g_object_thaw_notify (G_OBJECT (calendar));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user