gtklabel.c 208 KB
Newer Older
Cody Russell's avatar
Cody Russell committed
1
/* GTK - The GIMP Toolkit
Elliot Lee's avatar
Elliot Lee committed
2 3 4
 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
 *
 * This library is free software; you can redistribute it and/or
5
 * modify it under the terms of the GNU Lesser General Public
Elliot Lee's avatar
Elliot Lee committed
6 7 8 9 10
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
 * Lesser General Public License for more details.
Elliot Lee's avatar
Elliot Lee committed
13
 *
14
 * You should have received a copy of the GNU Lesser General Public
Javier Jardón's avatar
Javier Jardón committed
15
 * License along with this library. If not, see <http://www.gnu.org/licenses/>.Free
Elliot Lee's avatar
Elliot Lee committed
16
 */
17 18

/*
19
 * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
20 21
 * file for a list of people on the GTK+ Team.  See the ChangeLog
 * files for a list of changes.  These files are distributed with
22
 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
23 24
 */

25
#include "config.h"
26

27
#include <math.h>
Elliot Lee's avatar
Elliot Lee committed
28
#include <string.h>
29

Elliot Lee's avatar
Elliot Lee committed
30
#include "gtklabel.h"
31
#include "gtklabelprivate.h"
32
#include "gtkaccellabel.h"
33 34 35
#include "gtkbindings.h"
#include "gtkbuildable.h"
#include "gtkclipboard.h"
36
#include "gtkcssshadowsvalueprivate.h"
37
#include "gtkdnd.h"
38
#include "gtkimage.h"
39
#include "gtkintl.h"
40
#include "gtkmain.h"
41
#include "gtkmarshalers.h"
42
#include "gtkmenuitem.h"
43
#include "gtkmenushellprivate.h"
44
#include "gtknotebook.h"
45 46 47
#include "gtkpango.h"
#include "gtkprivate.h"
#include "gtkseparatormenuitem.h"
48
#include "gtkshow.h"
49
#include "gtkstylecontextprivate.h"
50
#include "gtktextutil.h"
51
#include "gtktooltip.h"
52
#include "gtktypebuiltins.h"
53 54
#include "gtkwidgetprivate.h"
#include "gtkwindow.h"
55

56
#include "a11y/gtklabelaccessibleprivate.h"
57

Chun-wei Fan's avatar
Chun-wei Fan committed
58 59 60 61 62
/* this is in case rint() is not provided by the compiler, 
 * such as in the case of C89 compilers, like MSVC
 */
#include "fallback-c89.c"

63 64 65 66 67 68 69
/**
 * SECTION:gtklabel
 * @Short_description: A widget that displays a small to medium amount of text
 * @Title: GtkLabel
 *
 * The #GtkLabel widget displays a small amount of text. As the name
 * implies, most labels are used to label another widget such as a
70
 * #GtkButton, a #GtkMenuItem, or a #GtkComboBox.
71
 *
72
 * # GtkLabel as GtkBuildable
73
 *
74
 * The GtkLabel implementation of the GtkBuildable interface supports a
75 76 77 78
 * custom <attributes> element, which supports any number of <attribute>
 * elements. The <attribute> element has attributes named “name“, “value“,
 * “start“ and “end“ and allows you to specify #PangoAttribute values for
 * this label.
79
 *
80
 * An example of a UI definition fragment specifying Pango attributes:
81
 * |[
82 83 84 85 86 87
 * <object class="GtkLabel">
 *   <attributes>
 *     <attribute name="weight" value="PANGO_WEIGHT_BOLD"/>
 *     <attribute name="background" value="red" start="5" end="10"/>"
 *   </attributes>
 * </object>
88
 * ]|
89
 *
90 91 92 93 94
 * The start and end attributes specify the range of characters to which the
 * Pango attribute applies. If start and end are not specified, the attribute is
 * applied to the whole text. Note that specifying ranges does not make much
 * sense with translatable attributes. Use markup embedded in the translatable
 * content instead.
95
 *
96
 * # Mnemonics
97
 *
98
 * Labels may contain “mnemonics”. Mnemonics are
99 100
 * underlined characters in the label, used for keyboard navigation.
 * Mnemonics are created by providing a string with an underscore before
101
 * the mnemonic character, such as `"_File"`, to the
102 103 104 105 106
 * functions gtk_label_new_with_mnemonic() or
 * gtk_label_set_text_with_mnemonic().
 *
 * Mnemonics automatically activate any activatable widget the label is
 * inside, such as a #GtkButton; if the label is not inside the
107 108
 * mnemonic’s target widget, you have to tell the label about the target
 * using gtk_label_set_mnemonic_widget(). Here’s a simple example where
109 110
 * the label is inside a button:
 *
111
 * |[<!-- language="C" -->
112
 *   // Pressing Alt+H will activate this button
113
 *   button = gtk_button_new ();
114 115
 *   label = gtk_label_new_with_mnemonic ("_Hello");
 *   gtk_container_add (GTK_CONTAINER (button), label);
116
 * ]|
117
 *
118
 * There’s a convenience function to create buttons with a mnemonic label
119 120
 * already inside:
 *
121
 * |[<!-- language="C" -->
122
 *   // Pressing Alt+H will activate this button
123
 *   button = gtk_button_new_with_mnemonic ("_Hello");
124
 * ]|
125 126 127 128 129
 *
 * To create a mnemonic for a widget alongside the label, such as a
 * #GtkEntry, you have to point the label at the entry with
 * gtk_label_set_mnemonic_widget():
 *
130
 * |[<!-- language="C" -->
131
 *   // Pressing Alt+H will focus the entry
132
 *   entry = gtk_entry_new ();
133 134
 *   label = gtk_label_new_with_mnemonic ("_Hello");
 *   gtk_label_set_mnemonic_widget (GTK_LABEL (label), entry);
135
 * ]|
136
 *
137
 * # Markup (styled text)
138 139
 *
 * To make it easy to format text in a label (changing colors,
140 141
 * fonts, etc.), label text can be provided in a simple
 * [markup format][PangoMarkupFormat].
142
 *
143
 * Here’s how to create a label with a small font:
144
 * |[<!-- language="C" -->
145 146
 *   label = gtk_label_new (NULL);
 *   gtk_label_set_markup (GTK_LABEL (label), "<small>Small text</small>");
147
 * ]|
148
 *
149
 * (See [complete documentation][PangoMarkupFormat] of available
150 151 152
 * tags in the Pango manual.)
 *
 * The markup passed to gtk_label_set_markup() must be valid; for example,
153 154 155
 * literal <, > and & characters must be escaped as &lt;, &gt;, and &amp;.
 * If you pass text obtained from the user, file, or a network to
 * gtk_label_set_markup(), you’ll want to escape it with
156 157 158 159 160
 * g_markup_escape_text() or g_markup_printf_escaped().
 *
 * Markup strings are just a convenient way to set the #PangoAttrList on
 * a label; gtk_label_set_attributes() may be a simpler way to set
 * attributes in some cases. Be careful though; #PangoAttrList tends to
161
 * cause internationalization problems, unless you’re applying attributes
162 163 164 165
 * to the entire string (i.e. unless you set the range of each attribute
 * to [0, %G_MAXINT)). The reason is that specifying the start_index and
 * end_index for a #PangoAttribute requires knowledge of the exact string
 * being displayed, so translations will cause problems.
166
 *
167
 * # Selectable labels
168
 *
169 170 171
 * Labels can be made selectable with gtk_label_set_selectable().
 * Selectable labels allow the user to copy the label contents to
 * the clipboard. Only labels that contain useful-to-copy information
172
 * — such as error messages — should be made selectable.
173
 *
174
 * # Text layout # {#label-text-layout}
175
 *
176 177 178 179 180 181 182 183 184 185
 * A label can contain any number of paragraphs, but will have
 * performance problems if it contains more than a small number.
 * Paragraphs are separated by newlines or other paragraph separators
 * understood by Pango.
 *
 * Labels can automatically wrap text if you call
 * gtk_label_set_line_wrap().
 *
 * gtk_label_set_justify() sets how the lines in a label align
 * with one another. If you want to set how the label as a whole
186 187
 * aligns in its available space, see the #GtkWidget::halign and
 * #GtkWidget:valign properties.
188 189 190 191 192 193 194 195 196 197 198 199
 *
 * The #GtkLabel:width-chars and #GtkLabel:max-width-chars properties
 * can be used to control the size allocation of ellipsized or wrapped
 * labels. For ellipsizing labels, if either is specified (and less
 * than the actual text size), it is used as the minimum width, and the actual
 * text size is used as the natural width of the label. For wrapping labels,
 * width-chars is used as the minimum width, if specified, and max-width-chars
 * is used as the natural width. Even if max-width-chars specified, wrapping
 * labels will be rewrapped to use all of the available width.
 *
 * Note that the interpretation of #GtkLabel:width-chars and
 * #GtkLabel:max-width-chars has changed a bit with the introduction of
200
 * [width-for-height geometry management.][geometry-management]
201
 *
202
 * # Links
203
 *
204
 * Since 2.18, GTK+ supports markup for clickable hyperlinks in addition
205 206 207 208
 * to regular Pango markup. The markup for links is borrowed from HTML,
 * using the `<a>` with “href“ and “title“ attributes. GTK+ renders links
 * similar to the way they appear in web browsers, with colored, underlined
 * text. The “title“ attribute is displayed as a tooltip on the link.
209
 *
210
 * An example looks like this:
211
 *
212
 * |[<!-- language="C" -->
213 214 215 216 217
 * const gchar *text =
 * "Go to the"
 * "<a href=\"http://www.gtk.org title="&lt;i&gt;Our&lt;/i&gt; website\">"
 * "GTK+ website</a> for more...";
 * gtk_label_set_markup (label, text);
218
 * ]|
219 220 221 222 223
 *
 * It is possible to implement custom handling for links and their tooltips with
 * the #GtkLabel::activate-link signal and the gtk_label_get_current_uri() function.
 */

