void Gobby::TitleBar::update_title() { // TODO: Show path, as gedit does. This requires change notification // for document info storage. if(m_current_view != NULL) { InfSession* session = m_current_view->get_session(); InfBuffer* buffer = inf_session_get_buffer(session); InfSessionStatus status = inf_session_get_status(session); if(status == INF_SESSION_SYNCHRONIZING || !inf_buffer_get_modified(buffer)) { m_window.set_title( m_current_view->get_title() + " - Gobby"); } else { m_window.set_title( "*" + m_current_view->get_title() + " - Gobby"); } } else { m_window.set_title("Gobby"); } }
static void inf_adopted_session_create_algorithm(InfAdoptedSession* session) { InfAdoptedSessionPrivate* priv; priv = INF_ADOPTED_SESSION_PRIVATE(session); g_assert(priv->algorithm == NULL); g_assert( inf_session_get_status(INF_SESSION(session)) == INF_SESSION_RUNNING ); priv->algorithm = inf_adopted_algorithm_new_full( inf_session_get_user_table(INF_SESSION(session)), inf_session_get_buffer(INF_SESSION(session)), priv->max_total_log_size ); g_signal_connect( G_OBJECT(priv->algorithm), "execute-request", G_CALLBACK(inf_adopted_session_execute_request_cb), session ); g_object_notify(G_OBJECT(session), "algorithm"); }
Gobby::UserJoinCommands::UserJoinInfo::UserJoinInfo(UserJoinCommands& cmds, InfBrowser* browser, const InfBrowserIter* it, InfSessionProxy* proxy, Folder& folder, SessionView& view): m_node(browser, it), m_commands(cmds), m_proxy(proxy), m_folder(folder), m_view(view), m_request(NULL), m_synchronization_complete_handler(0), m_retry_index(1) { g_object_ref(m_proxy); InfSession* session; g_object_get(G_OBJECT(proxy), "session", &session, NULL); if(inf_session_get_status(session) == INF_SESSION_SYNCHRONIZING) { // If not yet synchronized, wait for synchronization until // attempting userjoin m_synchronization_complete_handler = g_signal_connect_after( G_OBJECT(session), "synchronization-complete", G_CALLBACK(on_synchronization_complete_static), this); } else { // Delay this call to make sure we don't call finish() // right inside the constructor. Glib::signal_idle().connect( sigc::bind_return(sigc::mem_fun( *this, &UserJoinInfo::attempt_user_join), false)); } g_object_unref(session); }
static void inf_test_mass_join_subscribe_finished_cb(InfRequest* request, const InfRequestResult* result, const GError* error, gpointer user_data) { InfTestMassJoiner* joiner; const InfBrowserIter* iter; InfSession* session; joiner = (InfTestMassJoiner*)user_data; inf_request_result_get_subscribe_session(result, NULL, &iter, NULL); joiner->session = INFC_SESSION_PROXY( inf_browser_get_session( INF_BROWSER(joiner->browser), iter ) ); g_assert(joiner->session != NULL); g_object_get(G_OBJECT(joiner->session), "session", &session, NULL); switch(inf_session_get_status(session)) { case INF_SESSION_PRESYNC: case INF_SESSION_SYNCHRONIZING: g_signal_connect_after( G_OBJECT(session), "synchronization-failed", G_CALLBACK(inf_test_mass_join_session_synchronization_failed_cb), joiner ); g_signal_connect_after( G_OBJECT(session), "synchronization-complete", G_CALLBACK(inf_test_mass_join_session_synchronization_complete_cb), joiner ); break; case INF_SESSION_RUNNING: inf_test_mass_join_join_user(joiner); break; case INF_SESSION_CLOSED: fprintf( stderr, "Joiner %s: Session closed after subscription\n", joiner->username ); inf_xml_connection_close(infc_browser_get_connection(joiner->browser)); break; } g_object_unref(session); }
static void infinoted_plugin_linekeeper_session_added(const InfBrowserIter* iter, InfSessionProxy* proxy, gpointer plugin_info, gpointer session_info) { InfinotedPluginLinekeeperSessionInfo* info; InfSession* session; InfUserTable* user_table; info = (InfinotedPluginLinekeeperSessionInfo*)session_info; info->plugin = (InfinotedPluginLinekeeper*)plugin_info; info->proxy = proxy; info->request = NULL; info->user = NULL; info->dispatch = NULL; g_object_ref(proxy); g_object_get(G_OBJECT(proxy), "session", &session, NULL); g_assert(inf_session_get_status(session) == INF_SESSION_RUNNING); info->buffer = INF_TEXT_BUFFER(inf_session_get_buffer(session)); g_object_ref(info->buffer); user_table = inf_session_get_user_table(session); g_signal_connect( G_OBJECT(user_table), "add-available-user", G_CALLBACK(infinoted_plugin_linekeeper_add_available_user_cb), info ); g_signal_connect( G_OBJECT(user_table), "remove-available-user", G_CALLBACK(infinoted_plugin_linekeeper_remove_available_user_cb), info ); /* Only join a user when there are other nonlocal users available, so that * we don't keep the session from going idle. */ if(infinoted_plugin_linekeeper_has_available_users(info) == TRUE) infinoted_plugin_linekeeper_join_user(info); g_object_unref(session); }
void Gobby::SynchronizationCommands::on_document_added(SessionView& view) { InfSession* session = view.get_session(); if(inf_session_get_status(session) == INF_SESSION_SYNCHRONIZING) { InfXmlConnection* connection; g_object_get(G_OBJECT(session), "sync-connection", &connection, NULL); gdouble percentage = inf_session_get_synchronization_progress( session, connection); g_object_unref(connection); g_assert(m_sync_map.find(session) == m_sync_map.end()); m_sync_map[session] = new SyncInfo(*this, view); set_progress_text(view, percentage); } }
void Gobby::TextTabLabel::update_modified() { InfSession* session = INF_SESSION(m_view.get_session()); bool modified = inf_buffer_get_modified(inf_session_get_buffer(session)); InfSessionStatus status = inf_session_get_status(session); if(status == INF_SESSION_SYNCHRONIZING || status == INF_SESSION_PRESYNC) { modified = false; } if(modified) m_title.set_text("*" + m_view.get_title()); else m_title.set_text(m_view.get_title()); }
void Gobby::TextTabLabel::on_changed(InfTextUser* author) { if(!m_changed) { InfSession* session = INF_SESSION(m_view.get_session()); if(inf_session_get_status(session) == INF_SESSION_RUNNING) set_changed(); } if(m_folder.get_current_document() != &m_view) { // TODO: remove dot if all the user's // new contributions where undone if(std::find(m_changed_by.begin(), m_changed_by.end(), author) == m_changed_by.end()) { m_changed_by.push_back(UserWatcher(this, author)); update_dots(); } } }
static void inf_adopted_session_local_user_added(InfAdoptedSession* session, InfAdoptedUser* user) { InfAdoptedSessionPrivate* priv; InfSessionStatus status; InfAdoptedSessionLocalUser* local; InfAdoptedStateVector* current_state; priv = INF_ADOPTED_SESSION_PRIVATE(session); status = inf_session_get_status(INF_SESSION(session)); /* Cannot be local while synchronizing */ g_assert(status == INF_SESSION_RUNNING); local = g_slice_new(InfAdoptedSessionLocalUser); local->user = user; local->last_send_vector = inf_adopted_state_vector_copy( inf_adopted_user_get_vector(user) ); /* Set current vector for local user, this is kept up-to-date by * InfAdoptedAlgorithm. TODO: Also do this in InfAdoptedAlgorithm? */ inf_adopted_user_set_vector( user, inf_adopted_state_vector_copy( inf_adopted_algorithm_get_current(priv->algorithm) ) ); local->noop_time = 0; priv->local_users = g_slist_prepend(priv->local_users, local); /* Start noop timer if user is not up to date */ current_state = inf_adopted_algorithm_get_current(priv->algorithm); if(inf_adopted_state_vector_compare(current_state, local->last_send_vector)) inf_adopted_session_start_noop_timer(session, local); }
void Gobby::TabLabel::update_icon() { InfSession* session = INF_SESSION(m_view.get_session()); if(inf_session_get_subscription_group(session) == NULL) { m_icon.set_from_icon_name("network-offline", Gtk::ICON_SIZE_MENU); } else { switch(inf_session_get_status(session)) { case INF_SESSION_PRESYNC: case INF_SESSION_SYNCHRONIZING: // TODO: Switch to process-working, if/when m_icon can // show animations. m_icon.set_from_icon_name("system-run", Gtk::ICON_SIZE_MENU); break; case INF_SESSION_RUNNING: if(m_view.get_active_user() != NULL) { m_icon.set_from_icon_name(m_active_icon_name, Gtk::ICON_SIZE_MENU); } else { m_icon.set_from_icon_name("text-x-generic", Gtk::ICON_SIZE_MENU); } break; case INF_SESSION_CLOSED: m_icon.set_from_icon_name("network-offline", Gtk::ICON_SIZE_MENU); break; } } }
void Gobby::TabLabel::update_color() { InfSession* session = INF_SESSION(m_view.get_session()); if(m_changed) { // Document has changed: awareness -> red m_title.override_color(Gdk::RGBA("#c00000")); } else if(inf_session_get_subscription_group(session) == NULL || inf_session_get_status(session) != INF_SESSION_RUNNING) { // Document disconnected or not yet running // (most probably synchronizing): not (yet) available -> grey m_title.override_color(Gdk::RGBA("#606060")); } else { // Otherwise default m_title.unset_color(); } }
Gobby::UserJoin::UserJoin(InfBrowser* browser, const InfBrowserIter* iter, InfSessionProxy* proxy, std::auto_ptr<ParameterProvider> param_provider): m_node(browser, iter), m_proxy(proxy), m_param_provider(param_provider), m_synchronization_complete_handler(0), m_request(NULL), m_retry_index(1), m_user(NULL), m_error(NULL) { g_object_ref(m_proxy); InfSession* session; g_object_get(G_OBJECT(proxy), "session", &session, NULL); if(inf_session_get_status(session) == INF_SESSION_SYNCHRONIZING) { // If not yet synchronized, wait for synchronization until // attempting userjoin m_synchronization_complete_handler = g_signal_connect_after( G_OBJECT(session), "synchronization-complete", G_CALLBACK(on_synchronization_complete_static), this); } else { // Delay this call to make sure we don't emit the // finished signal right inside the constructor. // TODO: This might not be a problem, since the caller // can just check for completion with the get_user() // and get_error() methods. Glib::signal_idle().connect( sigc::bind_return(sigc::mem_fun( *this, &UserJoin::attempt_user_join), false)); } g_object_unref(session); }
static gboolean infc_session_proxy_net_object_received(InfNetObject* net_object, InfXmlConnection* connection, xmlNodePtr node, GError** error) { InfcSessionProxy* proxy; InfcSessionProxyPrivate* priv; InfcSessionProxyClass* proxy_class; InfSessionSyncStatus status; GError* local_error; InfcRequest* request; GError* seq_error; proxy = INFC_SESSION_PROXY(net_object); priv = INFC_SESSION_PROXY_PRIVATE(proxy); proxy_class = INFC_SESSION_PROXY_GET_CLASS(proxy); status = inf_session_get_synchronization_status(priv->session, connection); local_error = NULL; g_assert(status != INF_SESSION_SYNC_NONE || priv->connection == connection); g_assert(inf_session_get_status(priv->session) != INF_SESSION_CLOSED); if(status != INF_SESSION_SYNC_NONE) { /* Direct delegate during synchronization */ return inf_net_object_received( INF_NET_OBJECT(priv->session), connection, node, error ); } else { if(strcmp((const char*)node->name, "user-join") == 0) { infc_session_proxy_handle_user_join( proxy, connection, node, &local_error ); } else if(strcmp((const char*)node->name, "user-rejoin") == 0) { infc_session_proxy_handle_user_rejoin( proxy, connection, node, &local_error ); } else if(strcmp((const char*)node->name, "request-failed") == 0) { infc_session_proxy_handle_request_failed( proxy, connection, node, &local_error ); } else if(strcmp((const char*)node->name, "session-close") == 0) { infc_session_proxy_handle_session_close( proxy, connection, node, &local_error ); } else { return inf_net_object_received( INF_NET_OBJECT(priv->session), connection, node, error ); } } if(local_error != NULL) { /* If the request had a (valid) seq set, we cancel the corresponding * request because the reply could not be processed. */ request = infc_request_manager_get_request_by_xml( priv->request_manager, NULL, node, NULL ); if(request != NULL) { /* If the request had a seq set, we cancel the corresponding request * because the reply could not be processed. */ seq_error = NULL; g_set_error( &seq_error, inf_request_error_quark(), INF_REQUEST_ERROR_REPLY_UNPROCESSED, _("Server reply could not be processed: %s"), local_error->message ); infc_request_manager_fail_request( priv->request_manager, request, seq_error ); g_error_free(seq_error); } g_propagate_error(error, local_error); } /* Don't forward any of the handled messages */ return FALSE; }
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); } }