pidgin/purple-plugin-pack
Clone
Summary
Browse
Changes
Graph
Changelogging a bunch of stuff.
2010-08-13, John Bailey
a6eb63360fad
Changelogging a bunch of stuff.
/*--------------------------------------------------------------------------*
* AUTOPROFILE *
* *
* A Purple away message and profile manager that supports dynamic text *
* *
* AutoProfile is the legal property of its developers. Please refer to *
* the COPYRIGHT file distributed with this source distribution. *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software *
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
*--------------------------------------------------------------------------*/
#include
"autoprofile.h"
#include
"gtkimhtml.h"
#include
"gtksavedstatuses.h"
#include
"gtkprefs.h"
/*--------------------------------------------------------------------------*
* Info Tab *
*--------------------------------------------------------------------------*/
static
GtkWidget
*
get_info_page
()
{
GtkWidget
*
page
;
GtkWidget
*
label
;
GtkWidget
*
aboutwin
;
GtkWidget
*
text
;
gchar
*
labeltext
,
*
str
;
/* Make the box */
page
=
gtk_vbox_new
(
FALSE
,
5
);
gtk_container_set_border_width
(
GTK_CONTAINER
(
page
),
5
);
/* AutoProfile title */
labeltext
=
g_strdup_printf
(
_
(
"<span weight=
\"
bold
\"
size=
\"
larger
\"
>AutoProfile %s</span>"
),
PP_VERSION
);
label
=
gtk_label_new
(
NULL
);
gtk_label_set_markup
(
GTK_LABEL
(
label
),
labeltext
);
gtk_label_set_line_wrap
(
GTK_LABEL
(
label
),
TRUE
);
gtk_misc_set_alignment
(
GTK_MISC
(
label
),
0.5
,
0
);
gtk_box_pack_start
(
GTK_BOX
(
page
),
label
,
FALSE
,
FALSE
,
0
);
g_free
(
labeltext
);
/* Window with info */
aboutwin
=
gtk_scrolled_window_new
(
NULL
,
NULL
);
gtk_scrolled_window_set_policy
(
GTK_SCROLLED_WINDOW
(
aboutwin
),
GTK_POLICY_AUTOMATIC
,
GTK_POLICY_AUTOMATIC
);
gtk_scrolled_window_set_shadow_type
(
GTK_SCROLLED_WINDOW
(
aboutwin
),
GTK_SHADOW_IN
);
gtk_box_pack_start
(
GTK_BOX
(
page
),
aboutwin
,
TRUE
,
TRUE
,
0
);
text
=
gtk_imhtml_new
(
NULL
,
NULL
);
gtk_container_add
(
GTK_CONTAINER
(
aboutwin
),
text
);
pidgin_setup_imhtml
(
text
);
/* Info text */
gtk_imhtml_append_text
(
GTK_IMHTML
(
text
),
_
(
"Use the <b>Autoprofile</b> portion of the <b>Tools</b> "
"menu in the <b>"
"buddy list</b> to configure the actual content that will go in your "
"status messages and profiles and set options.<br><br>"
),
GTK_IMHTML_NO_SCROLL
);
gtk_imhtml_append_text
(
GTK_IMHTML
(
text
),
_
(
"<u>DOCUMENTATION / HELP</u><br>"
),
GTK_IMHTML_NO_SCROLL
);
gtk_imhtml_append_text
(
GTK_IMHTML
(
text
),
_
(
"Complete documentation can be found at:<br> <a href="
"
\"
http://hkn.eecs.berkeley.edu/~casey/autoprofile/documentation.php
\"
>"
"hkn.eecs.berkeley.edu/~casey/autoprofile/documentation.php</a><br>"
),
GTK_IMHTML_NO_SCROLL
);
gtk_imhtml_append_text
(
GTK_IMHTML
(
text
),
_
(
"<br><u>ABOUT</u><br>"
),
GTK_IMHTML_NO_SCROLL
);
str
=
g_strconcat
(
"<font size=
\"
3
\"
><b>"
,
_
(
"Developers"
),
":</b></font><br>"
" Casey Ho (Lead Developer)<br>"
" Mitchell Harwell<br>"
,
NULL
);
gtk_imhtml_append_text
(
GTK_IMHTML
(
text
),
str
,
GTK_IMHTML_NO_SCROLL
);
g_free
(
str
);
str
=
g_strconcat
(
"<font size=
\"
3
\"
><b>"
,
_
(
"Contributors/Patchers"
),
":</b></font><br>"
" Onime Clement<br>"
" Michael Milligan<br>"
" Mark Painter<br>"
,
NULL
);
gtk_imhtml_append_text
(
GTK_IMHTML
(
text
),
str
,
GTK_IMHTML_NO_SCROLL
);
g_free
(
str
);
str
=
g_strconcat
(
"<font size=
\"
3
\"
><b>"
,
_
(
"Website"
),
":</b></font><br>"
" <a href=
\"
http://autoprofile.sourceforge.net
\"
>"
"autoprofile.sourceforge.net<br>"
,
NULL
);
gtk_imhtml_append_text
(
GTK_IMHTML
(
text
),
str
,
GTK_IMHTML_NO_SCROLL
);
g_free
(
str
);
return
page
;
}
/*----------------------------------------------------------------------------
* Accounts Tab
*--------------------------------------------------------------------------*/
/* PRIMARILY RIPPED FROM GAIM GTKACCOUNT.C */
enum
{
COLUMN_ICON
,
COLUMN_SCREENNAME
,
COLUMN_ENABLED
,
COLUMN_PROTOCOL
,
COLUMN_DATA
,
COLUMN_PULSE_DATA
,
NUM_COLUMNS
};
typedef
struct
{
PurpleAccount
*
account
;
char
*
username
;
char
*
alias
;
}
PidginAccountAddUserData
;
typedef
struct
{
GtkWidget
*
treeview
;
GtkListStore
*
model
;
GtkTreeIter
drag_iter
;
GtkTreeViewColumn
*
screenname_col
;
}
AccountsWindow
;
static
void
add_account_to_liststore
(
PurpleAccount
*
,
gpointer
);
static
void
set_account
(
GtkListStore
*
,
GtkTreeIter
*
,
PurpleAccount
*
);
static
gboolean
is_profile_settable
(
PurpleAccount
*
a
)
{
const
gchar
*
id
=
purple_account_get_protocol_id
(
a
);
if
(
!
strcmp
(
id
,
"prpl-yahoo"
)
||
!
strcmp
(
id
,
"prpl-msn"
)
||
!
strcmp
(
id
,
"prpl-jabber"
))
{
return
FALSE
;
}
return
TRUE
;
}
static
void
drag_data_get_cb
(
GtkWidget
*
widget
,
GdkDragContext
*
ctx
,
GtkSelectionData
*
data
,
guint
info
,
guint
time
,
AccountsWindow
*
dialog
)
{
if
(
data
->
target
==
gdk_atom_intern
(
"PURPLE_ACCOUNT"
,
FALSE
))
{
GtkTreeRowReference
*
ref
;
GtkTreePath
*
source_row
;
GtkTreeIter
iter
;
PurpleAccount
*
account
=
NULL
;
GValue
val
=
{
0
};
ref
=
g_object_get_data
(
G_OBJECT
(
ctx
),
"gtk-tree-view-source-row"
);
source_row
=
gtk_tree_row_reference_get_path
(
ref
);
if
(
source_row
==
NULL
)
return
;
gtk_tree_model_get_iter
(
GTK_TREE_MODEL
(
dialog
->
model
),
&
iter
,
source_row
);
gtk_tree_model_get_value
(
GTK_TREE_MODEL
(
dialog
->
model
),
&
iter
,
COLUMN_DATA
,
&
val
);
dialog
->
drag_iter
=
iter
;
account
=
g_value_get_pointer
(
&
val
);
gtk_selection_data_set
(
data
,
gdk_atom_intern
(
"PURPLE_ACCOUNT"
,
FALSE
),
8
,
(
void
*
)
&
account
,
sizeof
(
account
));
gtk_tree_path_free
(
source_row
);
}
}
static
void
move_account_after
(
GtkListStore
*
store
,
GtkTreeIter
*
iter
,
GtkTreeIter
*
position
)
{
GtkTreeIter
new_iter
;
PurpleAccount
*
account
;
gtk_tree_model_get
(
GTK_TREE_MODEL
(
store
),
iter
,
COLUMN_DATA
,
&
account
,
-1
);
gtk_list_store_insert_after
(
store
,
&
new_iter
,
position
);
set_account
(
store
,
&
new_iter
,
account
);
gtk_list_store_remove
(
store
,
iter
);
}
static
void
move_account_before
(
GtkListStore
*
store
,
GtkTreeIter
*
iter
,
GtkTreeIter
*
position
)
{
GtkTreeIter
new_iter
;
PurpleAccount
*
account
;
gtk_tree_model_get
(
GTK_TREE_MODEL
(
store
),
iter
,
COLUMN_DATA
,
&
account
,
-1
);
gtk_list_store_insert_before
(
store
,
&
new_iter
,
position
);
set_account
(
store
,
&
new_iter
,
account
);
gtk_list_store_remove
(
store
,
iter
);
}
static
void
drag_data_received_cb
(
GtkWidget
*
widget
,
GdkDragContext
*
ctx
,
guint
x
,
guint
y
,
GtkSelectionData
*
sd
,
guint
info
,
guint
t
,
AccountsWindow
*
dialog
)
{
if
(
sd
->
target
==
gdk_atom_intern
(
"PURPLE_ACCOUNT"
,
FALSE
)
&&
sd
->
data
)
{
gint
dest_index
;
PurpleAccount
*
a
=
NULL
;
GtkTreePath
*
path
=
NULL
;
GtkTreeViewDropPosition
position
;
memcpy
(
&
a
,
sd
->
data
,
sizeof
(
a
));
if
(
gtk_tree_view_get_dest_row_at_pos
(
GTK_TREE_VIEW
(
widget
),
x
,
y
,
&
path
,
&
position
))
{
GtkTreeIter
iter
;
PurpleAccount
*
account
;
GValue
val
=
{
0
};
gtk_tree_model_get_iter
(
GTK_TREE_MODEL
(
dialog
->
model
),
&
iter
,
path
);
gtk_tree_model_get_value
(
GTK_TREE_MODEL
(
dialog
->
model
),
&
iter
,
COLUMN_DATA
,
&
val
);
account
=
g_value_get_pointer
(
&
val
);
switch
(
position
)
{
case
GTK_TREE_VIEW_DROP_AFTER
:
case
GTK_TREE_VIEW_DROP_INTO_OR_AFTER
:
move_account_after
(
dialog
->
model
,
&
dialog
->
drag_iter
,
&
iter
);
dest_index
=
g_list_index
(
purple_accounts_get_all
(),
account
)
+
1
;
break
;
case
GTK_TREE_VIEW_DROP_BEFORE
:
case
GTK_TREE_VIEW_DROP_INTO_OR_BEFORE
:
dest_index
=
g_list_index
(
purple_accounts_get_all
(),
account
);
move_account_before
(
dialog
->
model
,
&
dialog
->
drag_iter
,
&
iter
);
break
;
default
:
return
;
}
purple_accounts_reorder
(
a
,
dest_index
);
}
}
}
static
void
enabled_cb
(
GtkCellRendererToggle
*
renderer
,
gchar
*
path_str
,
gpointer
data
)
{
AccountsWindow
*
dialog
=
(
AccountsWindow
*
)
data
;
PurpleAccount
*
account
;
GtkTreeModel
*
model
=
GTK_TREE_MODEL
(
dialog
->
model
);
GtkTreeIter
iter
;
gboolean
enabled
;
gtk_tree_model_get_iter_from_string
(
model
,
&
iter
,
path_str
);
gtk_tree_model_get
(
model
,
&
iter
,
COLUMN_DATA
,
&
account
,
COLUMN_ENABLED
,
&
enabled
,
-1
);
/* Change profile settings */
ap_account_enable_profile
(
account
,
!
enabled
);
set_account
(
dialog
->
model
,
&
iter
,
account
);
}
static
void
add_columns
(
GtkWidget
*
treeview
,
AccountsWindow
*
dialog
)
{
GtkCellRenderer
*
renderer
;
GtkTreeViewColumn
*
column
;
/* Screen Name column */
column
=
gtk_tree_view_column_new
();
gtk_tree_view_column_set_title
(
column
,
_
(
"Screen Name"
));
gtk_tree_view_insert_column
(
GTK_TREE_VIEW
(
treeview
),
column
,
-1
);
gtk_tree_view_column_set_resizable
(
column
,
TRUE
);
/* Icon */
renderer
=
gtk_cell_renderer_pixbuf_new
();
gtk_tree_view_column_pack_start
(
column
,
renderer
,
FALSE
);
gtk_tree_view_column_add_attribute
(
column
,
renderer
,
"pixbuf"
,
COLUMN_ICON
);
/* Screen Name */
renderer
=
gtk_cell_renderer_text_new
();
gtk_tree_view_column_pack_start
(
column
,
renderer
,
TRUE
);
gtk_tree_view_column_add_attribute
(
column
,
renderer
,
"text"
,
COLUMN_SCREENNAME
);
dialog
->
screenname_col
=
column
;
/* Enabled */
renderer
=
gtk_cell_renderer_toggle_new
();
g_signal_connect
(
G_OBJECT
(
renderer
),
"toggled"
,
G_CALLBACK
(
enabled_cb
),
dialog
);
column
=
gtk_tree_view_column_new_with_attributes
(
_
(
"AutoProfile sets user info"
),
renderer
,
"active"
,
COLUMN_ENABLED
,
NULL
);
gtk_tree_view_insert_column
(
GTK_TREE_VIEW
(
treeview
),
column
,
-1
);
gtk_tree_view_column_set_resizable
(
column
,
TRUE
);
/* Protocol name */
column
=
gtk_tree_view_column_new
();
gtk_tree_view_column_set_title
(
column
,
_
(
"Protocol"
));
gtk_tree_view_insert_column
(
GTK_TREE_VIEW
(
treeview
),
column
,
-1
);
gtk_tree_view_column_set_resizable
(
column
,
TRUE
);
renderer
=
gtk_cell_renderer_text_new
();
gtk_tree_view_column_pack_start
(
column
,
renderer
,
TRUE
);
gtk_tree_view_column_add_attribute
(
column
,
renderer
,
"text"
,
COLUMN_PROTOCOL
);
}
static
void
set_account
(
GtkListStore
*
store
,
GtkTreeIter
*
iter
,
PurpleAccount
*
account
)
{
GdkPixbuf
*
pixbuf
;
GdkPixbuf
*
scale
;
scale
=
NULL
;
pixbuf
=
pidgin_create_prpl_icon
(
account
,
0.5
);
if
(
pixbuf
!=
NULL
)
{
scale
=
gdk_pixbuf_scale_simple
(
pixbuf
,
16
,
16
,
GDK_INTERP_BILINEAR
);
if
(
purple_account_is_disconnected
(
account
))
gdk_pixbuf_saturate_and_pixelate
(
scale
,
scale
,
0.0
,
FALSE
);
}
gtk_list_store_set
(
store
,
iter
,
COLUMN_ICON
,
scale
,
COLUMN_SCREENNAME
,
purple_account_get_username
(
account
),
COLUMN_ENABLED
,
ap_account_has_profile_enabled
(
account
),
COLUMN_PROTOCOL
,
purple_account_get_protocol_name
(
account
),
COLUMN_DATA
,
account
,
-1
);
if
(
pixbuf
!=
NULL
)
g_object_unref
(
G_OBJECT
(
pixbuf
));
if
(
scale
!=
NULL
)
g_object_unref
(
G_OBJECT
(
scale
));
}
static
void
add_account_to_liststore
(
PurpleAccount
*
account
,
gpointer
user_data
)
{
GtkTreeIter
iter
;
AccountsWindow
*
dialog
=
(
AccountsWindow
*
)
user_data
;
if
(
dialog
==
NULL
)
return
;
if
(
!
is_profile_settable
(
account
))
return
;
gtk_list_store_append
(
dialog
->
model
,
&
iter
);
set_account
(
dialog
->
model
,
&
iter
,
account
);
}
static
void
populate_accounts_list
(
AccountsWindow
*
dialog
)
{
GList
*
l
;
gtk_list_store_clear
(
dialog
->
model
);
for
(
l
=
purple_accounts_get_all
();
l
!=
NULL
;
l
=
l
->
next
)
add_account_to_liststore
((
PurpleAccount
*
)
l
->
data
,
dialog
);
}
#if !GTK_CHECK_VERSION(2,2,0)
static
void
get_selected_helper
(
GtkTreeModel
*
model
,
GtkTreePath
*
path
,
GtkTreeIter
*
iter
,
gpointer
user_data
)
{
*
((
gboolean
*
)
user_data
)
=
TRUE
;
}
#endif
static
void
account_selected_cb
(
GtkTreeSelection
*
sel
,
AccountsWindow
*
dialog
)
{
gboolean
selected
=
FALSE
;
#if GTK_CHECK_VERSION(2,2,0)
selected
=
(
gtk_tree_selection_count_selected_rows
(
sel
)
>
0
);
#else
gtk_tree_selection_selected_foreach
(
sel
,
get_selected_helper
,
&
selected
);
#endif
}
static
GtkWidget
*
create_accounts_list
(
AccountsWindow
*
dialog
)
{
GtkWidget
*
sw
;
GtkWidget
*
treeview
;
GtkTreeSelection
*
sel
;
GtkTargetEntry
gte
[]
=
{{
"PURPLE_ACCOUNT"
,
GTK_TARGET_SAME_APP
,
0
}};
/* Create the scrolled window. */
sw
=
gtk_scrolled_window_new
(
0
,
0
);
gtk_scrolled_window_set_policy
(
GTK_SCROLLED_WINDOW
(
sw
),
GTK_POLICY_AUTOMATIC
,
GTK_POLICY_ALWAYS
);
gtk_scrolled_window_set_shadow_type
(
GTK_SCROLLED_WINDOW
(
sw
),
GTK_SHADOW_IN
);
gtk_widget_show
(
sw
);
/* Create the list model. */
dialog
->
model
=
gtk_list_store_new
(
NUM_COLUMNS
,
GDK_TYPE_PIXBUF
,
G_TYPE_STRING
,
G_TYPE_BOOLEAN
,
G_TYPE_STRING
,
G_TYPE_POINTER
,
G_TYPE_POINTER
);
/* And now the actual treeview */
treeview
=
gtk_tree_view_new_with_model
(
GTK_TREE_MODEL
(
dialog
->
model
));
dialog
->
treeview
=
treeview
;
gtk_tree_view_set_rules_hint
(
GTK_TREE_VIEW
(
treeview
),
TRUE
);
sel
=
gtk_tree_view_get_selection
(
GTK_TREE_VIEW
(
treeview
));
gtk_tree_selection_set_mode
(
sel
,
GTK_SELECTION_MULTIPLE
);
g_signal_connect
(
G_OBJECT
(
sel
),
"changed"
,
G_CALLBACK
(
account_selected_cb
),
dialog
);
gtk_container_add
(
GTK_CONTAINER
(
sw
),
treeview
);
gtk_widget_show
(
treeview
);
add_columns
(
treeview
,
dialog
);
populate_accounts_list
(
dialog
);
/* Setup DND. I wanna be an orc! */
gtk_tree_view_enable_model_drag_source
(
GTK_TREE_VIEW
(
treeview
),
GDK_BUTTON1_MASK
,
gte
,
1
,
GDK_ACTION_COPY
);
gtk_tree_view_enable_model_drag_dest
(
GTK_TREE_VIEW
(
treeview
),
gte
,
1
,
GDK_ACTION_COPY
|
GDK_ACTION_MOVE
);
g_signal_connect
(
G_OBJECT
(
treeview
),
"drag-data-received"
,
G_CALLBACK
(
drag_data_received_cb
),
dialog
);
g_signal_connect
(
G_OBJECT
(
treeview
),
"drag-data-get"
,
G_CALLBACK
(
drag_data_get_cb
),
dialog
);
return
sw
;
}
static
void
account_page_delete_cb
(
GtkObject
*
object
,
gpointer
data
)
{
g_free
(
data
);
}
GtkWidget
*
get_account_page
()
{
GtkWidget
*
page
;
GtkWidget
*
sw
;
GtkWidget
*
label
;
AccountsWindow
*
accounts_window
;
/* Make the box */
page
=
gtk_vbox_new
(
FALSE
,
8
);
gtk_container_set_border_width
(
GTK_CONTAINER
(
page
),
12
);
accounts_window
=
g_new0
(
AccountsWindow
,
1
);
/* Setup the scrolled window that will contain the list of accounts. */
sw
=
create_accounts_list
(
accounts_window
);
gtk_box_pack_start
(
GTK_BOX
(
page
),
sw
,
TRUE
,
TRUE
,
0
);
label
=
gtk_label_new
(
_
(
"Accounts that do not support user-specified profiles are not shown"
));
gtk_box_pack_start
(
GTK_BOX
(
page
),
label
,
FALSE
,
FALSE
,
0
);
g_signal_connect
(
G_OBJECT
(
page
),
"destroy"
,
G_CALLBACK
(
account_page_delete_cb
),
accounts_window
);
return
page
;
}
/*----------------------------------------------------------------------------
* Behavior Tab
*--------------------------------------------------------------------------*/
void
ap_gtk_prefs_add_summary_option
(
GtkWidget
*
widget
)
{
pidgin_prefs_dropdown
(
widget
,
"Show AutoProfile summary window"
,
PURPLE_PREF_STRING
,
"/plugins/gtk/autoprofile/show_summary"
,
"Always"
,
"always"
,
"When away"
,
"away"
,
"Never"
,
"never"
,
NULL
);
}
static
void
set_idle_away
(
PurpleSavedStatus
*
status
)
{
purple_prefs_set_int
(
"/core/savedstatus/idleaway"
,
purple_savedstatus_get_creation_time
(
status
));
}
static
GtkWidget
*
get_behavior_page
()
{
GtkWidget
*
page
;
GtkWidget
*
label
;
GtkWidget
*
frame
,
*
vbox
,
*
hbox
;
GtkWidget
*
button
,
*
select
,
*
menu
;
GtkSizeGroup
*
sg
;
gchar
*
markup
;
/* Make the box */
page
=
gtk_vbox_new
(
FALSE
,
8
);
gtk_container_set_border_width
(
GTK_CONTAINER
(
page
),
12
);
/*---------- Update frequency ----------*/
frame
=
pidgin_make_frame
(
page
,
_
(
"Update frequency"
));
vbox
=
gtk_vbox_new
(
FALSE
,
0
);
gtk_container_add
(
GTK_CONTAINER
(
frame
),
vbox
);
pidgin_prefs_labeled_spin_button
(
vbox
,
_
(
"Minimum number of seconds between updates"
),
"/plugins/gtk/autoprofile/delay_update"
,
15
,
1000
,
NULL
);
label
=
gtk_label_new
(
""
);
markup
=
g_markup_printf_escaped
(
"<span style=
\"
italic
\"
>%s</span>"
,
_
(
"WARNING: Using values below 60 seconds may increase the frequency
\n
"
"of rate limiting errors"
));
gtk_label_set_markup
(
GTK_LABEL
(
label
),
markup
);
g_free
(
markup
);
gtk_box_pack_start
(
GTK_BOX
(
vbox
),
label
,
FALSE
,
FALSE
,
0
);
/*----------- Auto-away stuff ------------*/
frame
=
pidgin_make_frame
(
page
,
_
(
"Auto-away"
));
button
=
pidgin_prefs_checkbox
(
_
(
"Change status when idle"
),
"/plugins/gtk/autoprofile/away_when_idle"
,
frame
);
sg
=
gtk_size_group_new
(
GTK_SIZE_GROUP_HORIZONTAL
);
select
=
pidgin_prefs_labeled_spin_button
(
frame
,
_
(
"Minutes before changing status:"
),
"/core/away/mins_before_away"
,
1
,
24
*
60
,
sg
);
g_signal_connect
(
G_OBJECT
(
button
),
"clicked"
,
G_CALLBACK
(
pidgin_toggle_sensitive
),
select
);
hbox
=
gtk_hbox_new
(
FALSE
,
0
);
gtk_container_add
(
GTK_CONTAINER
(
frame
),
hbox
);
label
=
gtk_label_new_with_mnemonic
(
_
(
"Change status to:"
));
gtk_size_group_add_widget
(
sg
,
label
);
gtk_misc_set_alignment
(
GTK_MISC
(
label
),
0
,
0.5
);
g_signal_connect
(
G_OBJECT
(
button
),
"clicked"
,
G_CALLBACK
(
pidgin_toggle_sensitive
),
label
);
gtk_box_pack_start
(
GTK_BOX
(
hbox
),
label
,
FALSE
,
FALSE
,
0
);
/* TODO: Show something useful if we don't have any saved statuses. */
menu
=
pidgin_status_menu
(
purple_savedstatus_get_idleaway
(),
G_CALLBACK
(
set_idle_away
));
gtk_box_pack_start
(
GTK_BOX
(
frame
),
menu
,
FALSE
,
FALSE
,
0
);
g_signal_connect
(
G_OBJECT
(
button
),
"clicked"
,
G_CALLBACK
(
pidgin_toggle_sensitive
),
menu
);
gtk_label_set_mnemonic_widget
(
GTK_LABEL
(
label
),
menu
);
if
(
!
purple_prefs_get_bool
(
"/plugins/gtk/autoprofile/away_when_idle"
))
{
gtk_widget_set_sensitive
(
GTK_WIDGET
(
menu
),
FALSE
);
gtk_widget_set_sensitive
(
GTK_WIDGET
(
select
),
FALSE
);
gtk_widget_set_sensitive
(
GTK_WIDGET
(
label
),
FALSE
);
}
return
page
;
}
/*----------------------------------------------------------------------------
* Auto-reply Tab
*--------------------------------------------------------------------------*/
/* Update string arguments */
static
gboolean
update_behavior_string
(
GtkWidget
*
widget
,
GdkEventFocus
*
evt
,
gpointer
data
)
{
ap_debug
(
"preferences"
,
"behavior string preference modified"
);
if
(
!
strcmp
(
data
,
"text_trigger"
))
{
purple_prefs_set_string
(
"/plugins/gtk/autoprofile/autorespond/trigger"
,
gtk_entry_get_text
(
GTK_ENTRY
(
widget
)));
}
else
if
(
!
strcmp
(
data
,
"text_respond"
))
{
purple_prefs_set_string
(
"/plugins/gtk/autoprofile/autorespond/text"
,
gtk_entry_get_text
(
GTK_ENTRY
(
widget
)));
}
else
{
ap_debug_error
(
"preferences"
,
"invalid data argument to string update"
);
}
return
FALSE
;
}
/* Update value returned from spinner for auto-respond delay */
static
gboolean
update_delay_respond
(
GtkWidget
*
widget
,
GdkEventFocus
*
evt
,
gpointer
data
)
{
purple_prefs_set_int
(
"/plugins/gtk/autoprofile/delay_respond"
,
gtk_spin_button_get_value_as_int
(
GTK_SPIN_BUTTON
(
widget
)));
return
FALSE
;
}
static
GtkWidget
*
get_autoreply_page
()
{
GtkWidget
*
page
;
GtkWidget
*
label
,
*
checkbox
,
*
spinner
,
*
entry
;
GtkWidget
*
frame
,
*
vbox
,
*
large_vbox
,
*
hbox
;
GtkWidget
*
dd
;
GtkSizeGroup
*
sg
;
/* Make the box */
page
=
gtk_vbox_new
(
FALSE
,
8
);
gtk_container_set_border_width
(
GTK_CONTAINER
(
page
),
12
);
frame
=
pidgin_make_frame
(
page
,
_
(
"General"
));
dd
=
pidgin_prefs_dropdown
(
frame
,
_
(
"Auto-reply:"
),
PURPLE_PREF_STRING
,
"/plugins/gtk/autoprofile/autorespond/auto_reply"
,
_
(
"Never"
),
"never"
,
_
(
"When away"
),
"away"
,
_
(
"When both away and idle"
),
"awayidle"
,
NULL
);
sg
=
gtk_size_group_new
(
GTK_SIZE_GROUP_HORIZONTAL
);
gtk_size_group_add_widget
(
sg
,
dd
);
gtk_misc_set_alignment
(
GTK_MISC
(
dd
),
0
,
0.5
);
/*---------- Auto-responses ----------*/
frame
=
pidgin_make_frame
(
page
,
_
(
"Dynamic auto-responses"
));
vbox
=
gtk_vbox_new
(
FALSE
,
5
);
gtk_container_add
(
GTK_CONTAINER
(
frame
),
vbox
);
/* Auto-response activated */
checkbox
=
pidgin_prefs_checkbox
(
_
(
"Allow users to request more auto-responses"
),
"/plugins/gtk/autoprofile/autorespond/enable"
,
vbox
);
large_vbox
=
gtk_vbox_new
(
FALSE
,
5
);
gtk_box_pack_start
(
GTK_BOX
(
vbox
),
large_vbox
,
FALSE
,
FALSE
,
0
);
/* Auto-response delay */
hbox
=
gtk_hbox_new
(
FALSE
,
5
);
gtk_box_pack_start
(
GTK_BOX
(
large_vbox
),
hbox
,
FALSE
,
FALSE
,
0
);
label
=
gtk_label_new
(
_
(
"Delay"
));
gtk_box_pack_start
(
GTK_BOX
(
hbox
),
label
,
FALSE
,
FALSE
,
0
);
spinner
=
gtk_spin_button_new_with_range
(
1
,
G_MAXINT
,
1
);
gtk_box_pack_start
(
GTK_BOX
(
hbox
),
spinner
,
TRUE
,
TRUE
,
0
);
label
=
gtk_label_new
(
_
(
"seconds between auto-responses"
));
gtk_box_pack_start
(
GTK_BOX
(
hbox
),
label
,
FALSE
,
FALSE
,
0
);
gtk_spin_button_set_value
(
GTK_SPIN_BUTTON
(
spinner
),
purple_prefs_get_int
(
"/plugins/gtk/autoprofile/autorespond/delay"
));
g_signal_connect
(
G_OBJECT
(
spinner
),
"value-changed"
,
G_CALLBACK
(
update_delay_respond
),
NULL
);
/* Auto-response message string */
label
=
gtk_label_new
(
_
(
"Message sent with first autoresponse:"
));
gtk_box_pack_start
(
GTK_BOX
(
large_vbox
),
label
,
FALSE
,
FALSE
,
0
);
gtk_misc_set_alignment
(
GTK_MISC
(
label
),
0
,
0
);
entry
=
gtk_entry_new
();
gtk_box_pack_start
(
GTK_BOX
(
large_vbox
),
entry
,
FALSE
,
FALSE
,
0
);
gtk_entry_set_max_length
(
GTK_ENTRY
(
entry
),
100
);
gtk_entry_set_text
(
GTK_ENTRY
(
entry
),
purple_prefs_get_string
(
"/plugins/gtk/autoprofile/autorespond/text"
));
g_signal_connect
(
G_OBJECT
(
entry
),
"focus-out-event"
,
G_CALLBACK
(
update_behavior_string
),
"text_respond"
);
label
=
gtk_label_new
(
_
(
"Request trigger message:"
));
gtk_box_pack_start
(
GTK_BOX
(
large_vbox
),
label
,
FALSE
,
FALSE
,
0
);
gtk_misc_set_alignment
(
GTK_MISC
(
label
),
0
,
0
);
entry
=
gtk_entry_new
();
gtk_box_pack_start
(
GTK_BOX
(
large_vbox
),
entry
,
FALSE
,
FALSE
,
0
);
gtk_entry_set_max_length
(
GTK_ENTRY
(
entry
),
50
);
gtk_entry_set_text
(
GTK_ENTRY
(
entry
),
purple_prefs_get_string
(
"/plugins/gtk/autoprofile/autorespond/trigger"
));
g_signal_connect
(
G_OBJECT
(
entry
),
"focus-out-event"
,
G_CALLBACK
(
update_behavior_string
),
"text_trigger"
);
/* Sensitivity signals */
g_signal_connect
(
G_OBJECT
(
checkbox
),
"clicked"
,
G_CALLBACK
(
pidgin_toggle_sensitive
),
large_vbox
);
if
(
!
purple_prefs_get_bool
(
"/plugins/gtk/autoprofile/autorespond/enable"
))
{
gtk_widget_set_sensitive
(
large_vbox
,
FALSE
);
}
else
{
gtk_widget_set_sensitive
(
large_vbox
,
TRUE
);
}
return
page
;
}
/*----------------------------------------------------------------------------
* Menu as a whole
*--------------------------------------------------------------------------*/
static
GtkWidget
*
get_config_frame
(
PurplePlugin
*
plugin
)
{
GtkWidget
*
info
=
get_info_page
();
gtk_widget_set_size_request
(
info
,
350
,
400
);
return
info
;
}
static
void
dialog_cb
(
GtkDialog
*
dialog
,
gint
arg1
,
gpointer
user_data
)
{
gtk_widget_destroy
((
GtkWidget
*
)
dialog
);
}
void
ap_preferences_display
()
{
GtkWidget
*
dialog
,
*
notebook
;
notebook
=
gtk_notebook_new
();
gtk_notebook_append_page
(
GTK_NOTEBOOK
(
notebook
),
get_behavior_page
(),
gtk_label_new
(
_
(
"General"
)));
gtk_notebook_append_page
(
GTK_NOTEBOOK
(
notebook
),
get_account_page
(),
gtk_label_new
(
_
(
"User info/profiles"
)));
gtk_notebook_append_page
(
GTK_NOTEBOOK
(
notebook
),
get_autoreply_page
(),
gtk_label_new
(
_
(
"Auto-reply"
)));
g_object_set
(
notebook
,
"homogeneous"
,
TRUE
,
NULL
);
dialog
=
gtk_dialog_new_with_buttons
(
PIDGIN_ALERT_TITLE
,
NULL
,
GTK_DIALOG_NO_SEPARATOR
,
GTK_STOCK_CLOSE
,
GTK_RESPONSE_CLOSE
,
NULL
);
gtk_container_add
(
GTK_CONTAINER
(
GTK_DIALOG
(
dialog
)
->
vbox
),
notebook
);
gtk_window_set_default_size
(
GTK_WINDOW
(
dialog
),
400
,
400
);
gtk_widget_show_all
(
dialog
);
g_signal_connect
(
G_OBJECT
(
dialog
),
"response"
,
G_CALLBACK
(
dialog_cb
),
dialog
);
}
/*--------------- Generate the preference widget once ----------------*/
PidginPluginUiInfo
ui_info
=
{
get_config_frame
};