224
struct _GtkLabelPrivate
225
{
226 227 228 229 230
  GtkLabelSelectionInfo *select_info;
  GtkWidget *mnemonic_widget;
  GtkWindow *mnemonic_window;

  PangoAttrList *attrs;
Benjamin Otte's avatar
Benjamin Otte committed
231
  PangoAttrList *markup_attrs;
232
  PangoLayout   *layout;
233

234 235 236
  GtkGesture    *drag_gesture;
  GtkGesture    *multipress_gesture;

237 238 239
  gchar   *label;
  gchar   *text;

240
  gdouble  angle;
241 242
  gfloat   xalign;
  gfloat   yalign;
243

244
  guint    mnemonics_visible  : 1;
245 246 247 248 249 250 251 252 253 254 255
  guint    jtype              : 2;
  guint    wrap               : 1;
  guint    use_underline      : 1;
  guint    use_markup         : 1;
  guint    ellipsize          : 3;
  guint    single_line_mode   : 1;
  guint    have_transform     : 1;
  guint    in_click           : 1;
  guint    wrap_mode          : 3;
  guint    pattern_set        : 1;
  guint    track_links        : 1;
256 257 258 259 260

  guint    mnemonic_keyval;

  gint     width_chars;
  gint     max_width_chars;
261
  gint     lines;
262
};
263 264 265 266 267 268 269

/* Notes about the handling of links:
 *
 * Links share the GtkLabelSelectionInfo struct with selectable labels.
 * There are some new fields for links. The links field contains the list
 * of GtkLabelLink structs that describe the links which are embedded in
 * the label. The active_link field points to the link under the mouse
270
 * pointer. For keyboard navigation, the “focus” link is determined by
271 272 273 274 275
 * finding the link which contains the selection_anchor position.
 * The link_clicked field is used with button press and release events
 * to ensure that pressing inside a link and releasing outside of it
 * does not activate the link.
 *
276 277 278
 * Links are rendered with the #GTK_STATE_FLAG_LINK/#GTK_STATE_FLAG_VISITED
 * state flags. When the mouse pointer is over a link, the pointer is changed
 * to indicate the link.
279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299
 *
 * Labels with links accept keyboard focus, and it is possible to move
 * the focus between the embedded links using Tab/Shift-Tab. The focus
 * is indicated by a focus rectangle that is drawn around the link text.
 * Pressing Enter activates the focussed link, and there is a suitable
 * context menu for links that can be opened with the Menu key. Pressing
 * Control-C copies the link URI to the clipboard.
 *
 * In selectable labels with links, link functionality is only available
 * when the selection is empty.
 */
typedef struct
{
  gchar *uri;
  gchar *title;     /* the title attribute, used as tooltip */
  gboolean visited; /* get set when the link is activated; this flag
                     * gets preserved over later set_markup() calls
                     */
  gint start;       /* position of the link in the PangoLayout */
  gint end;
} GtkLabelLink;
300

301 302 303 304 305
struct _GtkLabelSelectionInfo
{
  GdkWindow *window;
  gint selection_anchor;
  gint selection_end;
306
  GtkWidget *popup_menu;
307 308 309 310

  GList *links;
  GtkLabelLink *active_link;

311 312 313
  gint drag_start_x;
  gint drag_start_y;

314
  guint in_drag      : 1;
315
  guint select_words : 1;
316 317
  guint selectable   : 1;
  guint link_clicked : 1;
318
};
Elliot Lee's avatar
Elliot Lee committed
319

320 321 322 323
enum {
  MOVE_CURSOR,
  COPY_CLIPBOARD,
  POPULATE_POPUP,
324
  ACTIVATE_LINK,
325
  ACTIVATE_CURRENT_LINK,
326 327
  LAST_SIGNAL
};
328

329
enum {
330 331 332 333 334 335 336 337
  PROP_0,
  PROP_LABEL,
  PROP_ATTRIBUTES,
  PROP_USE_MARKUP,
  PROP_USE_UNDERLINE,
  PROP_JUSTIFY,
  PROP_PATTERN,
  PROP_WRAP,
338
  PROP_WRAP_MODE,
339
  PROP_SELECTABLE,
340
  PROP_MNEMONIC_KEYVAL,
341 342
  PROP_MNEMONIC_WIDGET,
  PROP_CURSOR_POSITION,
343
  PROP_SELECTION_BOUND,
344
  PROP_ELLIPSIZE,
345
  PROP_WIDTH_CHARS,
346
  PROP_SINGLE_LINE_MODE,
347
  PROP_ANGLE,
348
  PROP_MAX_WIDTH_CHARS,
349
  PROP_TRACK_VISITED_LINKS,
350 351 352
  PROP_LINES,
  PROP_XALIGN,
  PROP_YALIGN
353 354
};

