diff options
author | Søren Sandmann Pedersen <ssp@redhat.com> | 2011-01-23 14:10:23 -0500 |
---|---|---|
committer | Søren Sandmann Pedersen <ssp@redhat.com> | 2011-01-23 14:10:23 -0500 |
commit | 6a27897a9b966c5c28f593cc4ad47a19e8f98752 (patch) | |
tree | 0562288713f2d8d3cf9679d8097297b0fa35a8c8 |
-rw-r--r-- | channel-buffer.c | 132 | ||||
-rw-r--r-- | channel-buffer.h | 32 | ||||
-rw-r--r-- | chatterbox.glade | 2297 | ||||
-rw-r--r-- | irc.c | 931 | ||||
-rw-r--r-- | irc.h | 70 | ||||
-rw-r--r-- | main.c | 41 |
6 files changed, 3503 insertions, 0 deletions
diff --git a/channel-buffer.c b/channel-buffer.c new file mode 100644 index 0000000..5390439 --- /dev/null +++ b/channel-buffer.c @@ -0,0 +1,132 @@ +/* + * This data structure purpose in life is to maintain a GtkTextBuffer + * with these properies: + * + * - The channel is not editable: + * + * - There is an area after channel area where the user can enter new + * messages + * + * - You can add messages, and they will be displayed in gray in the + * channel area. + * + * - You can /commit/ messages which means they will turn black + * + * - Messages will be added to the channel area in the order they + * are committed + * + * - The user displays as either + * + * - The users nickname, followed by a colon, followed by a space, + * followed by the text that the user has entered in a normal + * typeface + * + * or + * + * - The users nickname in italic, followed by a apsce, followed + * by the text the user has entered, in italics + * + * The first style is used for nomal messages, the second for + * 'third person messages', ie. 'ssp thinks blah blah .... ' + * as opposed to 'ssp: blaah blah blah' + * + * The channel buffer also maintains a topic + * + */ +#include "channel-buffer.h" + +struct ChannelBuffer +{ + const char *user_nick; + + GtkTextBuffer *text_buffer; + GtkTextTag *nick_tag; + + GtkTextMark *mid_point; + GtkTextMark *nick_end; +}; + +static void +set_mid_point_gravity (ChannelBuffer *buffer, + gboolean left_gravity) +{ + GtkTextIter iter; + + if (gtk_text_mark_get_left_gravity (buffer->mid_point) == left_gravity) + return; + + gtk_text_buffer_get_iter_at_mark (buffer->text_buffer, &iter, + buffer->mid_point); + gtk_text_buffer_delete_mark (buffer->text_buffer, buffer->midpoint); + buffer->mid_point = gtk_text_buffer_create_mark ( + buffer->text_buffer, "mid_point", &iter, lelft_gravity); +} + +static void +channel_buffer_change_nick_text (ChannelBuffer *buffer, + const char *text, + gboolean italic) +{ + + gtk_text_buffer_insert (buffer->text_buffer, &iter, + buffer->user_nick, -1); +} + +ChannelBuffer * +channel_buffer_new (const char *user_nick) +{ + ChannelBuffer *buffer = g_new (ChannelBuffer, 1); + GtkTextIter iter; + + g_return_val_if_fail (g_utf8_validate (user_nick, -1, NULL), NULL); + + buffer->user_nick = g_strdup (user_nick); + + /* TextBuffer stuff */ + buffer->text_buffer = gtk_text_buffer_new (NULL); + buffer->nick_tag = + gtk_text_buffer_create_tag (buffer->text_buffer, "nick", + "weight", PANGO_WEIGHT_BOLD, + NULL); + + gtk_text_buffer_get_start_iter (buffer->text_buffer, &iter); + + buffer->mid_point = gtk_text_buffer_create_mark ( + buffer->text_buffer, "nick_begin", &iter, FALSE); + + buffer->nick_end = gtk_text_buffer_create_mark ( + buffer->text_buffer, "nick_end", &iter, TRUE); + + gtk_text_buffer_get_start_iter (buffer->text_buffer, &iter); + + buffer->channel_area_begin = gtk_text_buffer_create_mark ( + buffer->text_buffer, "channel_area_begin", &iter, TRUE); + + buffer->channel_area_end = gtk_text_buffer_create_mark ( + buffer->text_buffer, "channel_area_end", &iter, FALSE); + + return buffer; +} + +void channel_buffer_free (ChannelBuffer *buffer); +ChannelMessage *channel_buffer_add_message (ChannelBuffer *buffer, + const char *nick, + const char *message); +void channel_buffer_commit_message (ChannelMessage *message); +void channel_buffer_set_user_nick (ChannelBuffer *buffer, + const char *nick); +const char * channel_buffer_get_user_text (ChannelBuffer *buffer); +void channel_buffer_set_action_mode (ChannelBuffer *buffer, + gboolean action_mode); +gboolean channel_buffer_get_action_mode (ChannelBuffer *buffer); +#if 0 +void channel_buffer_set_topic (ChannelBuffer *buffer, + const char *topic); +const char * channel_buffer_get_topic (ChannelBuffer *buffer); +#endif + +GtkTextBuffer * +channel_buffer_get_text_buffer (ChannelBuffer *buffer) +{ + return buffer->text_buffer; +} diff --git a/channel-buffer.h b/channel-buffer.h new file mode 100644 index 0000000..416c761 --- /dev/null +++ b/channel-buffer.h @@ -0,0 +1,32 @@ +#include <gtk/gtk.h> + +typedef struct ChannelBuffer ChannelBuffer; +typedef struct ChannelMessage ChannelMessage; + +typedef union +{ + +} ChannelBufferEvent; + +typedef void (* ChannelBufferEventFunc) (ChannelBuffer *buffer, + const ChannelBufferEvent *event); + +ChannelBuffer *channel_buffer_new (); +void channel_buffer_free (ChannelBuffer *buffer); +ChannelMessage *channel_buffer_add_message (ChannelBuffer *buffer, + const char *nick, + const char *message); +void channel_buffer_commit_message (ChannelMessage *message); +void channel_buffer_set_user_nick (ChannelBuffer *buffer, + const char *nick); +const char * channel_buffer_get_user_text (ChannelBuffer *buffer); +void channel_buffer_set_action_mode (ChannelBuffer *buffer, + gboolean action_mode); +gboolean channel_buffer_get_action_mode (ChannelBuffer *buffer); +#if 0 +void channel_buffer_set_topic (ChannelBuffer *buffer, + const char *topic); +const char * channel_buffer_get_topic (ChannelBuffer *buffer); +#endif + +GtkTextBuffer *channel_buffer_get_text_buffer (ChannelBuffer *buffer); diff --git a/chatterbox.glade b/chatterbox.glade new file mode 100644 index 0000000..d487cf8 --- /dev/null +++ b/chatterbox.glade @@ -0,0 +1,2297 @@ +<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*--> +<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd"> + +<glade-interface> +<requires lib="gnome"/> + +<widget class="GtkWindow" id="startup-window"> + <property name="border_width">12</property> + <property name="visible">True</property> + <property name="title" translatable="yes">Connecting</property> + <property name="type">GTK_WINDOW_TOPLEVEL</property> + <property name="window_position">GTK_WIN_POS_NONE</property> + <property name="modal">False</property> + <property name="resizable">True</property> + <property name="destroy_with_parent">False</property> + <property name="decorated">True</property> + <property name="skip_taskbar_hint">False</property> + <property name="skip_pager_hint">False</property> + <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property> + <property name="gravity">GDK_GRAVITY_NORTH_WEST</property> + + <child> + <widget class="GtkVBox" id="vbox3"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">18</property> + + <child> + <widget class="GtkVBox" id="vbox4"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">12</property> + + <child> + <widget class="GtkHBox" id="hbox1"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">12</property> + + <child> + <widget class="GtkHBox" id="hbox2"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">6</property> + + <child> + <widget class="GtkLabel" id="label1"> + <property name="visible">True</property> + <property name="label" translatable="yes"><b>_Server:</b></property> + <property name="use_underline">True</property> + <property name="use_markup">True</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + <property name="mnemonic_widget">combo-entry1</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkCombo" id="combo1"> + <property name="visible">True</property> + <property name="value_in_list">False</property> + <property name="allow_empty">True</property> + <property name="case_sensitive">False</property> + <property name="enable_arrow_keys">True</property> + <property name="enable_arrows_always">False</property> + + <child internal-child="entry"> + <widget class="GtkEntry" id="combo-entry1"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="editable">True</property> + <property name="visibility">True</property> + <property name="max_length">0</property> + <property name="text" translatable="yes">irc.gimp.org</property> + <property name="has_frame">True</property> + <property name="invisible_char" translatable="yes">*</property> + <property name="activates_default">False</property> + </widget> + </child> + + <child internal-child="list"> + <widget class="GtkList" id="combo-list1"> + <property name="visible">True</property> + <property name="selection_mode">GTK_SELECTION_BROWSE</property> + </widget> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + + <child> + <widget class="GtkHBox" id="hbox3"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">6</property> + + <child> + <widget class="GtkLabel" id="label3"> + <property name="visible">True</property> + <property name="label" translatable="yes"><b>_Port:</b></property> + <property name="use_underline">True</property> + <property name="use_markup">True</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + <property name="mnemonic_widget">entry2</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkEntry" id="entry2"> + <property name="width_request">91</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="editable">True</property> + <property name="visibility">True</property> + <property name="max_length">0</property> + <property name="text" translatable="yes">6667</property> + <property name="has_frame">True</property> + <property name="invisible_char" translatable="yes">*</property> + <property name="activates_default">False</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkVBox" id="vbox1"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">6</property> + + <child> + <widget class="GtkLabel" id="label2"> + <property name="visible">True</property> + <property name="label" translatable="yes"><b>_Channels</b></property> + <property name="use_underline">True</property> + <property name="use_markup">True</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkScrolledWindow" id="scrolledwindow2"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="hscrollbar_policy">GTK_POLICY_ALWAYS</property> + <property name="vscrollbar_policy">GTK_POLICY_ALWAYS</property> + <property name="shadow_type">GTK_SHADOW_IN</property> + <property name="window_placement">GTK_CORNER_TOP_LEFT</property> + + <child> + <widget class="GtkTreeView" id="treeview2"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="headers_visible">True</property> + <property name="rules_hint">False</property> + <property name="reorderable">False</property> + <property name="enable_search">True</property> + </widget> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + + <child> + <widget class="GtkHButtonBox" id="hbuttonbox1"> + <property name="visible">True</property> + <property name="layout_style">GTK_BUTTONBOX_END</property> + <property name="spacing">0</property> + + <child> + <widget class="GtkButton" id="button1"> + <property name="visible">True</property> + <property name="can_default">True</property> + <property name="has_default">True</property> + <property name="can_focus">True</property> + <property name="label" translatable="yes">_Connect</property> + <property name="use_underline">True</property> + <property name="relief">GTK_RELIEF_NORMAL</property> + <property name="focus_on_click">True</property> + </widget> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + </widget> + </child> +</widget> + +<widget class="GtkWindow" id="main-window"> + <property name="visible">True</property> + <property name="title" translatable="yes">irc.gimp.org</property> + <property name="type">GTK_WINDOW_TOPLEVEL</property> + <property name="window_position">GTK_WIN_POS_NONE</property> + <property name="modal">False</property> + <property name="resizable">True</property> + <property name="destroy_with_parent">False</property> + <property name="decorated">True</property> + <property name="skip_taskbar_hint">False</property> + <property name="skip_pager_hint">False</property> + <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property> + <property name="gravity">GDK_GRAVITY_NORTH_WEST</property> + + <child> + <widget class="GtkVBox" id="vbox5"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">0</property> + + <child> + <widget class="GtkMenuBar" id="menubar1"> + <property name="visible">True</property> + + <child> + <widget class="GtkMenuItem" id="menuitem1"> + <property name="visible">True</property> + <property name="label" translatable="yes">_Chat</property> + <property name="use_underline">True</property> + + <child> + <widget class="GtkMenu" id="menuitem1_menu"> + + <child> + <widget class="GtkImageMenuItem" id="join_channel1"> + <property name="visible">True</property> + <property name="label" translatable="yes">_Join Channel...</property> + <property name="use_underline">True</property> + <signal name="activate" handler="on_join_channel1_activate" last_modification_time="Tue, 03 Sep 2002 19:14:39 GMT"/> + <accelerator key="J" modifiers="GDK_CONTROL_MASK" signal="activate"/> + + <child internal-child="image"> + <widget class="GtkImage" id="image28"> + <property name="visible">True</property> + <property name="stock">gtk-new</property> + <property name="icon_size">1</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + </child> + </widget> + </child> + + <child> + <widget class="GtkImageMenuItem" id="leave_channel1"> + <property name="visible">True</property> + <property name="label" translatable="yes">_Leave Channel...</property> + <property name="use_underline">True</property> + <signal name="activate" handler="on_leave_channel1_activate" last_modification_time="Mon, 11 Nov 2002 23:51:32 GMT"/> + <accelerator key="w" modifiers="GDK_CONTROL_MASK" signal="activate"/> + + <child internal-child="image"> + <widget class="GtkImage" id="image29"> + <property name="visible">True</property> + <property name="stock">gtk-close</property> + <property name="icon_size">1</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + </child> + </widget> + </child> + + <child> + <widget class="GtkMenuItem" id="separator4"> + <property name="visible">True</property> + </widget> + </child> + + <child> + <widget class="GtkMenuItem" id="servers1"> + <property name="visible">True</property> + <property name="label" translatable="yes">_Servers...</property> + <property name="use_underline">True</property> + <signal name="activate" handler="on_servers1_activate" last_modification_time="Tue, 03 Sep 2002 19:14:39 GMT"/> + </widget> + </child> + + <child> + <widget class="GtkMenuItem" id="separator3"> + <property name="visible">True</property> + </widget> + </child> + + <child> + <widget class="GtkImageMenuItem" id="save1"> + <property name="visible">True</property> + <property name="label" translatable="yes">gtk-quit</property> + <property name="use_underline">True</property> + <signal name="activate" handler="on_save1_activate" last_modification_time="Tue, 03 Sep 2002 19:14:39 GMT"/> + </widget> + </child> + </widget> + </child> + </widget> + </child> + + <child> + <widget class="GtkMenuItem" id="menuitem2"> + <property name="visible">True</property> + <property name="label" translatable="yes">_Edit</property> + <property name="use_underline">True</property> + + <child> + <widget class="GtkMenu" id="menuitem2_menu"> + + <child> + <widget class="GtkImageMenuItem" id="cut1"> + <property name="visible">True</property> + <property name="label" translatable="yes">gtk-cut</property> + <property name="use_underline">True</property> + <signal name="activate" handler="on_cut1_activate" last_modification_time="Tue, 03 Sep 2002 19:14:39 GMT"/> + </widget> + </child> + + <child> + <widget class="GtkImageMenuItem" id="copy1"> + <property name="visible">True</property> + <property name="label" translatable="yes">gtk-copy</property> + <property name="use_underline">True</property> + <signal name="activate" handler="on_copy1_activate" last_modification_time="Tue, 03 Sep 2002 19:14:39 GMT"/> + </widget> + </child> + + <child> + <widget class="GtkImageMenuItem" id="paste1"> + <property name="visible">True</property> + <property name="label" translatable="yes">gtk-paste</property> + <property name="use_underline">True</property> + <signal name="activate" handler="on_paste1_activate" last_modification_time="Tue, 03 Sep 2002 19:14:39 GMT"/> + </widget> + </child> + + <child> + <widget class="GtkImageMenuItem" id="delete1"> + <property name="visible">True</property> + <property name="label" translatable="yes">gtk-clear</property> + <property name="use_underline">True</property> + <signal name="activate" handler="on_delete1_activate" last_modification_time="Tue, 03 Sep 2002 19:14:39 GMT"/> + </widget> + </child> + + <child> + <widget class="GtkMenuItem" id="separator1"> + <property name="visible">True</property> + </widget> + </child> + + <child> + <widget class="GtkImageMenuItem" id="find_1"> + <property name="visible">True</property> + <property name="label" translatable="yes">Find ...</property> + <property name="use_underline">True</property> + <signal name="activate" handler="on_find_1_activate" last_modification_time="Mon, 11 Nov 2002 23:46:21 GMT"/> + <accelerator key="F" modifiers="GDK_CONTROL_MASK" signal="activate"/> + + <child internal-child="image"> + <widget class="GtkImage" id="image30"> + <property name="visible">True</property> + <property name="stock">gtk-find</property> + <property name="icon_size">1</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + </child> + </widget> + </child> + + <child> + <widget class="GtkImageMenuItem" id="find_next1"> + <property name="visible">True</property> + <property name="label" translatable="yes">Find Ne_xt</property> + <property name="use_underline">True</property> + <signal name="activate" handler="on_find_next1_activate" last_modification_time="Mon, 11 Nov 2002 23:46:21 GMT"/> + <accelerator key="G" modifiers="GDK_CONTROL_MASK" signal="activate"/> + + <child internal-child="image"> + <widget class="GtkImage" id="image31"> + <property name="visible">True</property> + <property name="stock">gtk-find</property> + <property name="icon_size">1</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + </child> + </widget> + </child> + + <child> + <widget class="GtkMenuItem" id="separator2"> + <property name="visible">True</property> + </widget> + </child> + + <child> + <widget class="GtkImageMenuItem" id="preferences1"> + <property name="visible">True</property> + <property name="label" translatable="yes">gtk-preferences</property> + <property name="use_underline">True</property> + <signal name="activate" handler="on_preferences1_activate" last_modification_time="Mon, 11 Nov 2002 23:47:06 GMT"/> + </widget> + </child> + </widget> + </child> + </widget> + </child> + + <child> + <widget class="GtkMenuItem" id="menuitem3"> + <property name="visible">True</property> + <property name="label" translatable="yes">_Action</property> + <property name="use_underline">True</property> + + <child> + <widget class="GtkMenu" id="menuitem3_menu"> + + <child> + <widget class="GtkMenuItem" id="talk_in_the_third_person1"> + <property name="visible">True</property> + <property name="label" translatable="yes">Talk in the Third Person...</property> + <property name="use_underline">True</property> + <signal name="activate" handler="on_talk_in_the_third_person1_activate" last_modification_time="Mon, 11 Nov 2002 23:55:47 GMT"/> + <accelerator key="m" modifiers="GDK_CONTROL_MASK" signal="activate"/> + </widget> + </child> + + <child> + <widget class="GtkMenuItem" id="change_nickname1"> + <property name="visible">True</property> + <property name="label" translatable="yes">Change _Nickname...</property> + <property name="use_underline">True</property> + <signal name="activate" handler="on_change_nickname1_activate" last_modification_time="Mon, 11 Nov 2002 23:55:47 GMT"/> + <accelerator key="n" modifiers="GDK_CONTROL_MASK" signal="activate"/> + </widget> + </child> + + <child> + <widget class="GtkMenuItem" id="separator5"> + <property name="visible">True</property> + </widget> + </child> + + <child> + <widget class="GtkCheckMenuItem" id="marked_away1"> + <property name="visible">True</property> + <property name="label" translatable="yes">Marked A_way</property> + <property name="use_underline">True</property> + <property name="active">False</property> + <signal name="activate" handler="on_marked_away1_activate" last_modification_time="Mon, 11 Nov 2002 23:55:47 GMT"/> + </widget> + </child> + </widget> + </child> + </widget> + </child> + + <child> + <widget class="GtkMenuItem" id="menuitem4"> + <property name="visible">True</property> + <property name="label" translatable="yes">_Help</property> + <property name="use_underline">True</property> + + <child> + <widget class="GtkMenu" id="menuitem4_menu"> + + <child> + <widget class="GtkImageMenuItem" id="about1"> + <property name="visible">True</property> + <property name="label" translatable="yes">gnome-stock-about</property> + <property name="use_underline">True</property> + <signal name="activate" handler="on_about1_activate" last_modification_time="Tue, 03 Sep 2002 19:14:39 GMT"/> + </widget> + </child> + </widget> + </child> + </widget> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkNotebook" id="notebook1"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="show_tabs">True</property> + <property name="show_border">True</property> + <property name="tab_pos">GTK_POS_TOP</property> + <property name="scrollable">False</property> + <property name="enable_popup">False</property> + + <child> + <widget class="GtkVBox" id="vbox6"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">0</property> + + <child> + <widget class="GtkHPaned" id="hpaned1"> + <property name="border_width">6</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="position">0</property> + + <child> + <widget class="GtkVBox" id="vbox7"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">6</property> + + <child> + <widget class="GtkHBox" id="hbox8"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">6</property> + + <child> + <widget class="GtkLabel" id="label11"> + <property name="visible">True</property> + <property name="label" translatable="yes">Topic:</property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkScrolledWindow" id="scrolledwindow9"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="hscrollbar_policy">GTK_POLICY_NEVER</property> + <property name="vscrollbar_policy">GTK_POLICY_NEVER</property> + <property name="shadow_type">GTK_SHADOW_IN</property> + <property name="window_placement">GTK_CORNER_TOP_LEFT</property> + + <child> + <widget class="GtkTextView" id="textview3"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="editable">False</property> + <property name="overwrite">False</property> + <property name="accepts_tab">True</property> + <property name="justification">GTK_JUSTIFY_LEFT</property> + <property name="wrap_mode">GTK_WRAP_NONE</property> + <property name="cursor_visible">False</property> + <property name="pixels_above_lines">0</property> + <property name="pixels_below_lines">0</property> + <property name="pixels_inside_wrap">0</property> + <property name="left_margin">0</property> + <property name="right_margin">0</property> + <property name="indent">0</property> + <property name="text" translatable="yes"></property> + </widget> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + + <child> + <widget class="GtkButton" id="button4"> + <property name="visible">True</property> + <property name="sensitive">False</property> + <property name="can_focus">True</property> + <property name="label" translatable="yes">_Change Topic...</property> + <property name="use_underline">True</property> + <property name="relief">GTK_RELIEF_NORMAL</property> + <property name="focus_on_click">True</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">True</property> + </packing> + </child> + + <child> + <widget class="GtkScrolledWindow" id="scrolledwindow3"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="hscrollbar_policy">GTK_POLICY_NEVER</property> + <property name="vscrollbar_policy">GTK_POLICY_ALWAYS</property> + <property name="shadow_type">GTK_SHADOW_IN</property> + <property name="window_placement">GTK_CORNER_TOP_LEFT</property> + + <child> + <widget class="GtkTextView" id="textview5"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="editable">False</property> + <property name="overwrite">False</property> + <property name="accepts_tab">True</property> + <property name="justification">GTK_JUSTIFY_LEFT</property> + <property name="wrap_mode">GTK_WRAP_NONE</property> + <property name="cursor_visible">False</property> + <property name="pixels_above_lines">0</property> + <property name="pixels_below_lines">0</property> + <property name="pixels_inside_wrap">0</property> + <property name="left_margin">0</property> + <property name="right_margin">0</property> + <property name="indent">0</property> + <property name="text" translatable="yes"></property> + </widget> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + <packing> + <property name="shrink">True</property> + <property name="resize">False</property> + </packing> + </child> + + <child> + <widget class="GtkVBox" id="vbox10"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">0</property> + + <child> + <widget class="GtkVBox" id="vbox14"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">4</property> + + <child> + <widget class="GtkScrolledWindow" id="scrolledwindow3"> + <property name="height_request">0</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="hscrollbar_policy">GTK_POLICY_NEVER</property> + <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property> + <property name="shadow_type">GTK_SHADOW_IN</property> + <property name="window_placement">GTK_CORNER_TOP_LEFT</property> + + <child> + <widget class="GtkTreeView" id="treeview3"> + <property name="border_width">6</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="headers_visible">True</property> + <property name="rules_hint">False</property> + <property name="reorderable">False</property> + <property name="enable_search">True</property> + </widget> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + <packing> + <property name="shrink">True</property> + <property name="resize">True</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + <packing> + <property name="tab_expand">False</property> + <property name="tab_fill">True</property> + </packing> + </child> + + <child> + <widget class="GtkHBox" id="hbox15"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">0</property> + + <child> + <widget class="GtkImage" id="image37"> + <property name="visible">True</property> + <property name="stock">gnome-stock-about</property> + <property name="icon_size">1</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkLabel" id="label4"> + <property name="visible">True</property> + <property name="label" translatable="yes"><b><span color="#004784">#gtk</span></b></property> + <property name="use_underline">False</property> + <property name="use_markup">True</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0</property> + <property name="yalign">0.5</property> + <property name="xpad">6</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + <packing> + <property name="type">tab</property> + </packing> + </child> + + <child> + <widget class="GtkHPaned" id="hpaned2"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="position">0</property> + + <child> + <widget class="GtkVBox" id="vbox8"> + <property name="border_width">6</property> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">6</property> + + <child> + <widget class="GtkScrolledWindow" id="scrolledwindow4"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="hscrollbar_policy">GTK_POLICY_NEVER</property> + <property name="vscrollbar_policy">GTK_POLICY_ALWAYS</property> + <property name="shadow_type">GTK_SHADOW_IN</property> + <property name="window_placement">GTK_CORNER_TOP_LEFT</property> + + <child> + <widget class="GtkTextView" id="textview2"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="editable">True</property> + <property name="overwrite">False</property> + <property name="accepts_tab">True</property> + <property name="justification">GTK_JUSTIFY_LEFT</property> + <property name="wrap_mode">GTK_WRAP_NONE</property> + <property name="cursor_visible">True</property> + <property name="pixels_above_lines">0</property> + <property name="pixels_below_lines">0</property> + <property name="pixels_inside_wrap">0</property> + <property name="left_margin">0</property> + <property name="right_margin">0</property> + <property name="indent">0</property> + <property name="text" translatable="yes"></property> + </widget> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + + <child> + <widget class="GtkHBox" id="hbox6"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">6</property> + + <child> + <widget class="GtkLabel" id="label10"> + <property name="visible">True</property> + <property name="label" translatable="yes"><b>sandmann:</b></property> + <property name="use_underline">False</property> + <property name="use_markup">True</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkEntry" id="entry4"> + <property name="height_request">30</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="editable">True</property> + <property name="visibility">True</property> + <property name="max_length">0</property> + <property name="text" translatable="yes"></property> + <property name="has_frame">True</property> + <property name="invisible_char" translatable="yes">*</property> + <property name="activates_default">False</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + + <child> + <widget class="GtkButton" id="button3"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="label">gtk-ok</property> + <property name="use_stock">True</property> + <property name="relief">GTK_RELIEF_NORMAL</property> + <property name="focus_on_click">True</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + </widget> + <packing> + <property name="shrink">True</property> + <property name="resize">False</property> + </packing> + </child> + + <child> + <widget class="GtkHBox" id="hbox7"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">12</property> + + <child> + <widget class="GtkScrolledWindow" id="scrolledwindow5"> + <property name="border_width">6</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="hscrollbar_policy">GTK_POLICY_NEVER</property> + <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property> + <property name="shadow_type">GTK_SHADOW_IN</property> + <property name="window_placement">GTK_CORNER_TOP_LEFT</property> + + <child> + <widget class="GtkTreeView" id="treeview4"> + <property name="border_width">6</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="headers_visible">True</property> + <property name="rules_hint">False</property> + <property name="reorderable">False</property> + <property name="enable_search">True</property> + </widget> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + <packing> + <property name="shrink">True</property> + <property name="resize">True</property> + </packing> + </child> + </widget> + <packing> + <property name="tab_expand">False</property> + <property name="tab_fill">True</property> + </packing> + </child> + + <child> + <widget class="GtkHBox" id="hbox16"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">0</property> + + <child> + <widget class="GtkLabel" id="label21"> + <property name="width_request">16</property> + <property name="height_request">16</property> + <property name="visible">True</property> + <property name="label" translatable="yes"></property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkLabel" id="label5"> + <property name="visible">True</property> + <property name="label" translatable="yes">#gnome</property> + <property name="use_underline">False</property> + <property name="use_markup">True</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0</property> + <property name="yalign">0.5</property> + <property name="xpad">6</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + <packing> + <property name="type">tab</property> + </packing> + </child> + + <child> + <placeholder/> + </child> + + <child> + <widget class="GtkHBox" id="hbox17"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">0</property> + + <child> + <widget class="GtkLabel" id="label22"> + <property name="width_request">16</property> + <property name="height_request">16</property> + <property name="visible">True</property> + <property name="label" translatable="yes"><b>|</b></property> + <property name="use_underline">False</property> + <property name="use_markup">True</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkLabel" id="label6"> + <property name="visible">True</property> + <property name="label" translatable="yes"><b>#usability</b></property> + <property name="use_underline">False</property> + <property name="use_markup">True</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0</property> + <property name="yalign">0.5</property> + <property name="xpad">6</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + <packing> + <property name="type">tab</property> + </packing> + </child> + + <child> + <placeholder/> + </child> + + <child> + <widget class="GtkHBox" id="hbox18"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">0</property> + + <child> + <widget class="GtkLabel" id="label23"> + <property name="width_request">16</property> + <property name="height_request">16</property> + <property name="visible">True</property> + <property name="label" translatable="yes"></property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkLabel" id="label7"> + <property name="visible">True</property> + <property name="label" translatable="yes">#danmark</property> + <property name="use_underline">False</property> + <property name="use_markup">True</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0</property> + <property name="yalign">0.5</property> + <property name="xpad">6</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + <packing> + <property name="type">tab</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + </child> +</widget> + +<widget class="GtkDialog" id="start-up-window-3"> + <property name="visible">True</property> + <property name="title" translatable="yes">Connecting</property> + <property name="type">GTK_WINDOW_TOPLEVEL</property> + <property name="window_position">GTK_WIN_POS_NONE</property> + <property name="modal">False</property> + <property name="resizable">True</property> + <property name="destroy_with_parent">False</property> + <property name="decorated">True</property> + <property name="skip_taskbar_hint">False</property> + <property name="skip_pager_hint">False</property> + <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property> + <property name="gravity">GDK_GRAVITY_NORTH_WEST</property> + <property name="has_separator">False</property> + + <child internal-child="vbox"> + <widget class="GtkVBox" id="dialog-vbox2"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">0</property> + + <child internal-child="action_area"> + <widget class="GtkHButtonBox" id="dialog-action_area2"> + <property name="visible">True</property> + <property name="layout_style">GTK_BUTTONBOX_END</property> + + <child> + <widget class="GtkButton" id="button6"> + <property name="visible">True</property> + <property name="can_default">True</property> + <property name="has_default">True</property> + <property name="can_focus">True</property> + <property name="label" translatable="yes">_Connect</property> + <property name="use_underline">True</property> + <property name="relief">GTK_RELIEF_NORMAL</property> + <property name="focus_on_click">True</property> + <property name="response_id">0</property> + </widget> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="pack_type">GTK_PACK_END</property> + </packing> + </child> + + <child> + <widget class="GtkVBox" id="vbox13"> + <property name="border_width">6</property> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">12</property> + + <child> + <widget class="GtkVBox" id="vbox22"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">3</property> + + <child> + <widget class="GtkLabel" id="label14"> + <property name="visible">True</property> + <property name="label" translatable="yes"><b>_Servers</b></property> + <property name="use_underline">True</property> + <property name="use_markup">True</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkHBox" id="hbox10"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">12</property> + + <child> + <widget class="GtkScrolledWindow" id="scrolledwindow8"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property> + <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property> + <property name="shadow_type">GTK_SHADOW_IN</property> + <property name="window_placement">GTK_CORNER_TOP_LEFT</property> + + <child> + <widget class="GtkTreeView" id="treeview7"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="headers_visible">False</property> + <property name="rules_hint">False</property> + <property name="reorderable">False</property> + <property name="enable_search">True</property> + </widget> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + + <child> + <widget class="GtkVButtonBox" id="vbuttonbox1"> + <property name="visible">True</property> + <property name="layout_style">GTK_BUTTONBOX_START</property> + <property name="spacing">0</property> + + <child> + <widget class="GtkButton" id="button8"> + <property name="visible">True</property> + <property name="can_default">True</property> + <property name="can_focus">True</property> + <property name="relief">GTK_RELIEF_NORMAL</property> + <property name="focus_on_click">True</property> + + <child> + <widget class="GtkAlignment" id="alignment4"> + <property name="visible">True</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xscale">0</property> + <property name="yscale">0</property> + <property name="top_padding">0</property> + <property name="bottom_padding">0</property> + <property name="left_padding">0</property> + <property name="right_padding">0</property> + + <child> + <widget class="GtkHBox" id="hbox13"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">2</property> + + <child> + <widget class="GtkImage" id="image35"> + <property name="visible">True</property> + <property name="stock">gtk-new</property> + <property name="icon_size">4</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkLabel" id="label18"> + <property name="visible">True</property> + <property name="label" translatable="yes">_New Server...</property> + <property name="use_underline">True</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + </widget> + </child> + </widget> + </child> + </widget> + </child> + + <child> + <widget class="GtkButton" id="button9"> + <property name="visible">True</property> + <property name="can_default">True</property> + <property name="can_focus">True</property> + <property name="relief">GTK_RELIEF_NORMAL</property> + <property name="focus_on_click">True</property> + + <child> + <widget class="GtkAlignment" id="alignment5"> + <property name="visible">True</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xscale">0</property> + <property name="yscale">0</property> + <property name="top_padding">0</property> + <property name="bottom_padding">0</property> + <property name="left_padding">0</property> + <property name="right_padding">0</property> + + <child> + <widget class="GtkHBox" id="hbox14"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">3</property> + + <child> + <widget class="GtkImage" id="image36"> + <property name="visible">True</property> + <property name="stock">gtk-properties</property> + <property name="icon_size">4</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkLabel" id="label19"> + <property name="visible">True</property> + <property name="label" translatable="yes">_Properties...</property> + <property name="use_underline">True</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + </widget> + </child> + </widget> + </child> + </widget> + </child> + + <child> + <widget class="GtkButton" id="button10"> + <property name="visible">True</property> + <property name="can_default">True</property> + <property name="can_focus">True</property> + <property name="label">gtk-delete</property> + <property name="use_stock">True</property> + <property name="relief">GTK_RELIEF_NORMAL</property> + <property name="focus_on_click">True</property> + </widget> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">True</property> + </packing> + </child> + + <child> + <widget class="GtkVBox" id="vbox21"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">3</property> + + <child> + <widget class="GtkLabel" id="label34"> + <property name="visible">True</property> + <property name="label" translatable="yes"><b>_Channels</b></property> + <property name="use_underline">True</property> + <property name="use_markup">True</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkScrolledWindow" id="scrolledwindow17"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property> + <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property> + <property name="shadow_type">GTK_SHADOW_IN</property> + <property name="window_placement">GTK_CORNER_TOP_LEFT</property> + + <child> + <widget class="GtkTreeView" id="treeview10"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="headers_visible">False</property> + <property name="rules_hint">False</property> + <property name="reorderable">False</property> + <property name="enable_search">True</property> + </widget> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + </child> +</widget> + +<widget class="GtkWindow" id="window1"> + <property name="visible">True</property> + <property name="title" translatable="yes">irc.gimp.org</property> + <property name="type">GTK_WINDOW_TOPLEVEL</property> + <property name="window_position">GTK_WIN_POS_NONE</property> + <property name="modal">False</property> + <property name="resizable">True</property> + <property name="destroy_with_parent">False</property> + <property name="decorated">True</property> + <property name="skip_taskbar_hint">False</property> + <property name="skip_pager_hint">False</property> + <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property> + <property name="gravity">GDK_GRAVITY_NORTH_WEST</property> + + <child> + <widget class="GtkVBox" id="vbox15"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">0</property> + + <child> + <widget class="GtkMenuBar" id="menubar2"> + <property name="visible">True</property> + + <child> + <widget class="GtkMenuItem" id="menuitem5"> + <property name="visible">True</property> + <property name="label" translatable="yes">_Chat</property> + <property name="use_underline">True</property> + + <child> + <widget class="GtkMenu" id="menu1"> + + <child> + <widget class="GtkImageMenuItem" id="imagemenuitem1"> + <property name="visible">True</property> + <property name="label" translatable="yes">_Join Channel...</property> + <property name="use_underline">True</property> + <signal name="activate" handler="on_join_channel1_activate" last_modification_time="Tue, 03 Sep 2002 19:14:39 GMT"/> + <accelerator key="J" modifiers="GDK_CONTROL_MASK" signal="activate"/> + + <child internal-child="image"> + <widget class="GtkImage" id="image38"> + <property name="visible">True</property> + <property name="stock">gtk-new</property> + <property name="icon_size">1</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + </child> + </widget> + </child> + + <child> + <widget class="GtkImageMenuItem" id="imagemenuitem2"> + <property name="visible">True</property> + <property name="label" translatable="yes">_Leave Channel...</property> + <property name="use_underline">True</property> + <signal name="activate" handler="on_leave_channel1_activate" last_modification_time="Mon, 11 Nov 2002 23:51:32 GMT"/> + <accelerator key="w" modifiers="GDK_CONTROL_MASK" signal="activate"/> + + <child internal-child="image"> + <widget class="GtkImage" id="image39"> + <property name="visible">True</property> + <property name="stock">gtk-close</property> + <property name="icon_size">1</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + </child> + </widget> + </child> + + <child> + <widget class="GtkMenuItem" id="menuitem6"> + <property name="visible">True</property> + </widget> + </child> + + <child> + <widget class="GtkMenuItem" id="menuitem7"> + <property name="visible">True</property> + <property name="label" translatable="yes">_Servers...</property> + <property name="use_underline">True</property> + <signal name="activate" handler="on_servers1_activate" last_modification_time="Tue, 03 Sep 2002 19:14:39 GMT"/> + </widget> + </child> + + <child> + <widget class="GtkMenuItem" id="menuitem8"> + <property name="visible">True</property> + </widget> + </child> + + <child> + <widget class="GtkImageMenuItem" id="imagemenuitem3"> + <property name="visible">True</property> + <property name="label" translatable="yes">gtk-quit</property> + <property name="use_underline">True</property> + <signal name="activate" handler="on_save1_activate" last_modification_time="Tue, 03 Sep 2002 19:14:39 GMT"/> + </widget> + </child> + </widget> + </child> + </widget> + </child> + + <child> + <widget class="GtkMenuItem" id="menuitem9"> + <property name="visible">True</property> + <property name="label" translatable="yes">_Edit</property> + <property name="use_underline">True</property> + + <child> + <widget class="GtkMenu" id="menu2"> + + <child> + <widget class="GtkImageMenuItem" id="imagemenuitem4"> + <property name="visible">True</property> + <property name="label" translatable="yes">gtk-cut</property> + <property name="use_underline">True</property> + <signal name="activate" handler="on_cut1_activate" last_modification_time="Tue, 03 Sep 2002 19:14:39 GMT"/> + </widget> + </child> + + <child> + <widget class="GtkImageMenuItem" id="imagemenuitem5"> + <property name="visible">True</property> + <property name="label" translatable="yes">gtk-copy</property> + <property name="use_underline">True</property> + <signal name="activate" handler="on_copy1_activate" last_modification_time="Tue, 03 Sep 2002 19:14:39 GMT"/> + </widget> + </child> + + <child> + <widget class="GtkImageMenuItem" id="imagemenuitem6"> + <property name="visible">True</property> + <property name="label" translatable="yes">gtk-paste</property> + <property name="use_underline">True</property> + <signal name="activate" handler="on_paste1_activate" last_modification_time="Tue, 03 Sep 2002 19:14:39 GMT"/> + </widget> + </child> + + <child> + <widget class="GtkImageMenuItem" id="imagemenuitem7"> + <property name="visible">True</property> + <property name="label" translatable="yes">gtk-clear</property> + <property name="use_underline">True</property> + <signal name="activate" handler="on_delete1_activate" last_modification_time="Tue, 03 Sep 2002 19:14:39 GMT"/> + </widget> + </child> + + <child> + <widget class="GtkMenuItem" id="menuitem10"> + <property name="visible">True</property> + </widget> + </child> + + <child> + <widget class="GtkImageMenuItem" id="imagemenuitem8"> + <property name="visible">True</property> + <property name="label" translatable="yes">Find ...</property> + <property name="use_underline">True</property> + <signal name="activate" handler="on_find_1_activate" last_modification_time="Mon, 11 Nov 2002 23:46:21 GMT"/> + <accelerator key="F" modifiers="GDK_CONTROL_MASK" signal="activate"/> + + <child internal-child="image"> + <widget class="GtkImage" id="image40"> + <property name="visible">True</property> + <property name="stock">gtk-find</property> + <property name="icon_size">1</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + </child> + </widget> + </child> + + <child> + <widget class="GtkImageMenuItem" id="imagemenuitem9"> + <property name="visible">True</property> + <property name="label" translatable="yes">Find Ne_xt</property> + <property name="use_underline">True</property> + <signal name="activate" handler="on_find_next1_activate" last_modification_time="Mon, 11 Nov 2002 23:46:21 GMT"/> + <accelerator key="G" modifiers="GDK_CONTROL_MASK" signal="activate"/> + + <child internal-child="image"> + <widget class="GtkImage" id="image41"> + <property name="visible">True</property> + <property name="stock">gtk-find</property> + <property name="icon_size">1</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + </child> + </widget> + </child> + + <child> + <widget class="GtkMenuItem" id="menuitem11"> + <property name="visible">True</property> + </widget> + </child> + + <child> + <widget class="GtkImageMenuItem" id="imagemenuitem10"> + <property name="visible">True</property> + <property name="label" translatable="yes">gtk-preferences</property> + <property name="use_underline">True</property> + <signal name="activate" handler="on_preferences1_activate" last_modification_time="Mon, 11 Nov 2002 23:47:06 GMT"/> + </widget> + </child> + </widget> + </child> + </widget> + </child> + + <child> + <widget class="GtkMenuItem" id="menuitem12"> + <property name="visible">True</property> + <property name="label" translatable="yes">_Action</property> + <property name="use_underline">True</property> + + <child> + <widget class="GtkMenu" id="menu3"> + + <child> + <widget class="GtkMenuItem" id="menuitem13"> + <property name="visible">True</property> + <property name="label" translatable="yes">Talk in the Third Person...</property> + <property name="use_underline">True</property> + <signal name="activate" handler="on_talk_in_the_third_person1_activate" last_modification_time="Mon, 11 Nov 2002 23:55:47 GMT"/> + <accelerator key="m" modifiers="GDK_CONTROL_MASK" signal="activate"/> + </widget> + </child> + + <child> + <widget class="GtkMenuItem" id="menuitem14"> + <property name="visible">True</property> + <property name="label" translatable="yes">Change _Nickname...</property> + <property name="use_underline">True</property> + <signal name="activate" handler="on_change_nickname1_activate" last_modification_time="Mon, 11 Nov 2002 23:55:47 GMT"/> + <accelerator key="n" modifiers="GDK_CONTROL_MASK" signal="activate"/> + </widget> + </child> + + <child> + <widget class="GtkMenuItem" id="menuitem15"> + <property name="visible">True</property> + </widget> + </child> + + <child> + <widget class="GtkCheckMenuItem" id="checkmenuitem1"> + <property name="visible">True</property> + <property name="label" translatable="yes">Marked A_way</property> + <property name="use_underline">True</property> + <property name="active">False</property> + <signal name="activate" handler="on_marked_away1_activate" last_modification_time="Mon, 11 Nov 2002 23:55:47 GMT"/> + </widget> + </child> + </widget> + </child> + </widget> + </child> + + <child> + <widget class="GtkMenuItem" id="menuitem16"> + <property name="visible">True</property> + <property name="label" translatable="yes">_Help</property> + <property name="use_underline">True</property> + + <child> + <widget class="GtkMenu" id="menu4"> + + <child> + <widget class="GtkImageMenuItem" id="imagemenuitem11"> + <property name="visible">True</property> + <property name="label" translatable="yes">gnome-stock-about</property> + <property name="use_underline">True</property> + <signal name="activate" handler="on_about1_activate" last_modification_time="Tue, 03 Sep 2002 19:14:39 GMT"/> + </widget> + </child> + </widget> + </child> + </widget> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkNotebook" id="notebook2"> + <property name="width_request">0</property> + <property name="height_request">0</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="show_tabs">True</property> + <property name="show_border">True</property> + <property name="tab_pos">GTK_POS_LEFT</property> + <property name="scrollable">False</property> + <property name="enable_popup">False</property> + + <child> + <widget class="GtkAlignment" id="alignment7"> + <property name="visible">True</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xscale">1</property> + <property name="yscale">1</property> + <property name="top_padding">0</property> + <property name="bottom_padding">0</property> + <property name="left_padding">6</property> + <property name="right_padding">6</property> + + <child> + <widget class="GtkVBox" id="vbox17"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">0</property> + + <child> + <widget class="GtkScrolledWindow" id="scrolledwindow18"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="hscrollbar_policy">GTK_POLICY_NEVER</property> + <property name="vscrollbar_policy">GTK_POLICY_NEVER</property> + <property name="shadow_type">GTK_SHADOW_IN</property> + <property name="window_placement">GTK_CORNER_TOP_LEFT</property> + + <child> + <widget class="GtkTextView" id="textview11"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="editable">True</property> + <property name="overwrite">False</property> + <property name="accepts_tab">True</property> + <property name="justification">GTK_JUSTIFY_LEFT</property> + <property name="wrap_mode">GTK_WRAP_NONE</property> + <property name="cursor_visible">True</property> + <property name="pixels_above_lines">0</property> + <property name="pixels_below_lines">0</property> + <property name="pixels_inside_wrap">0</property> + <property name="left_margin">0</property> + <property name="right_margin">0</property> + <property name="indent">0</property> + <property name="text" translatable="yes"></property> + </widget> + </child> + </widget> + <packing> + <property name="padding">6</property> + <property name="expand">False</property> + <property name="fill">True</property> + </packing> + </child> + + <child> + <widget class="GtkScrolledWindow" id="scrolledwindow12"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="hscrollbar_policy">GTK_POLICY_NEVER</property> + <property name="vscrollbar_policy">GTK_POLICY_ALWAYS</property> + <property name="shadow_type">GTK_SHADOW_IN</property> + <property name="window_placement">GTK_CORNER_TOP_LEFT</property> + + <child> + <widget class="GtkTextView" id="textview8"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="editable">False</property> + <property name="overwrite">False</property> + <property name="accepts_tab">True</property> + <property name="justification">GTK_JUSTIFY_LEFT</property> + <property name="wrap_mode">GTK_WRAP_NONE</property> + <property name="cursor_visible">False</property> + <property name="pixels_above_lines">0</property> + <property name="pixels_below_lines">0</property> + <property name="pixels_inside_wrap">0</property> + <property name="left_margin">0</property> + <property name="right_margin">0</property> + <property name="indent">0</property> + <property name="text" translatable="yes"></property> + </widget> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + </child> + </widget> + <packing> + <property name="tab_expand">False</property> + <property name="tab_fill">True</property> + </packing> + </child> + + <child> + <widget class="GtkHBox" id="hbox21"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">0</property> + + <child> + <widget class="GtkImage" id="image42"> + <property name="visible">True</property> + <property name="stock">gnome-stock-about</property> + <property name="icon_size">1</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkLabel" id="label26"> + <property name="visible">True</property> + <property name="label" translatable="yes"><b><span color="#004784">#gtk</span></b></property> + <property name="use_underline">False</property> + <property name="use_markup">True</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0</property> + <property name="yalign">0.5</property> + <property name="xpad">6</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + <packing> + <property name="type">tab</property> + </packing> + </child> + + <child> + <widget class="GtkVBox" id="vbox23"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">6</property> + + <child> + <widget class="GtkScrolledWindow" id="scrolledwindow19"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="hscrollbar_policy">GTK_POLICY_NEVER</property> + <property name="vscrollbar_policy">GTK_POLICY_NEVER</property> + <property name="shadow_type">GTK_SHADOW_IN</property> + <property name="window_placement">GTK_CORNER_TOP_LEFT</property> + + <child> + <widget class="GtkTextView" id="textview12"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="editable">True</property> + <property name="overwrite">False</property> + <property name="accepts_tab">True</property> + <property name="justification">GTK_JUSTIFY_LEFT</property> + <property name="wrap_mode">GTK_WRAP_NONE</property> + <property name="cursor_visible">True</property> + <property name="pixels_above_lines">0</property> + <property name="pixels_below_lines">0</property> + <property name="pixels_inside_wrap">0</property> + <property name="left_margin">0</property> + <property name="right_margin">0</property> + <property name="indent">0</property> + <property name="text" translatable="yes"></property> + </widget> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">True</property> + </packing> + </child> + + <child> + <widget class="GtkScrolledWindow" id="scrolledwindow20"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="hscrollbar_policy">GTK_POLICY_NEVER</property> + <property name="vscrollbar_policy">GTK_POLICY_ALWAYS</property> + <property name="shadow_type">GTK_SHADOW_IN</property> + <property name="window_placement">GTK_CORNER_TOP_LEFT</property> + + <child> + <widget class="GtkTextView" id="textview13"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="editable">False</property> + <property name="overwrite">False</property> + <property name="accepts_tab">True</property> + <property name="justification">GTK_JUSTIFY_LEFT</property> + <property name="wrap_mode">GTK_WRAP_NONE</property> + <property name="cursor_visible">False</property> + <property name="pixels_above_lines">0</property> + <property name="pixels_below_lines">0</property> + <property name="pixels_inside_wrap">0</property> + <property name="left_margin">0</property> + <property name="right_margin">0</property> + <property name="indent">0</property> + <property name="text" translatable="yes"></property> + </widget> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + <packing> + <property name="tab_expand">False</property> + <property name="tab_fill">True</property> + </packing> + </child> + + <child> + <widget class="GtkHBox" id="hbox24"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">0</property> + + <child> + <widget class="GtkLabel" id="label28"> + <property name="width_request">16</property> + <property name="height_request">16</property> + <property name="visible">True</property> + <property name="label" translatable="yes"></property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkLabel" id="label29"> + <property name="visible">True</property> + <property name="label" translatable="yes">#gnome</property> + <property name="use_underline">False</property> + <property name="use_markup">True</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0</property> + <property name="yalign">0.5</property> + <property name="xpad">6</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + <packing> + <property name="type">tab</property> + </packing> + </child> + + <child> + <placeholder/> + </child> + + <child> + <widget class="GtkHBox" id="hbox25"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">0</property> + + <child> + <widget class="GtkLabel" id="label30"> + <property name="width_request">16</property> + <property name="height_request">16</property> + <property name="visible">True</property> + <property name="label" translatable="yes"><b>|</b></property> + <property name="use_underline">False</property> + <property name="use_markup">True</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkLabel" id="label31"> + <property name="visible">True</property> + <property name="label" translatable="yes"><b>#usability</b></property> + <property name="use_underline">False</property> + <property name="use_markup">True</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0</property> + <property name="yalign">0.5</property> + <property name="xpad">6</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + <packing> + <property name="type">tab</property> + </packing> + </child> + + <child> + <placeholder/> + </child> + + <child> + <widget class="GtkHBox" id="hbox26"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">0</property> + + <child> + <widget class="GtkLabel" id="label32"> + <property name="width_request">16</property> + <property name="height_request">16</property> + <property name="visible">True</property> + <property name="label" translatable="yes"></property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkLabel" id="label33"> + <property name="visible">True</property> + <property name="label" translatable="yes">#danmark</property> + <property name="use_underline">False</property> + <property name="use_markup">True</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0</property> + <property name="yalign">0.5</property> + <property name="xpad">6</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + <packing> + <property name="type">tab</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + </child> +</widget> + +</glade-interface> @@ -0,0 +1,931 @@ +#include "irc.h" +#include <lac.h> +#include <string.h> + +typedef struct IrcMessage IrcMessage; +typedef struct CommandInfo CommandInfo; + +typedef enum +{ + /* Errors */ + ERR_NOSUCHNICK = 401, + ERR_NOSUCHSERVER = 402, + ERR_NOSUCHCHANNEL = 403, + ERR_CANNOTSENDTOCHAN = 404, + ERR_TOOMANYCHANNELS = 405, + ERR_WASNOSUCHNICK = 406, + ERR_TOOMANYTARGETS = 407, + ERR_NOORIGIN = 409, + ERR_NORECIPIENT = 411, + ERR_NOTEXTTOSEND = 412, + ERR_NOTOPLEVEL = 413, + ERR_WILDTOPLEVEL = 414, + ERR_UNKNOWNCOMMAND = 421, + ERR_NOMOTD = 422, + ERR_NOADMININFO = 423, + ERR_FILEERROR = 424, + ERR_NONICKNAMEGIVEN = 431, + ERR_ERRONEUSNICKNAME = 432, + ERR_NICKNAMEINUSE = 433, + ERR_NICKCOLLISION = 436, + ERR_USERNOTINCHANNEL = 441, + ERR_NOTONCHANNEL = 442, + ERR_USERONCHANNEL = 443, + ERR_NOLOGIN = 444, + ERR_SUMMONDISABLED = 445, + ERR_USERSDISABLED = 446, + ERR_NOTREGISTERED = 451, + ERR_NEEDMOREPARAMS = 461, + ERR_ALREADYREGISTRED = 462, + ERR_NOPERMFORHOST = 463, + ERR_PASSWDMISMATCH = 464, + ERR_YOUREBANNEDCREEP = 465, + ERR_KEYSET = 467, + ERR_CHANNELISFULL = 471, + ERR_UNKNOWNMODE = 472, + ERR_INVITEONLYCHAN = 473, + ERR_BANNEDFROMCHAN = 474, + ERR_BADCHANNELKEY = 475, + ERR_NOPRIVILEGES = 481, + ERR_CHANOPRIVSNEEDED = 482, + ERR_CANTKILLSERVER = 483, + ERR_NOOPERHOST = 491, + ERR_UMODEUNKNOWNFLAG = 501, + ERR_USERSDONTMATCH = 502, + + /* Replies */ + RPL_NONE = 300, + RPL_USERHOST = 302, + RPL_ISON = 303, + RPL_AWAY = 301, + RPL_UNAWAY = 305, + RPL_NOWAWAY = 306, + RPL_WHOISUSER = 311, + RPL_WHOISSERVER = 312, + RPL_WHOISOPERATOR = 313, + RPL_WHOISIDLE = 317, + RPL_ENDOFWHOIS = 318, + RPL_WHOWASUSER = 314, + RPL_ENDOFWHOWAS = 369, + RPL_LISTSTART = 321, + RPL_LIST = 322, + RPL_LISTEND = 323, + RPL_CHANNELMODEIS = 324, + RPL_NOTOPIC = 331, + RPL_TOPIC = 332, + RPL_INVITING = 341, + RPL_SUMMONING = 342, + RPL_VERSION = 351, + RPL_WHOREPLY = 352, + RPL_ENDOFWHO = 315, + RPL_NAMREPLY = 353, + RPL_ENDOFNAMES = 366, + RPL_LINKS = 364, + RPL_ENDOFLINKS = 365, + RPL_BANLIST = 367, + RPL_ENDOFBANLIST = 368, + RPL_INFO = 371, + RPL_ENDOFINFO = 374, + RPL_MOTDSTART = 375, + RPL_MOTD = 372, + RPL_ENDOFMOTD = 376, + RPL_YOUREOPER = 381, + RPL_REHASHING = 382, + RPL_TIME = 391, + RPL_USERSSTART = 392, + RPL_USERS = 393, + RPL_ENDOFUSERS = 394, + RPL_NOUSERS = 395, + RPL_TRACELINK = 200, + RPL_TRACECONNECTING = 201, + RPL_TRACEHANDSHAKE = 202, + RPL_TRACEUNKNOWN = 203, + RPL_TRACEOPERATOR = 204, + RPL_TRACEUSER = 205, + RPL_TRACESERVER = 206, + RPL_TRACENEWTYPE = 208, + RPL_TRACELOG = 261, + RPL_STATSLINKINFO = 211, + RPL_STATSCOMMANDS = 212, + RPL_STATSCLINE = 213, + RPL_STATSNLINE = 214, + RPL_STATSILINE = 215, + RPL_STATSKLINE = 216, + RPL_STATSYLINE = 218, + RPL_ENDOFSTATS = 219, + RPL_STATSLLINE = 241, + RPL_STATSUPTIME = 242, + RPL_STATSOLINE = 243, + RPL_STATSHLINE = 244, + RPL_UMODEIS = 221, + RPL_LUSERCLIENT = 251, + RPL_LUSEROP = 252, + RPL_LUSERUNKNOWN = 253, + RPL_LUSERCHANNELS = 254, + RPL_LUSERME = 255, + RPL_ADMINME = 256, + RPL_ADMINLOC1 = 257, + RPL_ADMINLOC2 = 258, + RPL_ADMINEMAIL = 259, + + /* These codes are not specified by the RFC spec, just + * used internally. (IRC can't use them, because they + * have more than three digits) + */ + CMD_NOTICE = 9001, + CMD_PRIVMSG = 9002, + CMD_PASS = 9003, + CMD_NICK = 9004, + CMD_USER = 9005, + + CMD_UNKNOWN = 10000, /* message not understood */ +} ReplyCode; + +#define CR 0x0d +#define LF 0x0a +#define NUL 0x00 +#define BELL 0x07 +#define SPACE 0x20 +#define COMMA 0x2c + +static const gchar CRLF[] = { CR, LF, '\0' }; + +struct CommandInfo +{ + const ReplyCode code; + const char *text; +}; + +static const CommandInfo commands[] = +{ + { CMD_NOTICE, "NOTICE" }, + { CMD_PRIVMSG, "PRIVMSG" }, + { CMD_USER, "USER" }, + { CMD_PASS, "PASS" }, + { CMD_NICK, "NICK" }, + { CMD_UNKNOWN, "Unknown command" } +}; + +static ReplyCode +command_to_code (const char *start, const char *end) +{ + char *command = g_strndup (start, end - start); + ReplyCode code = CMD_UNKNOWN; + int i; + + for (i = 0; i < G_N_ELEMENTS (commands); ++i) + { + if (strcmp (command, commands[i].text) == 0) + { + code = commands[i].code; + break; + } + } + + return code; +} + +static const char * +code_to_command (ReplyCode code) +{ + const char *cmd = NULL; + int i; + + for (i = 0; i < G_N_ELEMENTS (commands); ++i) + { + if (commands[i].code == code) + { + cmd = commands[i].text; + break; + } + } + + return cmd; +} + +struct IrcMessage +{ + char * prefix; + ReplyCode code; + GQueue * parameters; + + GList * free_list; +}; + +static IrcMessage *message_new_parsed (const char **input, + int *length); +static void message_free (IrcMessage *msg); + +static gpointer trace (gpointer data, + gpointer free_func, + GList **freelist); + +/* + * Message parser + */ +static int +eat_spaces (const char **input, int *length) +{ + int n_spaces; + + n_spaces = 0; + while (**input == SPACE) + { + *input += 1; + *length -= 1; + + n_spaces++; + } + + return n_spaces; +} + +static const char * +find_char (const char *input, int length, char c) +{ + int i; + for (i = 0; i < length; ++i) + { + if (input[i] == c) + return input + i; + } + return NULL; +} + +static char * +parse_prefix (const char **input, + int *length, + GList **free_list, + gboolean *error) +{ + const char *space; + + space = find_char (*input, *length, SPACE); + if (!space || space == *input) + { + *error = TRUE; + return NULL; + } + else + { + int prefix_len = space - *input; + char *result = g_strndup (*input, prefix_len); + + *input += prefix_len; + *length -= prefix_len; + + return trace (result, g_free, free_list); + } +} + +static ReplyCode +parse_command (const char **input, + int *length, + GList **free_list, + gboolean *err) +{ + ReplyCode result; + + if (*length < 1) + goto error; + + if (g_ascii_isalpha (**input)) + { + const char *start = *input; + + while (*length > 0 && g_ascii_isalpha (**input)) + { + *input += 1; + *length -= 1; + } + + return command_to_code (start, *input); + } + else if (g_ascii_isdigit (**input)); + { + int d1, d2, d3; + + if (*length < 3) + goto error; + + d1 = (*input)[0] - '0'; + d2 = (*input)[1] - '0'; + d3 = (*input)[2] - '0'; + + if (d1 < 0 || d1 > 9 || + d2 < 0 || d2 > 9 || + d3 < 0 || d3 > 9) + { + goto error; + } + + *input += 3; + *length -= 3; + + return (ReplyCode) d1 * 100 + d2 * 10 + d3; + } + + return result; + +error: + *err = TRUE; + return -1; +} + +static gboolean +is_trailing_char (char c) +{ + return c != NUL && c != CR && c != LF; +} + +static gboolean +is_middle_char (char c) +{ + return c != SPACE && c != NUL && c != CR && c != LF; +} + +static char * +parse_trailing (const char **input, + int *length, + GList **free_list, + gboolean *err) +{ + const char *start = *input; + + while (*length > 0 && is_trailing_char (**input)) + { + *input += 1; + *length -= 1; + } + + if (*input != start) + return trace (g_strndup (start, *input - start), g_free, free_list); + else + return NULL; +} + +static char * +parse_middle (const char **input, + int *length, + GList **free_list, + gboolean *err) +{ + const char *start = *input; + + while (*length > 0 && is_middle_char (**input)) + { + *input += 1; + *length -= 1; + } + + if (*input == start) + goto error; + + return trace (g_strndup (start, *input - start), g_free, free_list); + +error: + *err = TRUE; + return NUL; +} + +static GQueue * +parse_params (const char **input, + int *length, + GList **free_list, + gboolean *err) +{ + GQueue *params = NULL; + + if (*length < 1) + goto error; + + if (**input == SPACE) + eat_spaces (input, length); + + if (*length > 0) + { + char *trailing; + + if (**input == ':') + { + *input += 1; + *length -= 1; + + /* <trailing> */ + trailing = parse_trailing (input, length, free_list, err); + if (*err) + goto error; + + if (trailing) + { + params = trace (g_queue_new(), g_queue_free, free_list); + + g_queue_push_tail (params, trailing); + } + } + else if (is_middle_char (**input)) + { + char *middle; + + /* <middle> */ + middle = parse_middle (input, length, free_list, err); + if (*err) + goto error; + + /* <params> */ + + /* The RFC states that parameters always start with SPACE, + * but that is a lie: The final params following a <middle> + * can be the empty string + */ + if (**input == SPACE) + { + params = parse_params (input, length, free_list, err); + if (*err) + goto error; + } + else + { + params = trace (g_queue_new(), g_queue_free, free_list); + + g_queue_push_head (params, middle); + } + } + } + + if (!params) + params = trace (g_queue_new(), g_queue_free, free_list); + + return params; + +error: + *err = TRUE; + return NULL; +} + +/* Returns NULL if *input is not a valid message. This will also + * happen if we just haven't received enough data yet. + */ +static IrcMessage * +message_new_parsed (const char **input, + int *length) +{ + IrcMessage *msg = g_new (IrcMessage, 1); + const char *crlf; + gboolean err = FALSE; + + msg->free_list = NULL; + + if (*length < 2) + goto error; + + crlf = strstr (*input, CRLF); + + if (!crlf) + goto error; + + if (crlf - *input > 510) + goto error; + + msg->prefix = NULL; + if (**input == ':') + { + *input += 1; + *length -= 1; + + msg->prefix = parse_prefix (input, length, &msg->free_list, &err); + + if (err) + goto error; + + if (eat_spaces (input, length) < 1) + goto error; + } + + msg->code = parse_command (input, length, &msg->free_list, &err); + if (err) + goto error; + + msg->parameters = parse_params (input, length, &msg->free_list, &err); + + if (err) + goto error; + + if (*length < 2) + goto error; + + if (strncmp (*input, CRLF, 2) != 0) + goto error; + + *input += 2; + *length -= 2; + + return msg; + +error: + message_free (msg); + return NULL; +} + +static void +message_free (IrcMessage *msg) +{ + GList *list; + + for (list = msg->free_list; list != NULL; list = list->next->next) + { + GDestroyNotify free_func = list->data; + gpointer alloc = list->next->data; + + (* free_func) (alloc); + } + + g_list_free (msg->free_list); + + g_free (msg); +} + +typedef enum +{ + NOT_CONNECTED, + CONNECTING, + CONNECTED +} IrcServerState; + +struct IrcServer +{ + /* information about server */ + char * hostname; + gint port; + + /* information about user */ + char * local_user_name; + char * local_host_name; + char * local_domain_name; + char * real_name; + char * nickname; + char * password; + + /* state */ + IrcServerState state; + LacConnection * connection; + IrcServerFunc func; + gpointer data; + GString * unparsed; + GQueue * messages; +}; + +IrcServer * +irc_server_new (const char *hostname, + gint port, + IrcServerFunc func, + gpointer data) +{ + IrcServer *server; + + g_return_val_if_fail (hostname != NULL, NULL); + g_return_val_if_fail (port > 0, NULL); + g_return_val_if_fail (func != NULL, NULL); + + server = g_new (IrcServer, 1); + + server->hostname = g_strdup (hostname); + server->port = port; + + server->local_user_name = NULL; + server->local_host_name = NULL; + server->local_domain_name = NULL; + server->real_name = NULL; + server->nickname = NULL; + server->password = NULL; + + server->state = NOT_CONNECTED; + server->connection = NULL; + server->func = func; + server->data = data; + server->unparsed = g_string_new (""); + server->messages = g_queue_new (); + + return server; +} + +gpointer +irc_server_get_data (IrcServer *server) +{ + g_return_val_if_fail (server != NULL, NULL); + + return server->data; +} + +static void +server_emit_dns_complete (IrcServer *server) +{ +} + +static void +server_emit_error (IrcServer *server, + const GError *err) +{ + +} + +static void +server_emit_connect (IrcServer *server) +{ + +} + +static void +server_emit_close (IrcServer *server) +{ + +} + +static void +emit_malformed_error (IrcServer *server, const char *msg) +{ + GError *error = NULL; + + g_set_error (&error, + IRC_ERROR, + IRC_ERROR_MALFORMED_MESSAGE, + "Server %s sent an unparsable message (%s) " + "(This is most likely a bug in ChatterBox)", + server->hostname, + msg); + + server_emit_error (server, error); + + g_error_free (error); +} + +static gboolean +process_data (IrcServer *server) +{ + char *crlf = strstr (server->unparsed->str, CRLF); + + if (!crlf && server->unparsed->len > 510) + { + /* We have seen 510 bytes in a row without + * a CRLF. This means the server is sending + * garbage + */ + emit_malformed_error (server, "No CRLF"); + lac_connection_close (server->connection); + return FALSE; + } + else if (crlf) + { + IrcMessage *msg; + const char *s = server->unparsed->str; + int len = server->unparsed->len; + + msg = message_new_parsed (&s, &len); + + if (!msg) + { + emit_malformed_error (server, "parse error"); + lac_connection_close (server->connection); + return FALSE; + } + + g_string_erase (server->unparsed, 0, server->unparsed->len - len); + + /* process message */ +#if 0 + g_print ("\ncommand: %s - %d ", msg->prefix? msg->prefix : "", msg->code); + for (list = msg->parameters->head; list != NULL; list = list->next) + { + g_print ("%s ", (char *)list->data); + } + g_print ("\n"); +#endif + + message_free (msg); + return TRUE; + } + else + { + g_print ("no data/not enough data\n"); + /* No CRLF and less than 510 bytes: not enough + * data yet + */ + return FALSE; + } +} + +static void +server_handle_read (IrcServer *server, + const LacConnectionReadEvent *read) +{ + int i; + + for (i = 0; i < read->len; ++i) + g_print ("%c", read->data[i]); + + g_string_append_len (server->unparsed, read->data, read->len); + + while (process_data (server)) + ; +} + +static void +server_handle_disconnect (IrcServer *server) +{ + server->state = NOT_CONNECTED; + lac_connection_unref (server->connection); + server->connection = NULL; +} + +static void +server_send_command (IrcServer *server, + const char *prefix, + ReplyCode code, + const char *param, + ...) +{ + va_list var_args; + GQueue *params = g_queue_new (); + const char *command; + GList *list; + GString *message; + + command = code_to_command (code); + + g_return_if_fail (command != NULL); + + va_start (var_args, param); + + while (param != NULL) + { + g_queue_push_tail (params, (gpointer)param); + + param = va_arg (var_args, char *); + } + + va_end (var_args); + + message = g_string_new (""); + + if (prefix) + { + g_string_append (message, ":"); + g_string_append (message, prefix); + g_string_append (message, " "); + } + + g_string_append (message, command); + + for (list = params->head; list != NULL; list = list->next) + { + g_string_append (message, " "); + if (!list->next) + g_string_append (message, ":"); + g_string_append (message, list->data); + } + + g_string_append (message, CRLF); + + lac_connection_write (server->connection, message->str, message->len); + + g_string_free (message, TRUE); +} + +static void +server_send_registration (IrcServer *server) +{ + server_send_command (server, NULL, CMD_PASS, server->password, NULL); + server_send_command (server, NULL, CMD_NICK, server->nickname, NULL); + server_send_command ( + server, NULL, CMD_USER, + server->local_user_name? server->local_user_name : "unknown", + server->local_host_name? server->local_host_name : "unknown", + server->local_domain_name? server->local_domain_name : "unknown", + server->real_name? server->real_name : "Unknown", + NULL); +} + +static void +connection_callback (LacConnection *connection, + const LacConnectionEvent *event) +{ + IrcServer *server = lac_connection_get_data (connection); + + g_assert (server); + + switch (event->type) + { + case LAC_CONNECTION_EVENT_CONNECT: /* connect successful */ + server_emit_connect (server); + server->state = CONNECTED; + server_send_registration (server); + break; + + case LAC_CONNECTION_EVENT_READ: + server_handle_read (server, &(event->read)); + break; /* data to read */ + + case LAC_CONNECTION_EVENT_CLOSE: /* Connection closed */ + if (event->close.remote_closed) + server_emit_close (server); + server_handle_disconnect (server); + break; + + case LAC_CONNECTION_EVENT_ERROR: /* error */ + server_emit_error (server, event->error.err); + server_handle_disconnect (server); + break; + } +} + +static void +address_callback (const LacAddress * address, + gpointer data, + const GError * err) +{ + IrcServer *server = data; + + if (err) + { + server_emit_error (server, err); + } + else + { + server_emit_dns_complete (server); + server->connection = lac_connection_new ( + address, server->port, connection_callback, server); + } +} + +static char * +generate_password (void) +{ + return g_strdup_printf ("CH%x%x%x", + g_random_int(), + g_random_int(), + g_random_int()); +} + +void +irc_server_connect (IrcServer *server, + const char *nick, + const char *password) +{ + char *orig_pw, *orig_nick; + + g_return_if_fail (server != NULL); + g_return_if_fail (server->state == NOT_CONNECTED); + g_return_if_fail (nick != NULL); + + if (server->state != NOT_CONNECTED) + return; + + orig_pw = server->password; + orig_nick = server->nickname; + + if (password) + server->password = g_strdup (password); + else + server->password = generate_password (); + + server->nickname = g_strdup (nick); + + if (orig_pw) + g_free (orig_pw); + if (orig_nick) + g_free (orig_nick); + + server->state = CONNECTING; + lac_address_new_lookup_from_name ( + server->hostname, address_callback, server); +} + +void +irc_server_disconnect (IrcServer *server) +{ +} + +/* Tracing memory + */ + +static gpointer +trace (gpointer data, + gpointer free_func, + GList **free_list) +{ + *free_list = g_list_prepend (*free_list, data); + *free_list = g_list_prepend (*free_list, free_func); + return data; +} + +GQuark +irc_error_quark (void) +{ + static GQuark q = 0; + + if (q == 0) + q = g_quark_from_static_string ("irc-error-quark"); + + return q; +} + @@ -0,0 +1,70 @@ +#include <glib.h> + +/* + * Irc utilities + */ + +/* + * IrcServer + */ + +typedef struct IrcServer IrcServer; +typedef struct IrcChannel IrcChannel; + +#define IRC_ERROR irc_error_quark () + +typedef enum +{ + IRC_ERROR_MALFORMED_MESSAGE +} IrcError; + +GQuark irc_error_quark (void); + +typedef enum +{ + IRC_SERVER_LOOKING_UP_HOSTNAME, + IRC_SERVER_FOUND_HOST_NAME, + IRC_SERVER_CONNECTING, + IRC_SERVER_CONNECTED, + IRC_SERVER_DISCONNECT, + IRC_SERVER_ERROR +} IrcServerEvent; + +typedef enum +{ + IRC_CHANNEL_MESSAGE, + IRC_TOPIC_CHANGED, + IRC_USER_JOINED, +} IrcChannelEvent; + +typedef void (* IrcServerFunc) (IrcServer *server, + const IrcServerEvent *event); + +typedef void (* IrcChannelListFunc) (GList *channels, gpointer data); + +IrcServer *irc_server_new (const char *name, + gint port, + IrcServerFunc func, + gpointer data); +gpointer irc_server_get_data (IrcServer *server); + +void irc_server_list_channels (IrcServer *server, + IrcChannelListFunc func, + gpointer data); + +void irc_server_connect (IrcServer *server, + const char *nickname, + const char *password); +void irc_server_disconnect (IrcServer *server); + +typedef void (* IrcChannelFunc) (IrcChannel *channel, + const IrcChannelEvent *event, + gpointer data); + +IrcChannel *irc_server_join_channel (IrcServer *server, + const char *name, + IrcChannelFunc func, + gpointer data); + + +/* Channel operations */ @@ -0,0 +1,41 @@ +#include "channel-buffer.h" +#include "irc.h" + +static void +irc_func (IrcServer *server, + const IrcServerEvent *event) +{ + +} + +int +main (int argc, char **argv) +{ +#if 0 + GMainLoop *loop; + IrcServer *server = irc_server_new ("irc.gimp.org", 6667, irc_func, "hej"); + + loop = g_main_loop_new (NULL, FALSE); + + irc_server_connect (server, "ssp", "birnan"); + + g_main_loop_run (loop); +#endif + gtk_init (&argc, &argv); + + ChannelBuffer *buffer = channel_buffer_new ("ssp"); + + GtkWindow *window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + GtkWidget *text = gtk_text_view_new (); + + gtk_text_view_set_buffer (GTK_TEXT_VIEW (text), + channel_buffer_get_text_buffer (buffer)); + + gtk_container_add (GTK_CONTAINER (window), text); + + gtk_widget_show_all (window); + + gtk_main (); + + return 0; +} |