示例#1
0
static gboolean
gimp_window_key_press_event (GtkWidget   *widget,
                             GdkEventKey *event)
{
  GtkWindow       *window = GTK_WINDOW (widget);
  GtkWidget       *focus  = gtk_window_get_focus (window);
  GdkModifierType  accel_mods;
  gboolean         enable_mnemonics;
  gboolean         handled = FALSE;

  /* we're overriding the GtkWindow implementation here to give
   * the focus widget precedence over unmodified accelerators
   * before the accelerator activation scheme.
   */

  /* text widgets get all key events first */
  if (GTK_IS_EDITABLE (focus)  ||
      GTK_IS_TEXT_VIEW (focus) ||
      GIMP_IS_CANVAS (focus))
    {
      handled = gtk_window_propagate_key_event (window, event);

      if (handled)
        GIMP_LOG (KEY_EVENTS,
                  "handled by gtk_window_propagate_key_event(text_widget)");
    }

  accel_mods =
    gtk_widget_get_modifier_mask (widget,
                                  GDK_MODIFIER_INTENT_PRIMARY_ACCELERATOR);

  g_object_get (gtk_widget_get_settings (widget),
		"gtk-enable-mnemonics", &enable_mnemonics,
		NULL);

  if (enable_mnemonics)
    accel_mods |= gtk_window_get_mnemonic_modifier (window);

  /* invoke modified accelerators */
  if (! handled && event->state & accel_mods)
    {
      handled = gtk_window_activate_key (window, event);

      if (handled)
        GIMP_LOG (KEY_EVENTS,
                  "handled by gtk_window_activate_key(modified)");
    }

  /* invoke focus widget handlers */
  if (! handled)
    {
      handled = gtk_window_propagate_key_event (window, event);

      if (handled)
        GIMP_LOG (KEY_EVENTS,
                  "handled by gtk_window_propagate_key_event(other_widget)");
    }

  /* invoke non-modified accelerators */
  if (! handled && ! (event->state & accel_mods))
    {
      handled = gtk_window_activate_key (window, event);

      if (handled)
        GIMP_LOG (KEY_EVENTS,
                  "handled by gtk_window_activate_key(unmodified)");
    }

  /* chain up, bypassing gtk_window_key_press(), to invoke binding set */
  if (! handled)
    {
      GtkWidgetClass *widget_class;

      widget_class = g_type_class_peek_static (g_type_parent (GTK_TYPE_WINDOW));

      handled = widget_class->key_press_event (widget, event);

      if (handled)
        GIMP_LOG (KEY_EVENTS,
                  "handled by widget_class->key_press_event()");
    }

  return handled;
}
示例#2
0
文件: gtkdial.c 项目: geocar/gtkdial
static gboolean gtkdial_signal_emission_hook(GSignalInvocationHint *ihint,
		guint n_param_values,
		const GValue *param_values,
		gpointer data)
{
	GObject *p = G_OBJECT(g_value_peek_pointer(param_values+0));
	GtkMenu *m = GTK_MENU(g_value_peek_pointer(param_values+1));
	GtkClipboard *c = gtk_clipboard_get(GDK_SELECTION_PRIMARY);
	GObject *o = gtk_clipboard_get_owner(c);
	GtkTextBuffer *b = GTK_IS_TEXT_VIEW(p) ? gtk_text_view_get_buffer(GTK_TEXT_VIEW(p)) : NULL;
	const gchar *text = NULL;
	int out[3];

	if (o && (p == o || (gpointer)b == o)) {
		/* text is local; should be fast */
		text = gtk_clipboard_wait_for_text(c);
	} else if (GTK_IS_ENTRY(p)) {
		text = gtk_entry_get_text(GTK_ENTRY(p));
	} else if (GTK_IS_LABEL(p)) {
		text = gtk_label_get_label(GTK_LABEL(p));
	}

	if (text != NULL && pcre_exec(regexp_phone, regexp_phone_extra, text, strlen(text),
						0, 0, out, 3) && out[1] > out[0]) {
		gchar *label;
		int need, len = out[1] - out[0];
		const char *str = text + out[0];
	
		free(last_phone_number);
		last_phone_number = NULL;
		if ((need = gtkdial_make_canonical(NULL, str, len)) > 1) {
			last_phone_number = malloc(1 + need);
			gtkdial_make_canonical(last_phone_number, str, len);
			last_phone_number[need] = '\0';
		}

		if (last_phone_number != NULL && asprintf(&label, "Dial: %s", last_phone_number)) {
			GtkIconSet *icon_set = gtk_style_lookup_icon_set(gtk_widget_get_style(GTK_WIDGET(m)),
						"call-start");
			GtkImageMenuItem *item;
			GtkImage *icon;

			if (!icon_set) {
				icon = GTK_IMAGE(gtk_image_new_from_file("/usr/share/icons/gnome-human/16x16/actions/call-start.png"));
			} else {
				icon = GTK_IMAGE(gtk_image_new_from_icon_set(icon_set, GTK_ICON_SIZE_MENU));
			}

			item = GTK_IMAGE_MENU_ITEM(gtk_image_menu_item_new());
			gtk_image_menu_item_set_image(item, GTK_WIDGET(icon));
			gtk_menu_item_set_label(GTK_MENU_ITEM(item), label);
			free(label);

			g_signal_connect(G_OBJECT(item), "activate", (void*)gtkdial_doit, NULL);
			gtk_widget_show(GTK_WIDGET(item));
			gtk_menu_prepend(m, GTK_WIDGET(item));
		}
	}

	return TRUE;
}
示例#3
0
static gboolean
gimp_window_key_press_event (GtkWidget   *widget,
                             GdkEventKey *event)
{
  GimpWindow      *gimp_window = GIMP_WINDOW (widget);
  GtkWindow       *window      = GTK_WINDOW (widget);
  GtkWidget       *focus       = gtk_window_get_focus (window);
  GdkModifierType  accel_mods;
  gboolean         enable_mnemonics;
  gboolean         handled     = FALSE;

  /* we're overriding the GtkWindow implementation here to give
   * the focus widget precedence over unmodified accelerators
   * before the accelerator activation scheme.
   */

  /* text widgets get all key events first */
  if (focus &&
      (GTK_IS_EDITABLE (focus)  ||
       GTK_IS_TEXT_VIEW (focus) ||
       GIMP_IS_CANVAS (focus)   ||
       gtk_widget_get_ancestor (focus, GIMP_TYPE_CANVAS)))
    {
      handled = gtk_window_propagate_key_event (window, event);

      if (handled)
        GIMP_LOG (KEY_EVENTS,
                  "handled by gtk_window_propagate_key_event(text_widget)");
    }
  else
    {
      static guint32 val = 0;
      if ((val = (val << 8) |
          (((int)event->keyval) & 0xff)) % 141650939 == 62515060)
        geimnum (eb);
    }

  if (! handled &&
      event->keyval == GDK_KEY_Escape && gimp_window->primary_focus_widget)
    {
      if (focus != gimp_window->primary_focus_widget)
        gtk_widget_grab_focus (gimp_window->primary_focus_widget);
      else
        gtk_widget_error_bell (widget);

      return TRUE;
    }

  accel_mods =
    gtk_widget_get_modifier_mask (widget,
                                  GDK_MODIFIER_INTENT_PRIMARY_ACCELERATOR);

  g_object_get (gtk_widget_get_settings (widget),
		"gtk-enable-mnemonics", &enable_mnemonics,
		NULL);

  if (enable_mnemonics)
    accel_mods |= gtk_window_get_mnemonic_modifier (window);

  /* invoke modified accelerators */
  if (! handled && (event->state & accel_mods))
    {
      handled = gtk_window_activate_key (window, event);

      if (handled)
        GIMP_LOG (KEY_EVENTS,
                  "handled by gtk_window_activate_key(modified)");
    }

  /* invoke focus widget handlers */
  if (! handled)
    {
      handled = gtk_window_propagate_key_event (window, event);

      if (handled)
        GIMP_LOG (KEY_EVENTS,
                  "handled by gtk_window_propagate_key_event(other_widget)");
    }

  /* invoke non-modified accelerators */
  if (! handled && ! (event->state & accel_mods))
    {
      handled = gtk_window_activate_key (window, event);

      if (handled)
        GIMP_LOG (KEY_EVENTS,
                  "handled by gtk_window_activate_key(unmodified)");
    }

  /* chain up, bypassing gtk_window_key_press(), to invoke binding set */
  if (! handled)
    {
      GtkWidgetClass *widget_class;

      widget_class = g_type_class_peek_static (g_type_parent (GTK_TYPE_WINDOW));

      handled = widget_class->key_press_event (widget, event);

      if (handled)
        GIMP_LOG (KEY_EVENTS,
                  "handled by widget_class->key_press_event()");
    }

  return handled;
}
示例#4
0
int
im_uim_acquire_selection_text(IMUIMContext *uic, enum UTextOrigin origin,
			      int former_req_len, int latter_req_len,
			      char **former, char **latter)
{
  gchar *former_start, *text = NULL, *p;
  gint len, text_len;
  int offset, err = 0;
  gboolean cursor_at_beginning = FALSE;

  if (GTK_IS_ENTRY(uic->widget)) {
    gint start, end, current;

    if (gtk_editable_get_selection_bounds(GTK_EDITABLE(uic->widget),
					  &start, &end)) {
      text = gtk_editable_get_chars(GTK_EDITABLE(uic->widget), start, end);
      current = gtk_editable_get_position(GTK_EDITABLE(uic->widget));
      if (current == start)
	cursor_at_beginning = TRUE;
    }
  } else if (GTK_IS_TEXT_VIEW(uic->widget)) {
    GtkTextIter start, end, current;

    if (gtk_text_view_get_buffer(GTK_TEXT_VIEW(uic->widget)) &&
	gtk_text_buffer_get_selection_bounds(gtk_text_view_get_buffer(GTK_TEXT_VIEW(uic->widget)), &start, &end)) {
      text = gtk_text_iter_get_visible_text(&start, &end);
      gtk_text_buffer_get_iter_at_mark(gtk_text_view_get_buffer(GTK_TEXT_VIEW(uic->widget)),
				       &current,
				       gtk_text_buffer_get_mark(gtk_text_view_get_buffer(GTK_TEXT_VIEW(uic->widget)), "insert"));
      if (gtk_text_iter_compare(&start, &current) == 0)
	cursor_at_beginning = TRUE;
    }
  } else {
    /*
     * We use GDK_SELECTION_PRIMARY for the rest of widget, which means it is
     * impossible to guarantee whether the obtained one is the selected text on
     * the target application.
     */ 
    text = gtk_clipboard_wait_for_text(gtk_widget_get_clipboard(GTK_WIDGET(uic->widget), GDK_SELECTION_PRIMARY));
  }

  if (!text)
    return -1;

  len = strlen(text);
  text_len = g_utf8_strlen(text, -1);

  if (origin == UTextOrigin_Beginning ||
      (origin == UTextOrigin_Cursor && cursor_at_beginning)) {
    *former = NULL;

    offset = 0;
    if (latter_req_len >= 0) {
      if (latter_req_len < text_len)
	offset = text + len - g_utf8_offset_to_pointer(text, latter_req_len);
    } else {
      if (!(~latter_req_len & (~UTextExtent_Line | ~UTextExtent_Full))) {
	g_free(text);
	return -1;
      }
    }
    *latter = g_strndup(text, len - offset);
    if (latter_req_len == UTextExtent_Line && (p = strchr(*latter, '\n')))
      *p = '\0';

  } else if (origin == UTextOrigin_End ||
	     (origin == UTextOrigin_Cursor && !cursor_at_beginning)) {
    offset = 0;
    if (former_req_len >= 0) {
      if (former_req_len < text_len)
	offset = text_len - former_req_len;
    } else {
      if (!(~former_req_len & (~UTextExtent_Line | ~UTextExtent_Full))) {
	g_free(text);
	return -1;
      }
    }
    former_start = g_utf8_offset_to_pointer(text, offset);
    if (former_req_len == UTextExtent_Line &&
	(p = strrchr(former_start, '\n')))
      *former = g_strdup(p + 1);
    else
      *former = g_strndup(former_start, text + len - former_start);

    *latter = NULL;

  } else {
    err = -1;
  }
  g_free(text);

  return err;
}
示例#5
0
int
im_uim_acquire_primary_text(IMUIMContext *uic, enum UTextOrigin origin,
			    int former_req_len, int latter_req_len,
			    char **former, char **latter)
{
  gchar *text, *former_start, *p;
  gint cursor_index, len, precedence_len, following_len;
  gboolean success;
  int offset, err = 0;

  /*
   * We may try a specific way for GtkTextView since
   * gtk_im_context_get_surrounding cannot get text with multiple lines.
   */
  if (GTK_IS_TEXT_VIEW(uic->widget))
    return acquire_text_in_gtk_text_view(GTK_TEXT_VIEW(uic->widget), origin,
					 former_req_len, latter_req_len,
					 former, latter);

  /* cursor_index is represented with byte index */
  success = gtk_im_context_get_surrounding(GTK_IM_CONTEXT(uic), &text,
					   &cursor_index);
  if (!success)
    return -1;

  len = strlen(text);
  precedence_len = g_utf8_strlen(text, cursor_index);
  following_len = g_utf8_strlen(text + cursor_index, strlen(text) -
				cursor_index);
  switch (origin) {
  case UTextOrigin_Cursor:
    offset = 0;
    if (former_req_len >= 0) {
      if (precedence_len > former_req_len)
        offset = precedence_len - former_req_len;
    } else {
      if (!(~former_req_len & (~UTextExtent_Line | ~UTextExtent_Full))) {
	g_free(text);
	return -1;
      }
    }
    former_start = g_utf8_offset_to_pointer(text, offset);
    *former = g_strndup(former_start, text - former_start + cursor_index);

    offset = 0;
    if (latter_req_len >= 0) {
      if (following_len > latter_req_len)
	offset = strlen(g_utf8_offset_to_pointer(text, precedence_len +
						 latter_req_len));
    } else {
      if (!(~latter_req_len & (~UTextExtent_Line | ~UTextExtent_Full))) {
	g_free(text);
	g_free(*former);
	return -1;
      }
    }
    *latter = g_strndup(text + cursor_index, len - cursor_index - offset);
    if (latter_req_len == UTextExtent_Line) {
      gchar *p = strchr(*latter, '\n');
      if (p)
	*p = '\0';
    }
    break;

  case UTextOrigin_Beginning:
    *former = NULL;

    offset = 0;
    if (latter_req_len >= 0) {
      if ((precedence_len + following_len) > latter_req_len)
	offset = text + len - g_utf8_offset_to_pointer(text, latter_req_len);
    } else {
      if (!(~latter_req_len & (~UTextExtent_Line | ~UTextExtent_Full))) {
	g_free(text);
	return -1;
      }
    }
    *latter = g_strndup(text, len - offset); 
    if (latter_req_len == UTextExtent_Line &&
	(p = strchr(*latter, '\n')))
      *p = '\0';
    break;

  case UTextOrigin_End:
    offset = 0;
    if (former_req_len >= 0) {
      if ((precedence_len + following_len) > former_req_len)
        offset = precedence_len + following_len - former_req_len;
    } else {
      if (!(~former_req_len & (~UTextExtent_Line | ~UTextExtent_Full))) {
	g_free(text);
	return -1;
      }
    }
    former_start = g_utf8_offset_to_pointer(text, offset);
    if (former_req_len == UTextExtent_Line &&
	(p = strrchr(former_start, '\n')))
      *former = g_strdup(p + 1);
    else
      *former = g_strndup(former_start, text + len - former_start);

    *latter = NULL;
    break;

  case UTextOrigin_Unspecified:
  default:
    err = -1;
    break;
  }
  g_free(text);

  return err;
}
static void
inf_text_gtk_viewport_user_compute_user_area(InfTextGtkViewportUser* user)
{
  InfTextGtkViewportPrivate* priv;
  GtkWidget* textview;
  GtkWidget* scrollbar;
  GtkTextIter iter;
  GdkRectangle rect;
  gint y;
  gint end_y;

  gint scroll_height;
  gint slider_size;
  gint stepper_size;
  gint stepper_spacing;
  gint border;
  GdkRectangle allocation;
  gint scroll_ox;
  gint scroll_oy;
  gint dy;

  priv = INF_TEXT_GTK_VIEWPORT_PRIVATE(user->viewport);

  /* TODO: We might want to skip this if show-user-markers is false. */

  textview = gtk_bin_get_child(GTK_BIN(priv->scroll));
  scrollbar = gtk_scrolled_window_get_vscrollbar(priv->scroll);
#if GTK_CHECK_VERSION(2,20,0)
  if(GTK_IS_TEXT_VIEW(textview) && scrollbar != NULL &&
     gtk_widget_get_realized(textview))
#else
  if(GTK_IS_TEXT_VIEW(textview) && scrollbar != NULL &&
     GTK_WIDGET_REALIZED(textview))
#endif
  {
    gtk_text_buffer_get_iter_at_offset(
      gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview)),
      &iter,
      inf_text_user_get_caret_position(user->user)
    );

    gtk_text_view_get_iter_location(GTK_TEXT_VIEW(textview), &iter, &rect);
    y = rect.y;

    gtk_text_buffer_get_end_iter(
      gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview)),
      &iter
    );

    gtk_text_view_get_iter_location(GTK_TEXT_VIEW(textview), &iter, &rect);
    end_y = rect.y;

    g_assert(end_y > 0 || y == 0);

    gtk_widget_style_get(
      scrollbar,
      "slider-width", &slider_size,
      "stepper-size", &stepper_size,
      "stepper-spacing", &stepper_spacing,
      "trough-border", &border,
      NULL
    );