355 356 357
/* When rotating ellipsizable text we want the natural size to request 
 * more to ensure the label wont ever ellipsize in an allocation of full natural size.
 * */
358
#define ROTATION_ELLIPSIZE_PADDING 2
359

360 361
static guint signals[LAST_SIGNAL] = { 0 };

362 363 364
static void gtk_label_set_property      (GObject          *object,
					 guint             prop_id,
					 const GValue     *value,
365
					 GParamSpec       *pspec);
366 367 368
static void gtk_label_get_property      (GObject          *object,
					 guint             prop_id,
					 GValue           *value,
369
					 GParamSpec       *pspec);
370
static void gtk_label_finalize          (GObject          *object);
371
static void gtk_label_destroy           (GtkWidget        *widget);
372 373
static void gtk_label_size_allocate     (GtkWidget        *widget,
                                         GtkAllocation    *allocation);
374 375
static void gtk_label_state_flags_changed   (GtkWidget        *widget,
                                             GtkStateFlags     prev_state);
376
static void gtk_label_style_updated     (GtkWidget        *widget);
377
static gboolean gtk_label_draw          (GtkWidget        *widget,
378
                                         cairo_t          *cr);
379 380
static gboolean gtk_label_focus         (GtkWidget         *widget,
                                         GtkDirectionType   direction);
Elliot Lee's avatar
Elliot Lee committed
381

382 383 384 385
static void gtk_label_realize           (GtkWidget        *widget);
static void gtk_label_unrealize         (GtkWidget        *widget);
static void gtk_label_map               (GtkWidget        *widget);
static void gtk_label_unmap             (GtkWidget        *widget);
Federico Mena Quintero's avatar
Federico Mena Quintero committed
386 387 388

static gboolean gtk_label_motion            (GtkWidget        *widget,
					     GdkEventMotion   *event);
389 390 391
static gboolean gtk_label_leave_notify      (GtkWidget        *widget,
                                             GdkEventCrossing *event);

392
static void     gtk_label_grab_focus        (GtkWidget        *widget);
393

394 395 396 397 398
static gboolean gtk_label_query_tooltip     (GtkWidget        *widget,
                                             gint              x,
                                             gint              y,
                                             gboolean          keyboard_tip,
                                             GtkTooltip       *tooltip);
399 400 401 402 403 404 405 406 407 408 409 410

static void gtk_label_set_text_internal          (GtkLabel      *label,
						  gchar         *str);
static void gtk_label_set_label_internal         (GtkLabel      *label,
						  gchar         *str);
static void gtk_label_set_use_markup_internal    (GtkLabel      *label,
						  gboolean       val);
static void gtk_label_set_use_underline_internal (GtkLabel      *label,
						  gboolean       val);
static void gtk_label_set_uline_text_internal    (GtkLabel      *label,
						  const gchar   *str);
static void gtk_label_set_pattern_internal       (GtkLabel      *label,
411 412
				                  const gchar   *pattern,
                                                  gboolean       is_mnemonic);
413
static void gtk_label_set_markup_internal        (GtkLabel      *label,
414 415 416
						  const gchar   *str,
						  gboolean       with_uline);
static void gtk_label_recalculate                (GtkLabel      *label);
417 418
static void gtk_label_hierarchy_changed          (GtkWidget     *widget,
						  GtkWidget     *old_toplevel);
419 420
static void gtk_label_screen_changed             (GtkWidget     *widget,
						  GdkScreen     *old_screen);
421
static gboolean gtk_label_popup_menu             (GtkWidget     *widget);
422

423 424
static void gtk_label_create_window       (GtkLabel *label);
static void gtk_label_destroy_window      (GtkLabel *label);
425 426 427
static void gtk_label_ensure_select_info  (GtkLabel *label);
static void gtk_label_clear_select_info   (GtkLabel *label);
static void gtk_label_update_cursor       (GtkLabel *label);
428
static void gtk_label_clear_layout        (GtkLabel *label);
429
static void gtk_label_ensure_layout       (GtkLabel *label);
430 431 432 433
static void gtk_label_select_region_index (GtkLabel *label,
                                           gint      anchor_index,
                                           gint      end_index);

434

435 436 437 438
static gboolean gtk_label_mnemonic_activate (GtkWidget         *widget,
					     gboolean           group_cycling);
static void     gtk_label_setup_mnemonic    (GtkLabel          *label,
					     guint              last_key);
439 440 441 442 443 444
static void     gtk_label_drag_data_get     (GtkWidget         *widget,
					     GdkDragContext    *context,
					     GtkSelectionData  *selection_data,
					     guint              info,
					     guint              time);

445 446 447 448 449 450 451 452 453 454 455 456 457 458
static void     gtk_label_buildable_interface_init     (GtkBuildableIface *iface);
static gboolean gtk_label_buildable_custom_tag_start   (GtkBuildable     *buildable,
							GtkBuilder       *builder,
							GObject          *child,
							const gchar      *tagname,
							GMarkupParser    *parser,
							gpointer         *data);

static void     gtk_label_buildable_custom_finished    (GtkBuildable     *buildable,
							GtkBuilder       *builder,
							GObject          *child,
							const gchar      *tagname,
							gpointer          user_data);

459

460
static void connect_mnemonics_visible_notify    (GtkLabel   *label);
461 462 463 464
static gboolean      separate_uline_pattern     (const gchar  *str,
                                                 guint        *accel_key,
                                                 gchar       **new_str,
                                                 gchar       **pattern);
465 466


467
/* For selectable labels: */
468 469 470 471 472 473 474 475 476 477 478 479
static void gtk_label_move_cursor        (GtkLabel        *label,
					  GtkMovementStep  step,
					  gint             count,
					  gboolean         extend_selection);
static void gtk_label_copy_clipboard     (GtkLabel        *label);
static void gtk_label_select_all         (GtkLabel        *label);
static void gtk_label_do_popup           (GtkLabel        *label,
					  GdkEventButton  *event);
static gint gtk_label_move_forward_word  (GtkLabel        *label,
					  gint             start);
static gint gtk_label_move_backward_word (GtkLabel        *label,
					  gint             start);
480

481 482
/* For links: */
static void          gtk_label_clear_links      (GtkLabel  *label);
483 484 485
static gboolean      gtk_label_activate_link    (GtkLabel    *label,
                                                 const gchar *uri);
static void          gtk_label_activate_current_link (GtkLabel *label);
486
static GtkLabelLink *gtk_label_get_current_link (GtkLabel  *label);
487 488
static void          emit_activate_link         (GtkLabel     *label,
                                                 GtkLabelLink *link);
489

490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509
/* Event controller callbacks */
static void   gtk_label_multipress_gesture_pressed  (GtkGestureMultiPress *gesture,
                                                     gint                  n_press,
                                                     gdouble               x,
                                                     gdouble               y,
                                                     GtkLabel             *label);
