コード例 #1
0
void Gobby::UserJoinCommands::UserJoinInfo::
	add_text_user_properties(std::vector<GParameter>& params,
	                         TextSessionView& view)
{
	InfTextSession* session = view.get_session();

	GParameter hue_param = { "hue", { 0 } };
	g_value_init(&hue_param.value, G_TYPE_DOUBLE);
	g_value_set_double(&hue_param.value,
	                   m_commands.m_preferences.user.hue);
	params.push_back(hue_param);

	GParameter vector_param = { "vector", { 0 } };
	g_value_init(&vector_param.value, INF_ADOPTED_TYPE_STATE_VECTOR);

	g_value_take_boxed(&vector_param.value, inf_adopted_state_vector_copy(
		inf_adopted_algorithm_get_current(
			inf_adopted_session_get_algorithm(
				INF_ADOPTED_SESSION(session)))));
	params.push_back(vector_param);

	GParameter caret_param = { "caret-position", { 0 } };
	g_value_init(&caret_param.value, G_TYPE_UINT);

	GtkTextBuffer* buffer = GTK_TEXT_BUFFER(view.get_text_buffer());
	GtkTextMark* mark = gtk_text_buffer_get_insert(buffer);
	GtkTextIter caret_iter;

	gtk_text_buffer_get_iter_at_mark(buffer, &caret_iter, mark);
	g_value_set_uint(&caret_param.value,
	                 gtk_text_iter_get_offset(&caret_iter));
	params.push_back(caret_param);
}
コード例 #2
0
ファイル: edit-commands.cpp プロジェクト: JohnCC330/gobby
void Gobby::EditCommands::on_active_user_changed(InfUser* active_user)
{
	g_assert(m_current_view != NULL);

	if(active_user != NULL)
	{
		InfTextSession* session = m_current_view->get_session();
		InfAdoptedAlgorithm* algorithm =
			inf_adopted_session_get_algorithm(
				INF_ADOPTED_SESSION(session));
		GtkTextBuffer* buffer = GTK_TEXT_BUFFER(
			m_current_view->get_text_buffer());

		m_header.action_edit_undo->set_sensitive(
			inf_adopted_algorithm_can_undo(
				algorithm, INF_ADOPTED_USER(active_user)));
		m_header.action_edit_redo->set_sensitive(
			inf_adopted_algorithm_can_redo(
				algorithm, INF_ADOPTED_USER(active_user)));

		m_header.action_edit_cut->set_sensitive(
			gtk_text_buffer_get_has_selection(buffer));
		m_header.action_edit_paste->set_sensitive(true);
	}
	else
	{
		m_header.action_edit_undo->set_sensitive(false);
		m_header.action_edit_redo->set_sensitive(false);
		m_header.action_edit_cut->set_sensitive(false);
		m_header.action_edit_paste->set_sensitive(false);
	}
}
コード例 #3
0
ファイル: inf-test-gtk-browser.c プロジェクト: pkern/infinote
static void
on_synchronization_complete(InfSession* session,
                            InfXmlConnection* connection,
                            gpointer user_data)
{
  InfTestGtkBrowserWindow* test;
  InfAdoptedAlgorithm* algorithm;

  test = (InfTestGtkBrowserWindow*)user_data;
  session = infc_session_proxy_get_session(test->proxy);
  algorithm = inf_adopted_session_get_algorithm(INF_ADOPTED_SESSION(session));

  g_signal_connect(
    G_OBJECT(algorithm),
    "can-undo-changed",
    G_CALLBACK(on_can_undo_changed),
    test
  );

  g_signal_connect(
    G_OBJECT(algorithm),
    "can-redo-changed",
    G_CALLBACK(on_can_redo_changed),
    test
  );

  request_join(test, g_get_user_name());
}
コード例 #4
0
ファイル: inf-test-gtk-browser.c プロジェクト: pkern/infinote
static void
on_join_finished(InfcUserRequest* request,
                 InfUser* user,
                 gpointer user_data)
{
  InfTestGtkBrowserWindow* test;
  InfAdoptedSession* session;
  InfAdoptedAlgorithm* algorithm;
  gboolean undo;
  gboolean redo;

  test = (InfTestGtkBrowserWindow*)user_data;

  inf_text_gtk_buffer_set_active_user(test->buffer, INF_TEXT_USER(user));
  gtk_text_view_set_editable(GTK_TEXT_VIEW(test->textview), TRUE);

  test->user = user;

  session = INF_ADOPTED_SESSION(infc_session_proxy_get_session(test->proxy));
  algorithm = inf_adopted_session_get_algorithm(session);

  undo = inf_adopted_algorithm_can_undo(algorithm, INF_ADOPTED_USER(user));
  redo = inf_adopted_algorithm_can_redo(algorithm, INF_ADOPTED_USER(user));

  gtk_widget_set_sensitive(test->undo_button, undo);
  gtk_widget_set_sensitive(test->redo_button, redo);
}
コード例 #5
0
static void
inf_test_mass_join_join_user(InfTestMassJoiner* joiner)
{
    InfSession* session;
    InfAdoptedStateVector* v;
    GParameter params[3] = {
        { "name", { 0 } },
        { "vector", { 0 } },
        { "caret-position", { 0 } }
    };

    g_value_init(&params[0].value, G_TYPE_STRING);
    g_value_init(&params[1].value, INF_ADOPTED_TYPE_STATE_VECTOR);
    g_value_init(&params[2].value, G_TYPE_UINT);

    g_value_set_static_string(&params[0].value, joiner->username);

    g_object_get(G_OBJECT(joiner->session), "session", &session, NULL);
    v = inf_adopted_algorithm_get_current(
            inf_adopted_session_get_algorithm(INF_ADOPTED_SESSION(session))
        );
    g_object_unref(session);

    g_value_set_boxed(&params[1].value, v);
    g_value_set_uint(&params[2].value, 0u);

    inf_session_proxy_join_user(
        INF_SESSION_PROXY(joiner->session),
        3,
        params,
        inf_test_mass_join_user_join_finished_cb,
        joiner
    );

    g_value_unset(&params[2].value);
    g_value_unset(&params[1].value);
    g_value_unset(&params[0].value);
}
コード例 #6
0
ファイル: edit-commands.cpp プロジェクト: JohnCC330/gobby
void Gobby::EditCommands::on_sync_complete()
{
	g_assert(m_current_view != NULL);
	InfTextSession* session = m_current_view->get_session();

	InfAdoptedAlgorithm* algorithm = inf_adopted_session_get_algorithm(
		INF_ADOPTED_SESSION(session));

	m_can_undo_changed_handler = g_signal_connect(
		G_OBJECT(algorithm), "can-undo-changed",
		G_CALLBACK(&on_can_undo_changed_static), this);

	m_can_redo_changed_handler = g_signal_connect(
		G_OBJECT(algorithm), "can-redo-changed",
		G_CALLBACK(&on_can_redo_changed_static), this);

	if(m_synchronization_complete_handler != 0)
	{
		g_signal_handler_disconnect(
			G_OBJECT(session),
			m_synchronization_complete_handler);
		m_synchronization_complete_handler = 0;
	}
}
コード例 #7
0
ファイル: edit-commands.cpp プロジェクト: JohnCC330/gobby
void Gobby::EditCommands::on_document_changed(SessionView* view)
{
	if(m_current_view != NULL)
	{
		InfTextSession* session = m_current_view->get_session();
		InfAdoptedAlgorithm* algorithm =
			inf_adopted_session_get_algorithm(
				INF_ADOPTED_SESSION(session));
		GtkTextBuffer* buffer = GTK_TEXT_BUFFER(
			m_current_view->get_text_buffer());

		if(m_synchronization_complete_handler != 0)
		{
			g_signal_handler_disconnect(
				G_OBJECT(session),
				m_synchronization_complete_handler);
		}
		else
		{
			g_signal_handler_disconnect(
				G_OBJECT(algorithm),
				m_can_undo_changed_handler);
			g_signal_handler_disconnect(
				G_OBJECT(algorithm),
				m_can_redo_changed_handler);
		}

		g_signal_handler_disconnect(G_OBJECT(buffer),
		                            m_mark_set_handler);
		g_signal_handler_disconnect(G_OBJECT(buffer),
		                            m_changed_handler);

		m_active_user_changed_connection.disconnect();
	}

	m_current_view = dynamic_cast<TextSessionView*>(view);

	if(m_current_view != NULL)
	{
		InfTextSession* session = m_current_view->get_session();
		InfUser* active_user = m_current_view->get_active_user();
		GtkTextBuffer* buffer =
			GTK_TEXT_BUFFER(m_current_view->get_text_buffer());

		m_active_user_changed_connection =
			m_current_view->signal_active_user_changed().connect(
				sigc::mem_fun(
					*this,
					&EditCommands::
						on_active_user_changed));

		m_mark_set_handler = g_signal_connect_after(
			G_OBJECT(buffer), "mark-set",
			G_CALLBACK(&on_mark_set_static), this);
		// The selection might change without mark-set being emitted
		// when the document changes, for example when all
		// currently selected text is deleted.
		m_changed_handler = g_signal_connect_after(
			G_OBJECT(buffer), "changed",
			G_CALLBACK(&on_changed_static), this);

		if(inf_session_get_status(INF_SESSION(session)) ==
		   INF_SESSION_RUNNING)
		{
			// This connects to can-undo-changed and
			// can-redo-changed of the algorithm. Set
			// m_synchronization_complete_handler to zero so that
			// the function does not try to disconnect from it.
			m_synchronization_complete_handler = 0;
			on_sync_complete();
		}
		else
		{
			// The InfAdoptedSession is created after
			// synchronization, so we wait until that finished.
			m_synchronization_complete_handler =
				g_signal_connect_after(
					G_OBJECT(session),
					"synchronization_complete",
					G_CALLBACK(&on_sync_complete_static),
					this);

			m_can_undo_changed_handler = 0;
			m_can_redo_changed_handler = 0;
		}

		// Set initial sensitivity for active user:
		on_active_user_changed(active_user);
		// Set initial sensitivity for cut/copy/paste:
		on_mark_set();

		// Set initial sensitivity for find/replace/goto:
		m_header.action_edit_find->set_sensitive(true);

		if(m_find_dialog.get())
		{
			on_find_text_changed();
		}
		else
		{
			m_header.action_edit_find_next->set_sensitive(false);
			m_header.action_edit_find_prev->set_sensitive(false);
		}

		m_header.action_edit_find_replace->set_sensitive(true);
		m_header.action_edit_goto_line->set_sensitive(true);
	}
	else
	{
		m_header.action_edit_undo->set_sensitive(false);
		m_header.action_edit_redo->set_sensitive(false);
		m_header.action_edit_cut->set_sensitive(false);
		m_header.action_edit_copy->set_sensitive(false);
		m_header.action_edit_paste->set_sensitive(false);
		m_header.action_edit_find->set_sensitive(false);
		m_header.action_edit_find_next->set_sensitive(false);
		m_header.action_edit_find_prev->set_sensitive(false);
		m_header.action_edit_find_replace->set_sensitive(false);
		m_header.action_edit_goto_line->set_sensitive(false);
	}
}
コード例 #8
0
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;
}
static gboolean
infinoted_plugin_transformation_protection_check_request_cb(InfAdoptedSession* session,
                                                            InfAdoptedRequest* request,
                                                            InfAdoptedUser* user,
                                                            gpointer user_data)
{
  InfinotedPluginTransformationProtectionSessionInfo* info;
  guint vdiff;
  InfXmlConnection* connection;
  gchar* request_str;
  gchar* current_str;
  gchar* remote_id;
  gchar* path;

  info = (InfinotedPluginTransformationProtectionSessionInfo*)user_data;

  vdiff = inf_adopted_state_vector_vdiff(
    inf_adopted_request_get_vector(request),
    inf_adopted_algorithm_get_current(
      inf_adopted_session_get_algorithm(session)
    )
  );

  if(vdiff > info->plugin->max_vdiff)
  {
    connection = inf_user_get_connection(INF_USER(user));

    /* Local requests do not need to be transformed, so always have a
     * zero vdiff. */
    g_assert(connection != NULL);

    /* Kill the connection */
    infd_session_proxy_unsubscribe(
      INFD_SESSION_PROXY(info->proxy),
      connection
    );

    /* Write a log message */
    path = inf_browser_get_path(
      INF_BROWSER(
        infinoted_plugin_manager_get_directory(info->plugin->manager)
      ),
      &info->iter
    );

    request_str = inf_adopted_state_vector_to_string(
      inf_adopted_request_get_vector(request)
    );

    current_str = inf_adopted_state_vector_to_string(
      inf_adopted_algorithm_get_current(
        inf_adopted_session_get_algorithm(session)
      )
    );

    g_object_get(G_OBJECT(connection), "remote-id", &remote_id, NULL);

    infinoted_log_warning(
      infinoted_plugin_manager_get_log(info->plugin->manager),
      _("In document \"%s\": Attempt to transform request \"%s\" to current state \"%s\" "
        "(vdiff=%u) by user \"%s\" (id=%u, conn=%s). Maximum allowed is %u; the "
        "connection has been unsubscribed."),
      path,
      request_str,
      current_str,
      vdiff,
      inf_user_get_name(INF_USER(user)),
      inf_user_get_id(INF_USER(user)),
      remote_id,
      info->plugin->max_vdiff
    );

    g_free(path);
    g_free(request_str);
    g_free(current_str);
    g_free(remote_id);

    /* Prevent the request from being transformed */
    return TRUE;
  }

  return FALSE;
}
コード例 #10
0
ファイル: inf-test-gtk-browser.c プロジェクト: pkern/infinote
static void
request_join(InfTestGtkBrowserWindow* test,
             const gchar* user_name)
{
  InfcUserRequest* request;
  InfAdoptedStateVector* v;
  GError* error;
  GtkTextBuffer* buffer;
  GtkTextMark* mark;
  GtkTextIter iter;
  GParameter params[3] = {
    { "name", { 0 } },
    { "vector", { 0 } },
    { "caret-position", { 0 } }
  };

  g_value_init(&params[0].value, G_TYPE_STRING);
  g_value_init(&params[1].value, INF_ADOPTED_TYPE_STATE_VECTOR);
  g_value_init(&params[2].value, G_TYPE_UINT);

  g_value_set_static_string(&params[0].value, user_name);

  /* Use current state vector. Infinote should already do this. */
  v = inf_adopted_state_vector_copy(
    inf_adopted_algorithm_get_current(
      inf_adopted_session_get_algorithm(
        INF_ADOPTED_SESSION(infc_session_proxy_get_session(test->proxy))
      )
    )
  );

  g_value_take_boxed(&params[1].value, v);

  buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(test->textview));
  mark = gtk_text_buffer_get_insert(buffer);
  gtk_text_buffer_get_iter_at_mark(buffer, &iter, mark);
  g_value_set_uint(&params[2].value, gtk_text_iter_get_offset(&iter));

  error = NULL;
  request = infc_session_proxy_join_user(test->proxy, params, 3, &error);

  /* TODO: Free GValues? */

  if(request == NULL)
  {
    set_error(test, "Failed to request user join", error->message);
  }
  else
  {
    g_signal_connect_after(
      G_OBJECT(request),
      "failed",
      G_CALLBACK(on_join_failed),
      test
    );

    g_signal_connect_after(
      G_OBJECT(request),
      "finished",
      G_CALLBACK(on_join_finished),
      test
    );
  }
}