qulogic/pidgin
Clone
Summary
Browse
Changes
Graph
Update a bunch of gettext stuff
8 months ago, Gary Kramlich
c2cb3f628555
Update a bunch of gettext stuff
Add support for a PURPLE_LOCALE_DIR environment variable so we can set the
locale directory in a dev environment.
Added purple_get_locale_dir() which will check the environment variable or
fallback to PURPLE_LOCALE_DIR.
Removed the old PACKAGE and PACKAGE_NAME constants and replaced them with
GETTEXT_PACKAGE which is much more self explanatory.
Testing Done:
Compiled with finch enabled and verified no issues.
Reviewed at https://reviews.imfreedom.org/r/2759/
/*
* Purple - Internet Messaging Library
* Copyright (C) Pidgin Developers <devel@pidgin.im>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, see <https://www.gnu.org/licenses/>.
*/
#include
"purplechatconversation.h"
#include
"purpleconversationmanager.h"
#include
"purpleimconversation.h"
#include
"purpleprivate.h"
enum
{
SIG_REGISTERED
,
SIG_UNREGISTERED
,
SIG_CONVERSATION_CHANGED
,
N_SIGNALS
,
};
static
guint
signals
[
N_SIGNALS
]
=
{
0
,
};
struct
_PurpleConversationManager
{
GObject
parent
;
GHashTable
*
conversations
;
};
static
PurpleConversationManager
*
default_manager
=
NULL
;
G_DEFINE_TYPE
(
PurpleConversationManager
,
purple_conversation_manager
,
G_TYPE_OBJECT
)
typedef
gboolean
(
*
PurpleConversationManagerCompareFunc
)(
PurpleConversation
*
conversation
,
gpointer
userdata
);
/******************************************************************************
* Helpers
*****************************************************************************/
static
gboolean
purple_conversation_is_im
(
PurpleConversation
*
conversation
,
G_GNUC_UNUSED
gpointer
userdata
)
{
return
PURPLE_IS_IM_CONVERSATION
(
conversation
);
}
static
gboolean
purple_conversation_is_chat
(
PurpleConversation
*
conversation
,
G_GNUC_UNUSED
gpointer
userdata
)
{
return
PURPLE_IS_CHAT_CONVERSATION
(
conversation
);
}
static
gboolean
purple_conversation_chat_has_id
(
PurpleConversation
*
conversation
,
gpointer
userdata
)
{
PurpleChatConversation
*
chat
=
NULL
;
gint
id
=
GPOINTER_TO_INT
(
userdata
);
if
(
!
PURPLE_IS_CHAT_CONVERSATION
(
conversation
))
{
return
FALSE
;
}
chat
=
PURPLE_CHAT_CONVERSATION
(
conversation
);
return
(
purple_chat_conversation_get_id
(
chat
)
==
id
);
}
static
gboolean
purple_conversation_has_id
(
PurpleConversation
*
conversation
,
gpointer
data
)
{
const
char
*
needle
=
data
;
const
char
*
haystack
=
NULL
;
if
(
!
PURPLE_IS_CONVERSATION
(
conversation
))
{
return
FALSE
;
}
haystack
=
purple_conversation_get_id
(
conversation
);
return
purple_strequal
(
needle
,
haystack
);
}
static
PurpleConversation
*
purple_conversation_manager_find_internal
(
PurpleConversationManager
*
manager
,
PurpleAccount
*
account
,
const
gchar
*
name
,
PurpleConversationManagerCompareFunc
func
,
gpointer
userdata
)
{
GHashTableIter
iter
;
gpointer
key
;
g_return_val_if_fail
(
PURPLE_IS_ACCOUNT
(
account
),
NULL
);
g_hash_table_iter_init
(
&
iter
,
manager
->
conversations
);
while
(
g_hash_table_iter_next
(
&
iter
,
&
key
,
NULL
))
{
PurpleConversation
*
conversation
=
PURPLE_CONVERSATION
(
key
);
if
(
name
!=
NULL
)
{
const
gchar
*
conv_name
=
purple_conversation_get_name
(
conversation
);
if
(
!
purple_strequal
(
conv_name
,
name
))
{
continue
;
}
}
if
(
purple_conversation_get_account
(
conversation
)
!=
account
)
{
continue
;
}
if
(
func
!=
NULL
&&
!
func
(
conversation
,
userdata
))
{
continue
;
}
return
conversation
;
}
return
NULL
;
}
/******************************************************************************
* Callbacks
*****************************************************************************/
/* This callback propagates the notify signal from conversations. */
static
void
purple_conversation_manager_conversation_changed_cb
(
GObject
*
source
,
GParamSpec
*
pspec
,
gpointer
data
)
{
g_signal_emit
(
data
,
signals
[
SIG_CONVERSATION_CHANGED
],
g_param_spec_get_name_quark
(
pspec
),
source
,
pspec
);
}
/******************************************************************************
* GObject Implementation
*****************************************************************************/
static
void
purple_conversation_manager_init
(
PurpleConversationManager
*
manager
)
{
manager
->
conversations
=
g_hash_table_new_full
(
g_direct_hash
,
g_direct_equal
,
g_object_unref
,
NULL
);
}
static
void
purple_conversation_manager_finalize
(
GObject
*
obj
)
{
PurpleConversationManager
*
manager
=
PURPLE_CONVERSATION_MANAGER
(
obj
);
g_hash_table_destroy
(
manager
->
conversations
);
G_OBJECT_CLASS
(
purple_conversation_manager_parent_class
)
->
finalize
(
obj
);
}
static
void
purple_conversation_manager_class_init
(
PurpleConversationManagerClass
*
klass
)
{
GObjectClass
*
obj_class
=
G_OBJECT_CLASS
(
klass
);
obj_class
->
finalize
=
purple_conversation_manager_finalize
;
/**
* PurpleConversationManager::registered:
* @manager: The manager.
* @conversation: The conversation that was registered.
*
* Emitted after @conversation has been registered with @manager.
*
* Since: 3.0.0
*/
signals
[
SIG_REGISTERED
]
=
g_signal_new_class_handler
(
"registered"
,
G_OBJECT_CLASS_TYPE
(
klass
),
G_SIGNAL_RUN_LAST
,
NULL
,
NULL
,
NULL
,
NULL
,
G_TYPE_NONE
,
1
,
PURPLE_TYPE_CONVERSATION
);
/**
* PurpleConversationManager::unregistered:
* @manager: The manager.
* @conversation: The conversation that was unregistered.
*
* Emitted after @conversation has been unregistered from @manager.
*
* Since: 3.0.0
*/
signals
[
SIG_UNREGISTERED
]
=
g_signal_new_class_handler
(
"unregistered"
,
G_OBJECT_CLASS_TYPE
(
klass
),
G_SIGNAL_RUN_LAST
,
NULL
,
NULL
,
NULL
,
NULL
,
G_TYPE_NONE
,
1
,
PURPLE_TYPE_CONVERSATION
);
/**
* PurpleConversationManager::conversation-changed:
* @manager: The account manager instance.
* @conversation: The conversation that was changed.
* @pspec: The [class@GObject.ParamSpec] for the property that changed.
*
* This is a propagation of the notify signal from @conversation. This
* means that your callback will be called for any conversation that
* @manager knows about.
*
* This also supports details, so you can specify the signal name as
* something like `conversation-changed::title` and your callback will only
* be called when [property@Conversation:title] has been changed.
*
* Since: 3.0.0
*/
signals
[
SIG_CONVERSATION_CHANGED
]
=
g_signal_new_class_handler
(
"conversation-changed"
,
G_OBJECT_CLASS_TYPE
(
klass
),
G_SIGNAL_RUN_LAST
|
G_SIGNAL_DETAILED
,
NULL
,
NULL
,
NULL
,
NULL
,
G_TYPE_NONE
,
2
,
PURPLE_TYPE_CONVERSATION
,
G_TYPE_PARAM
);
}
/******************************************************************************
* Private API
*****************************************************************************/
void
purple_conversation_manager_startup
(
void
)
{
if
(
default_manager
==
NULL
)
{
default_manager
=
g_object_new
(
PURPLE_TYPE_CONVERSATION_MANAGER
,
NULL
);
}
}
void
purple_conversation_manager_shutdown
(
void
)
{
g_clear_object
(
&
default_manager
);
}
/******************************************************************************
* Public API
*****************************************************************************/
PurpleConversationManager
*
purple_conversation_manager_get_default
(
void
)
{
return
default_manager
;
}
gboolean
purple_conversation_manager_register
(
PurpleConversationManager
*
manager
,
PurpleConversation
*
conversation
)
{
gboolean
registered
=
FALSE
;
g_return_val_if_fail
(
PURPLE_IS_CONVERSATION_MANAGER
(
manager
),
FALSE
);
g_return_val_if_fail
(
PURPLE_IS_CONVERSATION
(
conversation
),
FALSE
);
/* g_hash_table_add calls the key_destroy_func if the key already exists
* which means we don't need to worry about the reference we're creating
* during the addition.
*/
registered
=
g_hash_table_add
(
manager
->
conversations
,
g_object_ref
(
conversation
));
if
(
registered
)
{
/* Register our signals that need to be propagated. */
g_signal_connect_object
(
conversation
,
"notify"
,
G_CALLBACK
(
purple_conversation_manager_conversation_changed_cb
),
manager
,
0
);
/* Tell everyone about the new conversation. */
g_signal_emit
(
manager
,
signals
[
SIG_REGISTERED
],
0
,
conversation
);
}
return
registered
;
}
gboolean
purple_conversation_manager_unregister
(
PurpleConversationManager
*
manager
,
PurpleConversation
*
conversation
)
{
gboolean
unregistered
=
FALSE
;
g_return_val_if_fail
(
PURPLE_IS_CONVERSATION_MANAGER
(
manager
),
FALSE
);
g_return_val_if_fail
(
PURPLE_IS_CONVERSATION
(
conversation
),
FALSE
);
unregistered
=
g_hash_table_remove
(
manager
->
conversations
,
conversation
);
if
(
unregistered
)
{
/* Disconnect all the signals we added for propagation. */
g_signal_handlers_disconnect_by_func
(
conversation
,
purple_conversation_manager_conversation_changed_cb
,
manager
);
/* Tell everyone about the unregistered conversation. */
g_signal_emit
(
manager
,
signals
[
SIG_UNREGISTERED
],
0
,
conversation
);
}
return
unregistered
;
}
gboolean
purple_conversation_manager_is_registered
(
PurpleConversationManager
*
manager
,
PurpleConversation
*
conversation
)
{
g_return_val_if_fail
(
PURPLE_IS_CONVERSATION_MANAGER
(
manager
),
FALSE
);
g_return_val_if_fail
(
PURPLE_IS_CONVERSATION
(
conversation
),
FALSE
);
return
g_hash_table_contains
(
manager
->
conversations
,
conversation
);
}
void
purple_conversation_manager_foreach
(
PurpleConversationManager
*
manager
,
PurpleConversationManagerForeachFunc
func
,
gpointer
data
)
{
GHashTableIter
iter
;
gpointer
key
;
g_return_if_fail
(
PURPLE_IS_CONVERSATION_MANAGER
(
manager
));
g_return_if_fail
(
func
!=
NULL
);
g_hash_table_iter_init
(
&
iter
,
manager
->
conversations
);
while
(
g_hash_table_iter_next
(
&
iter
,
&
key
,
NULL
))
{
func
(
PURPLE_CONVERSATION
(
key
),
data
);
}
}
GList
*
purple_conversation_manager_get_all
(
PurpleConversationManager
*
manager
)
{
g_return_val_if_fail
(
PURPLE_IS_CONVERSATION_MANAGER
(
manager
),
NULL
);
return
g_hash_table_get_keys
(
manager
->
conversations
);
}
PurpleConversation
*
purple_conversation_manager_find
(
PurpleConversationManager
*
manager
,
PurpleAccount
*
account
,
const
gchar
*
name
)
{
g_return_val_if_fail
(
PURPLE_IS_CONVERSATION_MANAGER
(
manager
),
NULL
);
g_return_val_if_fail
(
PURPLE_IS_ACCOUNT
(
account
),
NULL
);
g_return_val_if_fail
(
name
!=
NULL
,
NULL
);
return
purple_conversation_manager_find_internal
(
manager
,
account
,
name
,
NULL
,
NULL
);
}
PurpleConversation
*
purple_conversation_manager_find_im
(
PurpleConversationManager
*
manager
,
PurpleAccount
*
account
,
const
gchar
*
name
)
{
g_return_val_if_fail
(
PURPLE_IS_CONVERSATION_MANAGER
(
manager
),
NULL
);
g_return_val_if_fail
(
PURPLE_IS_ACCOUNT
(
account
),
NULL
);
g_return_val_if_fail
(
name
!=
NULL
,
NULL
);
return
purple_conversation_manager_find_internal
(
manager
,
account
,
name
,
purple_conversation_is_im
,
NULL
);
}
PurpleConversation
*
purple_conversation_manager_find_chat
(
PurpleConversationManager
*
manager
,
PurpleAccount
*
account
,
const
gchar
*
name
)
{
g_return_val_if_fail
(
PURPLE_IS_CONVERSATION_MANAGER
(
manager
),
NULL
);
g_return_val_if_fail
(
PURPLE_IS_ACCOUNT
(
account
),
NULL
);
g_return_val_if_fail
(
name
!=
NULL
,
NULL
);
return
purple_conversation_manager_find_internal
(
manager
,
account
,
name
,
purple_conversation_is_chat
,
NULL
);
}
PurpleConversation
*
purple_conversation_manager_find_chat_by_id
(
PurpleConversationManager
*
manager
,
PurpleAccount
*
account
,
gint
id
)
{
g_return_val_if_fail
(
PURPLE_IS_CONVERSATION_MANAGER
(
manager
),
NULL
);
g_return_val_if_fail
(
PURPLE_IS_ACCOUNT
(
account
),
NULL
);
return
purple_conversation_manager_find_internal
(
manager
,
account
,
NULL
,
purple_conversation_chat_has_id
,
GINT_TO_POINTER
(
id
));
}
PurpleConversation
*
purple_conversation_manager_find_with_id
(
PurpleConversationManager
*
manager
,
PurpleAccount
*
account
,
const
char
*
id
)
{
g_return_val_if_fail
(
PURPLE_IS_CONVERSATION_MANAGER
(
manager
),
NULL
);
g_return_val_if_fail
(
PURPLE_IS_ACCOUNT
(
account
),
NULL
);
return
purple_conversation_manager_find_internal
(
manager
,
account
,
NULL
,
purple_conversation_has_id
,
(
gpointer
)
id
);
}