static void   gtk_label_multipress_gesture_released (GtkGestureMultiPress *gesture,
                                                     gint                  n_press,
                                                     gdouble               x,
                                                     gdouble               y,
                                                     GtkLabel             *label);
static void   gtk_label_drag_gesture_begin          (GtkGestureDrag *gesture,
                                                     gdouble         start_x,
                                                     gdouble         start_y,
                                                     GtkLabel       *label);
static void   gtk_label_drag_gesture_update         (GtkGestureDrag *gesture,
                                                     gdouble         offset_x,
                                                     gdouble         offset_y,
                                                     GtkLabel       *label);

510 511 512 513 514 515 516 517 518 519 520 521 522 523 524
static GtkSizeRequestMode gtk_label_get_request_mode                (GtkWidget           *widget);
static void               gtk_label_get_preferred_width             (GtkWidget           *widget,
                                                                     gint                *minimum_size,
                                                                     gint                *natural_size);
static void               gtk_label_get_preferred_height            (GtkWidget           *widget,
                                                                     gint                *minimum_size,
                                                                     gint                *natural_size);
static void               gtk_label_get_preferred_width_for_height  (GtkWidget           *widget,
                                                                     gint                 height,
                                                                     gint                *minimum_width,
                                                                     gint                *natural_width);
static void               gtk_label_get_preferred_height_for_width  (GtkWidget           *widget,
                                                                     gint                 width,
                                                                     gint                *minimum_height,
                                                                     gint                *natural_height);
525 526 527 528 529 530
static void    gtk_label_get_preferred_height_and_baseline_for_width (GtkWidget          *widget,
								      gint                width,
								      gint               *minimum_height,
								      gint               *natural_height,
								      gint               *minimum_baseline,
								      gint               *natural_baseline);
531

532 533
static GtkBuildableIface *buildable_parent_iface = NULL;

Matthias Clasen's avatar
Matthias Clasen committed
534
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
535
G_DEFINE_TYPE_WITH_CODE (GtkLabel, gtk_label, GTK_TYPE_MISC,
536
                         G_ADD_PRIVATE (GtkLabel)
Matthias Clasen's avatar
Matthias Clasen committed
537 538 539
                         G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
                                                gtk_label_buildable_interface_init))
G_GNUC_END_IGNORE_DEPRECATIONS
Elliot Lee's avatar
Elliot Lee committed
540

541 542 543 544 545 546 547 548 549 550
static void
add_move_binding (GtkBindingSet  *binding_set,
		  guint           keyval,
		  guint           modmask,
		  GtkMovementStep step,
		  gint            count)
{
  g_return_if_fail ((modmask & GDK_SHIFT_MASK) == 0);
  
  gtk_binding_entry_add_signal (binding_set, keyval, modmask,
551
				"move-cursor", 3,
Manish Singh's avatar
Manish Singh committed
552
				G_TYPE_ENUM, step,
553
				G_TYPE_INT, count,
Manish Singh's avatar
Manish Singh committed
554
				G_TYPE_BOOLEAN, FALSE);
555 556 557

  /* Selection-extending version */
  gtk_binding_entry_add_signal (binding_set, keyval, modmask | GDK_SHIFT_MASK,
558
				"move-cursor", 3,
Manish Singh's avatar
Manish Singh committed
559
				G_TYPE_ENUM, step,
560
				G_TYPE_INT, count,
Manish Singh's avatar
Manish Singh committed
561
				G_TYPE_BOOLEAN, TRUE);
562 563
}

