static gboolean perform_test(guint max_total_log_size, InfTextChunk* initial, GSList* users, GSList* requests, GError** error) { InfTextBuffer* buffer; InfCommunicationManager* manager; InfIo* io; InfTextSession* session; InfAdoptedAlgorithm* algorithm; InfUserTable* user_table; InfTextUser* user; gchar* user_name; GSList* item; xmlNodePtr request; gboolean result; GError* local_error; guint verify_user_id; InfAdoptedUser* verify_user; guint verify_log_size; gint verify_can_undo; gint verify_can_redo; InfAdoptedRequestLog* log; guint log_size; buffer = INF_TEXT_BUFFER(inf_text_default_buffer_new("UTF-8")); inf_text_buffer_insert_chunk(buffer, 0, initial, NULL); manager = inf_communication_manager_new(); io = INF_IO(inf_standalone_io_new()); user_table = inf_user_table_new(); local_error = NULL; for(item = users; item != NULL; item = g_slist_next(item)) { user_name = g_strdup_printf("User_%u", GPOINTER_TO_UINT(item->data)); user = INF_TEXT_USER( g_object_new( INF_TEXT_TYPE_USER, "id", GPOINTER_TO_UINT(item->data), "name", user_name, "status", INF_USER_ACTIVE, "flags", 0, NULL ) ); g_free(user_name); inf_user_table_add_user(user_table, INF_USER(user)); g_object_unref(user); } session = INF_TEXT_SESSION( g_object_new( INF_TEXT_TYPE_SESSION, "communication-manager", manager, "buffer", buffer, "io", io, "user_table", user_table, "max-total-log-size", max_total_log_size, NULL ) ); algorithm = inf_adopted_session_get_algorithm(INF_ADOPTED_SESSION(session)); g_object_unref(io); g_object_unref(manager); g_object_unref(user_table); g_object_unref(buffer); for(item = requests; item != NULL; item = item->next) { request = (xmlNodePtr)item->data; if(strcmp((const char*)request->name, "request") == 0) { /* Request */ result = inf_communication_object_received( INF_COMMUNICATION_OBJECT(session), NULL, request, &local_error ); if(local_error != NULL) goto fail; } else { /* TODO: Make an extra function out of this: */ /* Verify */ result = inf_xml_util_get_attribute_uint_required( request, "user", &verify_user_id, &local_error ); if(result == FALSE) goto fail; verify_user = INF_ADOPTED_USER( inf_user_table_lookup_user_by_id(user_table, verify_user_id) ); if(verify_user == NULL) { g_set_error( error, inf_test_text_cleanup_error_quark(), INF_TEST_TEXT_CLEANUP_USER_UNAVAILABLE, "User ID '%u' not available", verify_user_id ); goto fail; } result = inf_xml_util_get_attribute_uint( request, "log-size", &verify_log_size, &local_error ); if(local_error) goto fail; if(result) { log = inf_adopted_user_get_request_log(INF_ADOPTED_USER(verify_user)); log_size = inf_adopted_request_log_get_end(log) - inf_adopted_request_log_get_begin(log); if(verify_log_size != log_size) { g_set_error( error, inf_test_text_cleanup_error_quark(), INF_TEST_TEXT_CLEANUP_VERIFY_FAILED, "Log size does not match; got %u, but expected %u", log_size, verify_log_size ); goto fail; } } result = inf_xml_util_get_attribute_int( request, "can-undo", &verify_can_undo, &local_error ); if(local_error) goto fail; if(result) { result = inf_adopted_algorithm_can_undo(algorithm, verify_user); if(result != verify_can_undo) { g_set_error( error, inf_test_text_cleanup_error_quark(), INF_TEST_TEXT_CLEANUP_VERIFY_FAILED, "can-undo does not match; got %d, but expected %d", (guint)result, verify_can_undo ); goto fail; } } result = inf_xml_util_get_attribute_int( request, "can-redo", &verify_can_redo, &local_error ); if(local_error) goto fail; if(result) { result = inf_adopted_algorithm_can_redo(algorithm, verify_user); if(result != verify_can_redo) { g_set_error( error, inf_test_text_cleanup_error_quark(), INF_TEST_TEXT_CLEANUP_VERIFY_FAILED, "can-redo does not match; got %d, but expected %d", (guint)result, verify_can_redo ); goto fail; } } } } g_object_unref(session); return TRUE; fail: g_object_unref(session); if(local_error) g_propagate_error(error, local_error); return FALSE; }
void Gobby::OperationOpen::read_finish() { // If the last character is a newline character, remove it. GtkTextIter end_iter, test_iter; gtk_text_buffer_get_end_iter(m_content, &end_iter); test_iter = end_iter; if(gtk_text_iter_backward_char(&test_iter)) { if(gtk_text_iter_get_char(&test_iter) == '\n') { gtk_text_buffer_delete( m_content, &test_iter, &end_iter); } } gtk_text_buffer_set_modified(m_content, FALSE); GtkTextIter insert_iter; GtkTextMark* insert = gtk_text_buffer_get_insert(m_content); gtk_text_buffer_get_iter_at_mark(m_content, &insert_iter, insert); InfUser* user = INF_USER(g_object_new( INF_TEXT_TYPE_USER, "id", 1, "flags", INF_USER_LOCAL, "name", m_preferences.user.name.get().c_str(), /* The user is made active when the user * switches to the document. */ "status", INF_USER_INACTIVE, "hue", m_preferences.user.hue.get(), "caret-position", gtk_text_iter_get_offset(&insert_iter), static_cast<void*>(NULL))); InfUserTable* user_table = inf_user_table_new(); inf_user_table_add_user(user_table, user); g_object_unref(user); InfTextGtkBuffer* text_gtk_buffer = inf_text_gtk_buffer_new(m_content, user_table); g_object_unref(user_table); ConnectionManager& connection_manager = get_browser().get_connection_manager(); InfCommunicationManager* communication_manager = connection_manager.get_communication_manager(); InfBrowser* browser = m_parent.get_browser(); InfIo* io; g_object_get(G_OBJECT(browser), "io", &io, NULL); InfTextSession* session = inf_text_session_new_with_user_table( communication_manager, INF_TEXT_BUFFER(text_gtk_buffer), io, user_table, INF_SESSION_RUNNING, NULL, NULL); g_object_unref(io); g_object_unref(text_gtk_buffer); InfRequest* request = inf_browser_add_note( m_parent.get_browser(), m_parent.get_browser_iter(), m_name.c_str(), "InfText", NULL, INF_SESSION(session), TRUE, on_request_finished_static, this); g_object_unref(session); if(request != NULL) { m_request = request; g_object_ref(m_request); // TODO: We can remove the node watch here, but need to have // the browser available in on_request_finished then. Maybe // just disconnect the signal, or bind it. } }
static gboolean infd_note_plugin_text_read_user(InfUserTable* user_table, xmlNodePtr node, GError** error) { guint id; gdouble hue; xmlChar* name; gboolean result; InfUser* user; if(!inf_xml_util_get_attribute_uint_required(node, "id", &id, error)) return FALSE; if(!inf_xml_util_get_attribute_double_required(node, "hue", &hue, error)) return FALSE; name = inf_xml_util_get_attribute_required(node, "name", error); if(name == NULL) return FALSE; if(inf_user_table_lookup_user_by_id(user_table, id) != NULL) { g_set_error( error, g_quark_from_static_string("INF_NOTE_PLUGIN_TEXT_ERROR"), INFD_NOTE_PLUGIN_TEXT_ERROR_USER_EXISTS, "User with ID %u exists already", id ); result = FALSE; } else { if(inf_user_table_lookup_user_by_name(user_table, (const gchar*)name)) { g_set_error( error, g_quark_from_static_string("INF_NOTE_PLUGIN_TEXT_ERROR"), INFD_NOTE_PLUGIN_TEXT_ERROR_USER_EXISTS, "User with name `%s' exists already", (const gchar*)name ); result = FALSE; } else { user = INF_USER( g_object_new( INF_TEXT_TYPE_USER, "id", id, "name", name, "hue", hue, NULL ) ); inf_user_table_add_user(user_table, user); g_object_unref(user); result = TRUE; } } xmlFree(name); return result; }