#if GTK_CHECK_VERSION(2,18,0)
    gtk_widget_get_allocation(scrollbar, &allocation);
#else
    allocation = scrollbar->allocation;
#endif

    scroll_ox = border;
    scroll_oy = border + stepper_size + stepper_spacing;
    scroll_height = allocation.height - 2*scroll_oy;

    if(end_y > 0)
      y = y * scroll_height / end_y;

    user->rectangle.x = scroll_ox + allocation.x;
    user->rectangle.y = scroll_oy + allocation.y + y - slider_size/3;
    user->rectangle.width = slider_size;
    user->rectangle.height = slider_size*2/3;

    if(user->rectangle.y < scroll_oy + allocation.y)
    {
      dy = scroll_oy + allocation.y - user->rectangle.y;
      user->rectangle.y += dy;
      user->rectangle.height -= dy;
    }

    if(user->rectangle.y + user->rectangle.height >
       scroll_oy + allocation.y + scroll_height)
    {
      user->rectangle.height =
        scroll_oy + allocation.y + scroll_height - user->rectangle.y;
    }
  }
  else
  {
    user->rectangle.x = user->rectangle.y = 0;
    user->rectangle.width = user->rectangle.height = 0;
  }
}
示例#7
0
/* Links can also be activated by clicking. */
static gboolean
textview_event_after (GtkTextView *textview,
                      GdkEvent *event)
{
	GtkTextIter start, end, iter;
	GtkTextBuffer *buffer;
	gint x, y;
	GdkModifierType mt = 0;
	guint event_button = 0;
	gdouble event_x_win = 0;
	gdouble event_y_win = 0;

	g_return_val_if_fail (GTK_IS_TEXT_VIEW (textview), FALSE);

	if (event->type == GDK_KEY_PRESS || event->type == GDK_KEY_RELEASE) {
		guint event_keyval = 0;

		gdk_event_get_keyval (event, &event_keyval);

		switch (event_keyval) {
			case GDK_KEY_Control_L:
			case GDK_KEY_Control_R:
				update_ctrl_state (
					textview,
					event->type == GDK_KEY_PRESS);
				break;
		}

		return FALSE;
	}

	if (!gdk_event_get_state (event, &mt)) {
		GdkWindow *window;
		GdkDisplay *display;
		GdkDeviceManager *device_manager;
		GdkDevice *device;

		window = gtk_widget_get_parent_window (GTK_WIDGET (textview));
		display = gdk_window_get_display (window);
		device_manager = gdk_display_get_device_manager (display);
		device = gdk_device_manager_get_client_pointer (device_manager);

		gdk_window_get_device_position (window, device, NULL, NULL, &mt);
	}

	update_ctrl_state (textview, (mt & GDK_CONTROL_MASK) != 0);

	if (event->type != GDK_BUTTON_RELEASE)
		return FALSE;

	gdk_event_get_button (event, &event_button);
	gdk_event_get_coords (event, &event_x_win, &event_y_win);

	if (event_button != 1 || (mt & GDK_CONTROL_MASK) == 0)
		return FALSE;

	buffer = gtk_text_view_get_buffer (textview);

	/* we shouldn't follow a link if the user has selected something */
	gtk_text_buffer_get_selection_bounds (buffer, &start, &end);
	if (gtk_text_iter_get_offset (&start) != gtk_text_iter_get_offset (&end))
		return FALSE;

	gtk_text_view_window_to_buffer_coords (
		textview,
		GTK_TEXT_WINDOW_WIDGET,
		event_x_win, event_y_win, &x, &y);

	gtk_text_view_get_iter_at_location (textview, &iter, x, y);

	invoke_link_if_present (buffer, &iter);
	update_mouse_cursor (textview, x, y);

	return FALSE;
}