564
static void
Elliot Lee's avatar
Elliot Lee committed
565 566
gtk_label_class_init (GtkLabelClass *class)
{
567
  GObjectClass *gobject_class = G_OBJECT_CLASS (class);
568
  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
569
  GtkBindingSet *binding_set;
570

571 572
  gobject_class->set_property = gtk_label_set_property;
  gobject_class->get_property = gtk_label_get_property;
573
  gobject_class->finalize = gtk_label_finalize;
574

575
  widget_class->destroy = gtk_label_destroy;
576
  widget_class->size_allocate = gtk_label_size_allocate;
577
  widget_class->state_flags_changed = gtk_label_state_flags_changed;
578
  widget_class->style_updated = gtk_label_style_updated;
579
  widget_class->query_tooltip = gtk_label_query_tooltip;
580
  widget_class->draw = gtk_label_draw;
581 582 583 584 585
  widget_class->realize = gtk_label_realize;
  widget_class->unrealize = gtk_label_unrealize;
  widget_class->map = gtk_label_map;
  widget_class->unmap = gtk_label_unmap;
  widget_class->motion_notify_event = gtk_label_motion;
586
  widget_class->leave_notify_event = gtk_label_leave_notify;
587
  widget_class->hierarchy_changed = gtk_label_hierarchy_changed;
588
  widget_class->screen_changed = gtk_label_screen_changed;
589
  widget_class->mnemonic_activate = gtk_label_mnemonic_activate;
590
  widget_class->drag_data_get = gtk_label_drag_data_get;
591
  widget_class->grab_focus = gtk_label_grab_focus;
592 593
  widget_class->popup_menu = gtk_label_popup_menu;
  widget_class->focus = gtk_label_focus;
594 595 596 597 598
  widget_class->get_request_mode = gtk_label_get_request_mode;
  widget_class->get_preferred_width = gtk_label_get_preferred_width;
  widget_class->get_preferred_height = gtk_label_get_preferred_height;
  widget_class->get_preferred_width_for_height = gtk_label_get_preferred_width_for_height;
  widget_class->get_preferred_height_for_width = gtk_label_get_preferred_height_for_width;
599
  widget_class->get_preferred_height_and_baseline_for_width = gtk_label_get_preferred_height_and_baseline_for_width;
600 601 602

  class->move_cursor = gtk_label_move_cursor;
  class->copy_clipboard = gtk_label_copy_clipboard;
603 604
  class->activate_link = gtk_label_activate_link;

Matthias Clasen's avatar
Matthias Clasen committed
605 606 607 608 609 610 611 612
  /**
   * GtkLabel::move-cursor:
   * @entry: the object which received the signal
   * @step: the granularity of the move, as a #GtkMovementStep
   * @count: the number of @step units to move
   * @extend_selection: %TRUE if the move should extend the selection
   *
   * The ::move-cursor signal is a
613
   * [keybinding signal][GtkBindingSignal]
Matthias Clasen's avatar
Matthias Clasen committed
614 615 616 617 618
   * which gets emitted when the user initiates a cursor movement.
   * If the cursor is not visible in @entry, this signal causes
   * the viewport to be moved instead.
   *
   * Applications should not connect to it, but may emit it with
619
   * g_signal_emit_by_name() if they need to control the cursor
Matthias Clasen's avatar
Matthias Clasen committed
620 621 622 623 624 625
   * programmatically.
   *
   * The default bindings for this signal come in two variants,
   * the variant with the Shift modifier extends the selection,
   * the variant without the Shift modifer does not.
   * There are too many key combinations to list them all here.
626 627 628
   * - Arrow keys move by individual characters/lines
   * - Ctrl-arrow key combinations move by words/paragraphs
   * - Home/End keys move to the ends of the buffer
Matthias Clasen's avatar
Matthias Clasen committed
629
   */
630
  signals[MOVE_CURSOR] = 
631
    g_signal_new (I_("move-cursor"),
Manish Singh's avatar
Manish Singh committed
632 633 634 635 636 637 638 639 640
		  G_OBJECT_CLASS_TYPE (gobject_class),
		  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
		  G_STRUCT_OFFSET (GtkLabelClass, move_cursor),
		  NULL, NULL,
		  _gtk_marshal_VOID__ENUM_INT_BOOLEAN,
		  G_TYPE_NONE, 3,
		  GTK_TYPE_MOVEMENT_STEP,
		  G_TYPE_INT,
		  G_TYPE_BOOLEAN);
Matthias Clasen's avatar
Matthias Clasen committed
641 642 643 644 645 646

   /**
   * GtkLabel::copy-clipboard:
   * @label: the object which received the signal
   *
   * The ::copy-clipboard signal is a
647
   * [keybinding signal][GtkBindingSignal]
Matthias Clasen's avatar
Matthias Clasen committed
648 649 650 651
   * which gets emitted to copy the selection to the clipboard.
   *
   * The default binding for this signal is Ctrl-c.
   */ 
652
  signals[COPY_CLIPBOARD] =
653
    g_signal_new (I_("copy-clipboard"),
Manish Singh's avatar
Manish Singh committed
654 655 656 657 658 659
		  G_OBJECT_CLASS_TYPE (gobject_class),
		  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
		  G_STRUCT_OFFSET (GtkLabelClass, copy_clipboard),
		  NULL, NULL,
		  _gtk_marshal_VOID__VOID,
		  G_TYPE_NONE, 0);
660
  
Matthias Clasen's avatar
Matthias Clasen committed
661 662 663 664 665 666 667 668 669 670 671 672
  /**
   * GtkLabel::populate-popup:
   * @label: The label on which the signal is emitted
   * @menu: the menu that is being populated
   *
   * The ::populate-popup signal gets emitted before showing the
   * context menu of the label. Note that only selectable labels
   * have context menus.
   *
   * If you need to add items to the context menu, connect
   * to this signal and append your menuitems to the @menu.
   */
673
  signals[POPULATE_POPUP] =
674
    g_signal_new (I_("populate-popup"),
Manish Singh's avatar
Manish Singh committed
675 676 677 678 679 680 681 682
		  G_OBJECT_CLASS_TYPE (gobject_class),
		  G_SIGNAL_RUN_LAST,
		  G_STRUCT_OFFSET (GtkLabelClass, populate_popup),
		  NULL, NULL,
		  _gtk_marshal_VOID__OBJECT,
		  G_TYPE_NONE, 1,
		  GTK_TYPE_MENU);

683
    /**
684 685
     * GtkLabel::activate-current-link:
     * @label: The label on which the signal was emitted
686
     *
687
     * A [keybinding signal][GtkBindingSignal]
688 689 690 691 692 693 694
     * which gets emitted when the user activates a link in the label.
     *
     * Applications may also emit the signal with g_signal_emit_by_name()
     * if they need to control activation of URIs programmatically.
     *
     * The default bindings for this signal are all forms of the Enter key.
     *
695 696 697 698
     * Since: 2.18
     */
    signals[ACTIVATE_CURRENT_LINK] =
      g_signal_new_class_handler ("activate-current-link",
699
                                  G_TYPE_FROM_CLASS (gobject_class),
700 701 702 703 704 705 706 707 708 709 710 711 712 713 714
                                  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
                                  G_CALLBACK (gtk_label_activate_current_link),
                                  NULL, NULL,
                                  _gtk_marshal_VOID__VOID,
                                  G_TYPE_NONE, 0);

    /**
     * GtkLabel::activate-link:
     * @label: The label on which the signal was emitted
     * @uri: the URI that is activated
     *
     * The signal which gets emitted to activate a URI.
     * Applications may connect to it to override the default behaviour,
     * which is to call gtk_show_uri().
     *
715 716 717 718 719 720
     * Returns: %TRUE if the link has been activated
     *
     * Since: 2.18
     */
    signals[ACTIVATE_LINK] =
      g_signal_new ("activate-link",
721
                    G_TYPE_FROM_CLASS (gobject_class),
722
                    G_SIGNAL_RUN_LAST,
723 724
                    G_STRUCT_OFFSET (GtkLabelClass, activate_link),
                    _gtk_boolean_handled_accumulator, NULL,
725 726
                    _gtk_marshal_BOOLEAN__STRING,
                    G_TYPE_BOOLEAN, 1, G_TYPE_STRING);
727

Manish Singh's avatar
Manish Singh committed
728
  g_object_class_install_property (gobject_class,
729 730
                                   PROP_LABEL,
                                   g_param_spec_string ("label",
731 732
                                                        P_("Label"),
                                                        P_("The text of the label"),
733
                                                        "",
734
                                                        GTK_PARAM_READWRITE));
735 736 737
  g_object_class_install_property (gobject_class,
				   PROP_ATTRIBUTES,
				   g_param_spec_boxed ("attributes",
738 739
						       P_("Attributes"),
						       P_("A list of style attributes to apply to the text of the label"),
740
						       PANGO_TYPE_ATTR_LIST,
741
						       GTK_PARAM_READWRITE));
742 743
  g_object_class_install_property (gobject_class,
                                   PROP_USE_MARKUP,
Matthias Clasen's avatar
x  
Matthias Clasen committed
744
                                   g_param_spec_boolean ("use-markup",
745 746
							 P_("Use markup"),
							 P_("The text of the label includes XML markup. See pango_parse_markup()"),
747
                                                        FALSE,
748
                                                        GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
749 750
  g_object_class_install_property (gobject_class,
                                   PROP_USE_UNDERLINE,
Matthias Clasen's avatar
x  
Matthias Clasen committed
751
                                   g_param_spec_boolean ("use-underline",
752 753
							 P_("Use underline"),
							 P_("If set, an underline in the text indicates the next character should be used for the mnemonic accelerator key"),
754
                                                        FALSE,
755
                                                        GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
756 757 758 759

  g_object_class_install_property (gobject_class,
				   PROP_JUSTIFY,
                                   g_param_spec_enum ("justify",
760
                                                      P_("Justification"),
761
                                                      P_("The alignment of the lines in the text of the label relative to each other. This does NOT affect the alignment of the label within its allocation. See GtkLabel:xalign for that"),
762 763
						      GTK_TYPE_JUSTIFICATION,
						      GTK_JUSTIFY_LEFT,
764
                                                      GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
765

766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801
  /**
   * GtkLabel:xalign:
   *
   * The xalign property determines the horizontal aligment of the label text
   * inside the labels size allocation. Compare this to #GtkWidget:halign,
   * which determines how the labels size allocation is positioned in the
   * space available for the label.
   *
   * Since: 3.16
   */
  g_object_class_install_property (gobject_class,
                                   PROP_XALIGN,
                                   g_param_spec_float ("xalign",
                                                       P_("X align"),
                                                       P_("The horizontal alignment, from 0 (left) to 1 (right). Reversed for RTL layouts."),
                                                       0.0, 1.0, 0.5,
                                                       GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));

  /**
   * GtkLabel:yalign:
   *
   * The yalign property determines the vertical aligment of the label text
   * inside the labels size allocation. Compare this to #GtkWidget:valign,
   * which determines how the labels size allocation is positioned in the
   * space available for the label.
   *
   * Since: 3.16
   */
  g_object_class_install_property (gobject_class,
                                   PROP_YALIGN,
                                   g_param_spec_float ("yalign",
                                                       P_("Y align"),
                                                       P_("The vertical alignment, from 0 (top) to 1 (bottom)"),
                                                       0.0, 1.0, 0.5,
                                                       GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));

802 803 804
  g_object_class_install_property (gobject_class,
                                   PROP_PATTERN,
                                   g_param_spec_string ("pattern",
805 806
                                                        P_("Pattern"),
                                                        P_("A string with _ characters in positions correspond to characters in the text to underline"),
807
                                                        NULL,
808
                                                        GTK_PARAM_WRITABLE));
809 810 811 812

  g_object_class_install_property (gobject_class,
                                   PROP_WRAP,
                                   g_param_spec_boolean ("wrap",
813 814
                                                        P_("Line wrap"),
                                                        P_("If set, wrap lines if the text becomes too wide"),
815
                                                        FALSE,
816 817
                                                        GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));

818 819 820
  /**
   * GtkLabel:wrap-mode:
   *
821 822 823
   * If line wrapping is on (see the #GtkLabel:wrap property) this controls 
   * how the line wrapping is done. The default is %PANGO_WRAP_WORD, which 
   * means wrap on word boundaries.
824 825 826 827 828 829 830 831 832 833
   *
   * Since: 2.10
   */
  g_object_class_install_property (gobject_class,
                                   PROP_WRAP_MODE,
                                   g_param_spec_enum ("wrap-mode",
						      P_("Line wrap mode"),
						      P_("If wrap is set, controls how linewrapping is done"),
						      PANGO_TYPE_WRAP_MODE,
						      PANGO_WRAP_WORD,
834
						      GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
835 836 837
  g_object_class_install_property (gobject_class,
                                   PROP_SELECTABLE,
                                   g_param_spec_boolean ("selectable",
838 839
                                                        P_("Selectable"),
                                                        P_("Whether the label text can be selected with the mouse"),
840
                                                        FALSE,
841
                                                        GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
842
  g_object_class_install_property (gobject_class,
843
                                   PROP_MNEMONIC_KEYVAL,
Matthias Clasen's avatar
x  
Matthias Clasen committed
844
                                   g_param_spec_uint ("mnemonic-keyval",
845 846
						      P_("Mnemonic key"),
						      P_("The mnemonic accelerator key for this label"),
847 848
						      0,
						      G_MAXUINT,
849
						      GDK_KEY_VoidSymbol,
850
						      GTK_PARAM_READABLE));
851 852
  g_object_class_install_property (gobject_class,
                                   PROP_MNEMONIC_WIDGET,
Matthias Clasen's avatar
x  
Matthias Clasen committed
853
                                   g_param_spec_object ("mnemonic-widget",
854 855
							P_("Mnemonic widget"),
							P_("The widget to be activated when the label's mnemonic "
856
							  "key is pressed"),
857
							GTK_TYPE_WIDGET,
858
							GTK_PARAM_READWRITE));
859

860 861
  g_object_class_install_property (gobject_class,
                                   PROP_CURSOR_POSITION,
Matthias Clasen's avatar
x  
Matthias Clasen committed
862
                                   g_param_spec_int ("cursor-position",
863 864
                                                     P_("Cursor Position"),
                                                     P_("The current position of the insertion cursor in chars"),
865 866 867
                                                     0,
                                                     G_MAXINT,
                                                     0,
868
                                                     GTK_PARAM_READABLE));
869 870 871
  
  g_object_class_install_property (gobject_class,
                                   PROP_SELECTION_BOUND,
Matthias Clasen's avatar
x  
Matthias Clasen committed
872
                                   g_param_spec_int ("selection-bound",
873 874
                                                     P_("Selection Bound"),
                                                     P_("The position of the opposite end of the selection from the cursor in chars"),
875 876 877
                                                     0,
                                                     G_MAXINT,
                                                     0,
878
                                                     GTK_PARAM_READABLE));
879
  
880 881 882
  /**
   * GtkLabel:ellipsize:
   *
883 884
   * The preferred place to ellipsize the string, if the label does 
   * not have enough room to display the entire string, specified as a 
885
   * #PangoEllipsizeMode. 
886
   *
887 888 889 890
   * Note that setting this property to a value other than 
   * %PANGO_ELLIPSIZE_NONE has the side-effect that the label requests 
   * only enough space to display the ellipsis "...". In particular, this 
   * means that ellipsizing labels do not work well in notebook tabs, unless 
891
   * the #GtkNotebook tab-expand child property is set to %TRUE. Other ways
892 893
   * to set a label's width are gtk_widget_set_size_request() and
   * gtk_label_set_width_chars().
894 895 896
   *
   * Since: 2.6
   */
897 898 899 900
  g_object_class_install_property (gobject_class,
				   PROP_ELLIPSIZE,
                                   g_param_spec_enum ("ellipsize",
                                                      P_("Ellipsize"),
901
                                                      P_("The preferred place to ellipsize the string, if the label does not have enough room to display the entire string"),
902 903
						      PANGO_TYPE_ELLIPSIZE_MODE,
						      PANGO_ELLIPSIZE_NONE,
904
                                                      GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
905 906 907

  /**
   * GtkLabel:width-chars:
908
   *
909
   * The desired width of the label, in characters. If this property is set to
910 911
   * -1, the width will be calculated automatically.
   *
912
   * See the section on [text layout][label-text-layout]
913 914
   * for details of how #GtkLabel:width-chars and #GtkLabel:max-width-chars
   * determine the width of ellipsized and wrapped labels.
915
   *
916 917 918 919
   * Since: 2.6
   **/
  g_object_class_install_property (gobject_class,
                                   PROP_WIDTH_CHARS,
Matthias Clasen's avatar
x  
Matthias Clasen committed
920
                                   g_param_spec_int ("width-chars",
921
                                                     P_("Width In Characters"),
922 923 924 925
                                                     P_("The desired width of the label, in characters"),
                                                     -1,
                                                     G_MAXINT,
                                                     -1,
926
                                                     GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
927
  
928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944
  /**
   * GtkLabel:single-line-mode:
   * 
   * Whether the label is in single line mode. In single line mode,
   * the height of the label does not depend on the actual text, it
   * is always set to ascent + descent of the font. This can be an
   * advantage in situations where resizing the label because of text 
   * changes would be distracting, e.g. in a statusbar.
   *
   * Since: 2.6
   **/
  g_object_class_install_property (gobject_class,
                                   PROP_SINGLE_LINE_MODE,
                                   g_param_spec_boolean ("single-line-mode",
                                                        P_("Single Line Mode"),
                                                        P_("Whether the label is in single line mode"),
                                                        FALSE,
945
                                                        GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964

  /**
   * GtkLabel:angle:
   * 
   * The angle that the baseline of the label makes with the horizontal,
   * in degrees, measured counterclockwise. An angle of 90 reads from
   * from bottom to top, an angle of 270, from top to bottom. Ignored
   * if the label is selectable, wrapped, or ellipsized.
   *
   * Since: 2.6
   **/
  g_object_class_install_property (gobject_class,
                                   PROP_ANGLE,
                                   g_param_spec_double ("angle",
							P_("Angle"),
							P_("Angle at which the label is rotated"),
							0.0,
							360.0,
							0.0, 
965
							GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
966
  
967 968 969
  /**
   * GtkLabel:max-width-chars:
   * 
970
   * The desired maximum width of the label, in characters. If this property 
971 972
   * is set to -1, the width will be calculated automatically.
   *
973
   * See the section on [text layout][label-text-layout]
974 975 976
   * for details of how #GtkLabel:width-chars and #GtkLabel:max-width-chars
   * determine the width of ellipsized and wrapped labels.
   *
977 978 979 980
   * Since: 2.6
   **/
  g_object_class_install_property (gobject_class,
                                   PROP_MAX_WIDTH_CHARS,
Matthias Clasen's avatar
x  
Matthias Clasen committed
981
                                   g_param_spec_int ("max-width-chars",
982 983
                                                     P_("Maximum Width In Characters"),
                                                     P_("The desired maximum width of the label, in characters"),
984 985 986
                                                     -1,
                                                     G_MAXINT,
                                                     -1,
987
                                                     GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
988 989 990 991 992

  /**
   * GtkLabel:track-visited-links:
   *
   * Set this property to %TRUE to make the label track which links
993 994
   * have been visited. It will then apply the #GTK_STATE_FLAG_VISITED
   * when rendering this link, in addition to #GTK_STATE_FLAG_LINK.
995 996 997 998 999 1000 1001 1002 1003
   *
   * Since: 2.18
   */
  g_object_class_install_property (gobject_class,
                                   PROP_TRACK_VISITED_LINKS,
                                   g_param_spec_boolean ("track-visited-links",
                                                         P_("Track visited links"),
                                                         P_("Whether visited links should be tracked"),
                                                         TRUE,
1004
                                                         GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023

  /**
   * GtkLabel:lines:
   *
   * The number of lines to which an ellipsized, wrapping label
   * should be limited. This property has no effect if the
   * label is not wrapping or ellipsized. Set this property to
   * -1 if you don't want to limit the number of lines.
   *
   * Since: 3.10
   */
  g_object_class_install_property (gobject_class,
                                   PROP_LINES,
                                   g_param_spec_int ("lines",
                                                     P_("Number of lines"),
                                                     P_("The desired number of lines, when ellipsizing a wrapping label"),
                                                     -1,
                                                     G_MAXINT,
                                                     -1,
1024
                                                     GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
1025 1026 1027 1028 1029 1030 1031
  /*
   * Key bindings
   */

  binding_set = gtk_binding_set_by_class (class);

  /* Moving the insertion point */
1032
  add_move_binding (binding_set, GDK_KEY_Right, 0,
1033 1034
		    GTK_MOVEMENT_VISUAL_POSITIONS, 1);
  
1035
  add_move_binding (binding_set, GDK_KEY_Left, 0,
1036 1037
		    GTK_MOVEMENT_VISUAL_POSITIONS, -1);

1038
  add_move_binding (binding_set, GDK_KEY_KP_Right, 0,
1039 1040
		    GTK_MOVEMENT_VISUAL_POSITIONS, 1);
  
1041
  add_move_binding (binding_set, GDK_KEY_KP_Left, 0,
1042 1043
		    GTK_MOVEMENT_VISUAL_POSITIONS, -1);
  
1044
  add_move_binding (binding_set, GDK_KEY_f, GDK_CONTROL_MASK,
1045 1046
		    GTK_MOVEMENT_LOGICAL_POSITIONS, 1);
  
1047
  add_move_binding (binding_set, GDK_KEY_b, GDK_CONTROL_MASK,
1048 1049
		    GTK_MOVEMENT_LOGICAL_POSITIONS, -1);
  
1050
  add_move_binding (binding_set, GDK_KEY_Right, GDK_CONTROL_MASK,
1051 1052
		    GTK_MOVEMENT_WORDS, 1);

1053
  add_move_binding (binding_set, GDK_KEY_Left, GDK_CONTROL_MASK,
1054 1055
		    GTK_MOVEMENT_WORDS, -1);

1056
  add_move_binding (binding_set, GDK_KEY_KP_Right, GDK_CONTROL_MASK,
1057 1058
		    GTK_MOVEMENT_WORDS, 1);

1059
  add_move_binding (binding_set, GDK_KEY_KP_Left, GDK_CONTROL_MASK,
1060 1061
		    GTK_MOVEMENT_WORDS, -1);

1062
  /* select all */
1063
  gtk_binding_entry_add_signal (binding_set, GDK_KEY_a, GDK_CONTROL_MASK,
1064
				"move-cursor", 3,
1065 1066 1067 1068
				G_TYPE_ENUM, GTK_MOVEMENT_PARAGRAPH_ENDS,
				G_TYPE_INT, -1,
				G_TYPE_BOOLEAN, FALSE);

1069
  gtk_binding_entry_add_signal (binding_set, GDK_KEY_a, GDK_CONTROL_MASK,
1070
				"move-cursor", 3,
1071 1072 1073 1074
				G_TYPE_ENUM, GTK_MOVEMENT_PARAGRAPH_ENDS,
				G_TYPE_INT, 1,
				G_TYPE_BOOLEAN, TRUE);

1075
  gtk_binding_entry_add_signal (binding_set, GDK_KEY_slash, GDK_CONTROL_MASK,
1076
				"move-cursor", 3,
1077 1078 1079 1080
				G_TYPE_ENUM, GTK_MOVEMENT_PARAGRAPH_ENDS,
				G_TYPE_INT, -1,
				G_TYPE_BOOLEAN, FALSE);

1081
  gtk_binding_entry_add_signal (binding_set, GDK_KEY_slash, GDK_CONTROL_MASK,
1082
				"move-cursor", 3,
1083 1084 1085 1086 1087
				G_TYPE_ENUM, GTK_MOVEMENT_PARAGRAPH_ENDS,
				G_TYPE_INT, 1,
				G_TYPE_BOOLEAN, TRUE);

  /* unselect all */
1088
  gtk_binding_entry_add_signal (binding_set, GDK_KEY_a, GDK_SHIFT_MASK | GDK_CONTROL_MASK,
1089
				"move-cursor", 3,
1090 1091 1092 1093
				G_TYPE_ENUM, GTK_MOVEMENT_PARAGRAPH_ENDS,
				G_TYPE_INT, 0,
				G_TYPE_BOOLEAN, FALSE);

1094
  gtk_binding_entry_add_signal (binding_set, GDK_KEY_backslash, GDK_CONTROL_MASK,
1095
				"move-cursor", 3,
1096 1097 1098
				G_TYPE_ENUM, GTK_MOVEMENT_PARAGRAPH_ENDS,
				G_TYPE_INT, 0,
				G_TYPE_BOOLEAN, FALSE);
1099

1100
  add_move_binding (binding_set, GDK_KEY_f, GDK_MOD1_MASK,
1101 1102
		    GTK_MOVEMENT_WORDS, 1);

1103
  add_move_binding (binding_set, GDK_KEY_b, GDK_MOD1_MASK,
1104 1105
		    GTK_MOVEMENT_WORDS, -1);

1106
  add_move_binding (binding_set, GDK_KEY_Home, 0,
1107 1108
		    GTK_MOVEMENT_DISPLAY_LINE_ENDS, -1);

1109
  add_move_binding (binding_set, GDK_KEY_End, 0,
1110 1111
		    GTK_MOVEMENT_DISPLAY_LINE_ENDS, 1);

1112
  add_move_binding (binding_set, GDK_KEY_KP_Home, 0,
1113 1114
		    GTK_MOVEMENT_DISPLAY_LINE_ENDS, -1);

1115
  add_move_binding (binding_set, GDK_KEY_KP_End, 0,
1116 1117
		    GTK_MOVEMENT_DISPLAY_LINE_ENDS, 1);
  
1118
  add_move_binding (binding_set, GDK_KEY_Home, GDK_CONTROL_MASK,
1119 1120
		    GTK_MOVEMENT_BUFFER_ENDS, -1);

1121
  add_move_binding (binding_set, GDK_KEY_End, GDK_CONTROL_MASK,
1122 1123
		    GTK_MOVEMENT_BUFFER_ENDS, 1);

1124
  add_move_binding (binding_set, GDK_KEY_KP_Home, GDK_CONTROL_MASK,
1125 1126
		    GTK_MOVEMENT_BUFFER_ENDS, -1);

1127
  add_move_binding (binding_set, GDK_KEY_KP_End, GDK_CONTROL_MASK,
1128 1129 1130
		    GTK_MOVEMENT_BUFFER_ENDS, 1);

  /* copy */
1131
  gtk_binding_entry_add_signal (binding_set, GDK_KEY_c, GDK_CONTROL_MASK,
1132
				"copy-clipboard", 0);
1133

1134
  gtk_binding_entry_add_signal (binding_set, GDK_KEY_Return, 0,
1135
				"activate-current-link", 0);
1136
  gtk_binding_entry_add_signal (binding_set, GDK_KEY_ISO_Enter, 0,
1137
				"activate-current-link", 0);
1138
  gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Enter, 0,
1139
				"activate-current-link", 0);
1140

1141
  gtk_widget_class_set_accessible_type (widget_class, GTK_TYPE_LABEL_ACCESSIBLE);
Elliot Lee's avatar
Elliot Lee committed
1142 1143
}

1144 1145 1146 1147
static void 
gtk_label_set_property (GObject      *object,
			guint         prop_id,
			const GValue *value,
1148
			GParamSpec   *pspec)
1149
{
1150
  GtkLabel *label = GTK_LABEL (object);
1151

1152
  switch (prop_id)
1153
    {
1154
    case PROP_LABEL:
1155
      gtk_label_set_label (label, g_value_get_string (value));
1156 1157 1158 1159 1160
      break;
    case PROP_ATTRIBUTES:
      gtk_label_set_attributes (label, g_value_get_boxed (value));
      break;
    case PROP_USE_MARKUP:
1161
      gtk_label_set_use_markup (label, g_value_get_boolean (value));
1162
      break;
1163
    case PROP_USE_UNDERLINE:
1164
      gtk_label_set_use_underline (label, g_value_get_boolean (value));
1165
      break;
1166 1167
    case PROP_JUSTIFY:
      gtk_label_set_justify (label, g_value_get_enum (value));
1168
      break;
1169 1170 1171 1172 1173 1174
    case PROP_PATTERN:
      gtk_label_set_pattern (label, g_value_get_string (value));
      break;
    case PROP_WRAP:
      gtk_label_set_line_wrap (label, g_value_get_boolean (value));
      break;	  
1175 1176 1177
    case PROP_WRAP_MODE:
      gtk_label_set_line_wrap_mode (label, g_value_get_enum (value));
      break;	  
1178 1179
    case PROP_SELECTABLE:
      gtk_label_set_selectable (label, g_value_get_boolean (value));
1180
      break;	  
1181 1182 1183
    case PROP_MNEMONIC_WIDGET:
      gtk_label_set_mnemonic_widget (label, (GtkWidget*) g_value_get_object (value));
      break;
1184 1185 1186
    case PROP_ELLIPSIZE:
      gtk_label_set_ellipsize (label, g_value_get_enum (value));
      break;
1187 1188 1189
    case PROP_WIDTH_CHARS:
      gtk_label_set_width_chars (label, g_value_get_int (value));
      break;
1190 1191 1192
    case PROP_SINGLE_LINE_MODE:
      gtk_label_set_single_line_mode (label, g_value_get_boolean (value));
      break;	  
1193 1194
    case PROP_ANGLE:
      gtk_label_set_angle (label, g_value_get_double (value));
1195 1196 1197 1198
      break;
    case PROP_MAX_WIDTH_CHARS:
      gtk_label_set_max_width_chars (label, g_value_get_int (value));
      break;
1199 1200 1201
    case PROP_TRACK_VISITED_LINKS:
      gtk_label_set_track_visited_links (label, g_value_get_boolean (value));
      break;
1202 1203 1204
    case PROP_LINES:
      gtk_label_set_lines (label, g_value_get_int (value));
      break;
1205 1206 1207 1208 1209 1210
    case PROP_XALIGN:
      gtk_label_set_xalign (label, g_value_get_float (value));
      break;
    case PROP_YALIGN:
      gtk_label_set_yalign (label, g_value_get_float (value));
      break;
Tim Janik's avatar
Tim Janik committed
1211
    default:
1212
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
Tim Janik's avatar
Tim Janik committed
1213
      break;
1214 1215 1216
    }
}

1217 1218 1219 1220
static void 
gtk_label_get_property (GObject     *object,
			guint        prop_id,
			GValue      *value,
1221
			GParamSpec  *pspec)
1222
{
1223
  GtkLabel *label = GTK_LABEL (object);
1224
  GtkLabelPrivate *priv = label->priv;
1225

1226
  switch (prop_id)
1227
    {
1228
    case PROP_LABEL:
1229
      g_value_set_string (value, priv->label);
1230 1231
      break;
    case PROP_ATTRIBUTES:
1232
      g_value_set_boxed (value, priv->attrs);
1233 1234
      break;
    case PROP_USE_MARKUP:
1235
      g_value_set_boolean (value, priv->use_markup);
1236 1237
      break;
    case PROP_USE_UNDERLINE:
1238
      g_value_set_boolean (value, priv->use_underline);
1239
      break;
1240
    case PROP_JUSTIFY:
1241
      g_value_set_enum (value, priv->jtype);
1242
      break;
1243
    case PROP_WRAP:
1244
      g_value_set_boolean (value, priv->wrap);
1245
      break;
1246
    case PROP_WRAP_MODE:
1247
      g_value_set_enum (value, priv->wrap_mode);
1248
      break;
1249 1250 1251
    case PROP_SELECTABLE:
      g_value_set_boolean (value, gtk_label_get_selectable (label));
      break;
1252
    case PROP_MNEMONIC_KEYVAL:
1253
      g_value_set_uint (value, priv->mnemonic_keyval);
1254
      break;
1255
    case PROP_MNEMONIC_WIDGET:
1256
      g_value_set_object (value, (GObject*) priv->mnemonic_widget);
1257
      break;
1258
    case PROP_CURSOR_POSITION:
1259
      g_value_set_int (value, _gtk_la