void Gobby::UserJoin::on_user_join_finished(InfUser* user, const GError* error) { if(m_request != NULL) { g_signal_handlers_disconnect_by_func( G_OBJECT(m_request), (gpointer)G_CALLBACK(on_user_join_finished_static), this); g_object_unref(m_request); m_request = NULL; } if(error == NULL) { user_join_complete(user, error); } else if(error->domain == inf_user_error_quark() && error->code == INF_USER_ERROR_NAME_IN_USE) { // If name is in use retry with alternative user name ++m_retry_index; attempt_user_join(); } else { user_join_complete(user, error); } }
void Gobby::UserJoinCommands::UserJoinInfo:: on_user_join_finished(InfUser* user, const GError* error) { if(m_request != NULL) { g_object_unref(m_request); m_request = NULL; } if(error == NULL) { user_join_complete(user); } else if(error->domain == inf_user_error_quark() && error->code == INF_USER_ERROR_NAME_IN_USE) { // If name is in use retry with alternative user name ++m_retry_index; attempt_user_join(); } else if(error->domain == inf_request_error_quark() && error->code == INF_REQUEST_ERROR_NOT_AUTHORIZED) { set_permission_denied_text(m_view); finish(); } else { set_error_text(m_view, error->message); finish(); } }
/** * inf_user_status_from_string: * @string: A string representation of a #InfUserStatus. * @status: A pointer to a #InfUserStatus value, or %NULL. * @error: Location to store error information, if any. * * This function does the opposite of inf_user_status_to_string(). It turns * the given string back to a #InfUserStatus, storing the result in @status * if @status is non-%NULL. If @string is invalid, then @status is left * untouched, @error is set and %FALSE is returned. Otherwise, the function * returns %TRUE. * * Returns: When an error occured during the conversion, %FALSE is returned, * and %TRUE otherwise. */ gboolean inf_user_status_from_string(const gchar* string, InfUserStatus* status, GError** error) { InfUserStatus tmp_status; if(strcmp(string, "active") == 0) tmp_status = INF_USER_ACTIVE; else if(strcmp(string, "inactive") == 0) tmp_status = INF_USER_INACTIVE; else if(strcmp(string, "unavailable") == 0) tmp_status = INF_USER_UNAVAILABLE; else { g_set_error( error, inf_user_error_quark(), INF_USER_ERROR_INVALID_STATUS, _("Invalid user status: '%s'"), string ); return FALSE; } if(status) *status = tmp_status; return TRUE; }
static void on_join_failed(InfcRequest* request, const GError* error, gpointer user_data) { InfTestGtkBrowserWindow* test; gchar* new_name; test = (InfTestGtkBrowserWindow*)user_data; if(error->domain == inf_user_error_quark() && error->code == INF_USER_ERROR_NAME_IN_USE) { new_name = g_strdup_printf("%s%d", g_get_user_name(), 2); request_join(test, new_name); g_free(new_name); } else { set_error(test, "User join failed", error->message); } }
static GError* infc_session_proxy_translate_error_impl(InfcSessionProxy* proxy, GQuark domain, guint code) { GError* error; const gchar* error_msg; if(domain == inf_request_error_quark()) error_msg = inf_request_strerror(code); else if(domain == inf_user_error_quark()) error_msg = inf_user_strerror(code); else error_msg = NULL; error = NULL; if(error_msg != NULL) { g_set_error(&error, domain, code, "%s", error_msg); } else { /* TODO: Check whether a human-readable error string was sent (that * we cannot translate then, of course). */ g_set_error( &error, inf_request_error_quark(), INF_REQUEST_ERROR_UNKNOWN_DOMAIN, _("Error comes from unknown error domain '%s' (code %u)"), g_quark_to_string(domain), (guint)code ); } return error; }
static void on_join_user_request_failed (InfcRequest *request, const GError *error, gpointer data) { if (error->domain == inf_user_error_quark () && error->code == INF_USER_ERROR_NAME_IN_USE) { gchar *new_name; ChatData *cdata = (ChatData *)data; new_name = gedit_collaboration_generate_new_name ( cdata->user, &cdata->name_failed_counter); request_join (cdata, new_name); g_free (new_name); } else if (error) { g_warning ("%s", error->message); } }
static InfCommunicationScope inf_adopted_session_process_xml_run(InfSession* session, InfXmlConnection* connection, const xmlNodePtr xml, GError** error) { InfAdoptedSessionPrivate* priv; InfAdoptedSessionClass* session_class; InfAdoptedRequest* request; InfAdoptedUser* user; gboolean has_num; guint num; GError* local_error; InfAdoptedRequest* copy_req; guint i; priv = INF_ADOPTED_SESSION_PRIVATE(session); if(strcmp((const char*)xml->name, "request") == 0) { session_class = INF_ADOPTED_SESSION_GET_CLASS(session); g_assert(session_class->xml_to_request != NULL); user = inf_adopted_session_user_from_request_xml( INF_ADOPTED_SESSION(session), xml, error ); if(user == NULL) return INF_COMMUNICATION_SCOPE_PTP; if(inf_user_get_status(INF_USER(user)) == INF_USER_UNAVAILABLE || inf_user_get_connection(INF_USER(user)) != connection) { g_set_error( error, inf_user_error_quark(), INF_USER_ERROR_NOT_JOINED, "%s", _("User did not join from this connection") ); return INF_COMMUNICATION_SCOPE_PTP; } local_error = NULL; has_num = inf_xml_util_get_attribute_uint(xml, "num", &num, &local_error); if(local_error != NULL) { g_propagate_error(error, local_error); return INF_COMMUNICATION_SCOPE_PTP; } request = session_class->xml_to_request( INF_ADOPTED_SESSION(session), xml, inf_adopted_user_get_vector(user), FALSE, error ); if(request == NULL) return INF_COMMUNICATION_SCOPE_PTP; inf_adopted_algorithm_receive_request(priv->algorithm, request); /* Apply the request more than once if num is given. This is mostly used * for multiple undos and redos, but is in general allowed for any * request. */ if(has_num) { for(i = 1; i < num; ++i) { /* TODO: This is a bit of a hack since requests are normally * immutable. It avoids an additional vector copy here though. */ copy_req = inf_adopted_request_copy(request); inf_adopted_state_vector_add( inf_adopted_request_get_vector(copy_req), inf_user_get_id(INF_USER(user)), i ); inf_adopted_algorithm_receive_request(priv->algorithm, copy_req); g_object_unref(copy_req); } } g_object_unref(request); /* Requests can always be forwarded since user is given. */ return INF_COMMUNICATION_SCOPE_GROUP; } return INF_SESSION_CLASS(parent_class)->process_xml_run( session, connection, xml, error ); }
static gboolean infc_session_proxy_handle_user_rejoin(InfcSessionProxy* proxy, InfXmlConnection* connection, xmlNodePtr xml, GError** error) { InfcSessionProxyPrivate* priv; InfSessionClass* session_class; GArray* array; InfUser* user; const GParameter* idparam; GParameter* param; guint id; gboolean result; guint i; priv = INFC_SESSION_PROXY_PRIVATE(proxy); session_class = INF_SESSION_GET_CLASS(priv->session); array = session_class->get_xml_user_props(priv->session, connection, xml); /* Find rejoining user first */ idparam = inf_session_lookup_user_property( (const GParameter*)array->data, array->len, "id" ); if(idparam == NULL) { g_set_error( error, inf_request_error_quark(), INF_REQUEST_ERROR_NO_SUCH_ATTRIBUTE, _("Request does not contain required attribute 'id'") ); goto error; } id = g_value_get_uint(&idparam->value); user = inf_user_table_lookup_user_by_id( inf_session_get_user_table(priv->session), id ); if(user == NULL) { g_set_error( error, inf_user_error_quark(), INF_USER_ERROR_NO_SUCH_USER, _("No such user with ID %u"), id ); goto error; } /* Set local flag if the join was requested by us (seq is present in * server response). */ param = inf_session_get_user_property(array, "flags"); g_assert(!G_IS_VALUE(¶m->value)); /* must not have been set already */ g_value_init(¶m->value, INF_TYPE_USER_FLAGS); if(xmlHasProp(xml, (const xmlChar*)"seq") != NULL) g_value_set_flags(¶m->value, INF_USER_LOCAL); else g_value_set_flags(¶m->value, 0); /* Set connection. If none was given, use publisher connection */ param = inf_session_get_user_property(array, "connection"); if(!G_IS_VALUE(¶m->value)) { g_value_init(¶m->value, INF_TYPE_XML_CONNECTION); g_value_set_object(¶m->value, G_OBJECT(connection)); } result = session_class->validate_user_props( priv->session, (const GParameter*)array->data, array->len, user, error ); if(result == FALSE) goto error; /* Set properties on the found user object, performing the rejoin */ g_object_freeze_notify(G_OBJECT(user)); for(i = 0; i < array->len; ++ i) { param = &g_array_index(array, GParameter, i); /* Don't set ID because the ID is the same anyway (we did the user lookup * by it). The "id" property is construct only anyway. */ if(strcmp(param->name, "id") != 0) g_object_set_property(G_OBJECT(user), param->name, ¶m->value); } /* TODO: Set user status to available, if the server did not send the * status property? Require the status property being set on a rejoin? * Make sure it is not unavailable? */ g_object_thaw_notify(G_OBJECT(user)); for(i = 0; i < array->len; ++ i) g_value_unset(&g_array_index(array, GParameter, i).value); g_array_free(array, TRUE); infc_session_proxy_succeed_user_request(proxy, xml, user); return TRUE; error: for(i = 0; i < array->len; ++ i) g_value_unset(&g_array_index(array, GParameter, i).value); g_array_free(array, TRUE); return FALSE; }