2
* Whiteboard session manager
5
* David Yip <yipdw@rose-hulman.edu>
7
* Copyright (c) 2005 Authors
9
* Released under GNU GPL, read the file 'COPYING' for more information
12
#ifndef __SESSION_MANAGER_H__
13
#define __SESSION_MANAGER_H__
20
#include <loudmouth/loudmouth.h>
23
#include "jabber_whiteboard/typedefs.h"
24
#include "jabber_whiteboard/defines.h"
25
#include "jabber_whiteboard/buddy-list-manager.h"
40
namespace Whiteboard {
42
class ReceiveMessageQueue;
43
class SendMessageQueue;
47
class ChatMessageHandler;
50
class SessionFilePlayer;
51
class UndoStackObserver;
55
/// Jabber resource name
56
#define RESOURCE_NAME "Inkboard"
58
/// connectToServer return values
59
#define CONNECT_SUCCESS 0
60
#define FAILED_TO_CONNECT 1
61
#define INVALID_AUTH 2
62
#define SSL_INITIALIZATION_ERROR 3
64
/// sendMessage return values
65
#define SEND_SUCCESS 0
66
#define CONNECTION_ERROR 1
67
#define UNKNOWN_OUTGOING_TYPE 2
68
#define NO_RECIPIENT_JID 3
71
* Structure grouping data items pertinent to a whiteboard session.
73
* SessionData holds all session data for both 1:1 and chatroom conferences.
74
* Access to members should be controlled by first querying the status bitset
75
* to see if useful data will actually exist in that member -- i.e. checking
76
* status[IN_CHATROOM] to see if the chatters set will contain anything.
77
* It usually won't hurt to do a straight query -- there are very few members
78
* that remain uninitialized for very long -- but it's a good idea to check.
85
* \param sm The SessionManager with which a SessionData instance should be
88
SessionData(SessionManager *sm);
93
* The JID of the recipient: either another user JID or the JID of a chatroom.
95
gchar const* recipient;
98
* Pointer to Loudmouth connection structure.
99
* Used for Loudmouth calls that require it.
101
LmConnection* connection;
104
* SSL information structure for SSL connections.
109
* Flag indicating whether or not we should ignore further SSL errors for a given session.
111
bool ignoreFurtherSSLErrors;
115
* A user's handle in a Jabber chatroom.
117
Glib::ustring chat_handle;
120
* Name of the chatroom that a user in a chatroom is connected to.
122
Glib::ustring chat_name;
125
* Name of the conference server.
127
Glib::ustring chat_server;
132
* Map associating senders to receive queues.
134
RecipientToReceiveQueueMap receive_queues;
137
* Map associating senders to commit events sent by those committers.
139
CommitsQueue recipients_committed_queue;
142
* Pointer to queue for messages to be sent.
144
SendMessageQueue* send_queue;
146
// Message sequence numbers
149
* The sequence number of the latest message sent by this client in a given session.
150
* Used for determining the sequence number of the next message.
152
unsigned int sequence_number;
154
//unsigned int latest_sent_transaction;
155
//RecipientToLatestTransactionMap latest_processed_transactions;
160
* Session state and status flags.
162
std::bitset< NUM_FLAGS > status;
165
* Jabber buddy list data.
167
BuddyListManager buddyList;
170
* List of participants in a Jabber chatroom.
172
ChatterList chatters;
175
* Session file filename; blank if no session file is to be
178
Glib::ustring sessionFile;
181
// access to containing class
184
// noncopyable, nonassignable
185
SessionData(SessionData const&);
186
SessionData& operator=(SessionData const&);
190
// TODO: This class is huge. It might be best to refactor it into smaller,
191
// more coherent chunks.
193
// TODO: convert to pass-by-reference where appropriate. In particular, a lot of the
194
// string buffers passed to methods in the argument list can be made into references
195
// appropriately and easily.
198
* Session management class for Inkboard.
200
* By "session management", we refer to the management of all events that an Inkboard
201
* session may need to handle: negotiating a connection to a Jabber server, negotiating
202
* sessions with users and chatrooms, sending, receiving, and parsing messages, and so
205
* SessionManager instances are associated with Inkscape desktop objects on a 1:1 basis.
207
class SessionManager {
212
* \param desktop The desktop with which this SessionManager is associated. */
213
SessionManager(::SPDesktop *desktop);
216
// Session tracking data
219
* Pointer to SessionData structure.
221
struct SessionData *session_data;
223
// Inkscape interface
226
* Set the desktop with which this SessionManager is associated.
228
* @param desktop the desktop with which this SessionManager should be associated
230
void setDesktop(::SPDesktop* desktop);
232
// Session management
235
* Connect to a Jabber server.
237
* @param server Jabber server URL
238
* @param username Jabber username
239
* @param pw password for Jabber account
240
* @param usessl use SSL for connection
242
* @return CONNECT_SUCCESS if connection successful; FAILED_TO_CONNECT if connection failed or INVALID_AUTH
243
* if authentication invalid
245
int connectToServer(Glib::ustring const& server, Glib::ustring const& port, Glib::ustring const& username, Glib::ustring const& pw, bool usessl);
248
* Handle an SSL error by prompting the user for feedback, and continuing or aborting the connection
249
* process based on that feedback.
251
* @param ssl pointer to LmSSL structure
252
* @param status The error message
254
* @return LM_SSL_RESPONSE_CONTINUE if user wishes to continue establishing the connection or LM_SSL_RESPONSE_STOP if user wishes to abort connection
256
LmSSLResponse handleSSLError(LmSSL* ssl, LmSSLStatus status);
259
* Disconnect from a Jabber server.
261
* This invokes disconnectFromDocument().
263
* \see Inkscape::Whiteboard::SessionManager::disconnectFromDocument
265
void disconnectFromServer();
268
* Disconnect from a document session. The connection to the Jabber server is not
269
* broken, and may be reused to connect to a new document session.
272
void disconnectFromDocument();
275
* Perform session teardown. This method by itself does not disconnect from a document or
282
* Set the recipient for Inkboard messages.
284
* @param recipientJID the recipient's JID
286
void setRecipient(char const* recipientJID);
288
// Message sending utilities
291
* Put an Inkboard message into the send queue.
292
* This method does not actually send anything to an Inkboard client.
294
* \see Inkscape::Whiteboard::SessionManager::sendMessage
297
* @param msg the message to send
298
* @param type the type of message (only CHANGE_* types permitted)
299
* @param chatroom whether or not this message is destined for a chatroom
301
void sendChange(Glib::ustring const& msg, MessageType type, std::string const& recipientJID, bool chatroom);
304
* Send a message to an Inkboard client.
307
* @param msgtype the type of message to send
308
* @param sequence message sequence number
309
* @param msg the message to send
310
* @param recipientJID the JID of the recipient
311
* @param chatroom whether or not this message is destined for a chatroom
313
* @return SEND_SUCCESS if successful; otherwise: UNKNOWN_OUTGOING_TYPE if msgtype is not recognized, NO_RECIPIENT_JID if recipientJID is NULL or blank, CONNECTION_ERROR if Jabber connection error occurred
315
int sendMessage(MessageType msgtype, unsigned int sequence, Glib::ustring const& msg, char const* recipientJID, bool chatroom);
318
* Inform the user of a connection error via a Gtk::MessageDialog.
320
* @param errmsg message to display
322
void connectionError(Glib::ustring const& errmsg);
325
* Stream the contents of the document with which this SessionManager is associated with to the given recipient.
327
* @param recipientJID the JID of the recipient
328
* @param newidsbuf buffer to store IDs of new nodes
329
* @param newnodesbuf buffer to store address of new nodes
331
void resendDocument(char const* recipientJID, KeyToNodeMap& newidsbuf, NodeToKeyMap& newnodesbuf);
335
* Send a connection request to another Inkboard client.
338
* @param recipientJID the JID to connect to
339
* @param document document message to send
341
void sendRequestToUser(std::string const& recipientJID);
344
* Send a connection request to chatroom.
346
* @param server server to connect to
347
* @param chatroom name of chatroom
348
* @param handle chatroom handle to use
349
* @param password chatroom password; leave NULL if no password
351
void sendRequestToChatroom(Glib::ustring const& server, Glib::ustring const& chatroom, Glib::ustring const& handle, Glib::ustring const& password);
354
* Send a connection request response to a user who requested to connect to us.
356
* @param requesterJID the JID of the user whom sent us the request
357
* @param accepted_request whether or not we accepted the request
359
void sendConnectRequestResponse(char const* requesterJID, gboolean accepted_request);
362
* Method called when a connection request is received. This method produces a dialog
363
* that asks the user whether or not s/he would like to accept the request.
366
* @param requesterJID the JID of the user whom sent us the request
367
* @param msg the message associated with this request
369
void receiveConnectRequest(gchar const* requesterJID);
372
* Method called when a response to a connection request is received.
373
* This method performs any necessary session setup/teardown and user notification
374
* depending on the response received.
377
* @param msg the message associated with this request
378
* @param response the response code
379
* @param sender the JID of the user whom responded to our request
381
void receiveConnectRequestResponse(InvitationResponses response, std::string& sender);
384
* Method called when a document synchronization request is received from a new conference
385
* member in a chatroom.
387
* \param recipient the recipient JID
389
void receiveConnectRequestResponseChat(gchar const* recipient);
391
// Message parsing and passing
394
* Processes a group of document change messages.
396
* \param changemsg The change message group to process.
398
void receiveChange(Glib::ustring const& changemsg);
400
// Logging and session file handling
402
* Start a session log with the given filename.
404
* \param filename Full path to the file that the session log should be written to.
405
* \throw Glib::FileError Thrown if an exception is thrown during session file creation.
407
void startLog(Glib::ustring filename);
410
* Load a session file for playback.
412
* \param filename Full path to the session file that is to be loaded.
414
void loadSessionFile(Glib::ustring filename);
417
* Returns whether or not the session is in session file playback mode.
419
* \return Whether or not the session is in session file playback mode.
421
bool isPlayingSessionFile();
423
// User event notification
426
* Method to notify the user that a whiteboard session to another user has been successfully
429
* \param JID The JID with whom the user established a session.
431
void userConnectedToWhiteboard(gchar const* JID);
434
* Method to notify the user that the other user in a user-to-user whiteboard session
437
* \param JID The JID of the user who left the whiteboard session.
439
void userDisconnectedFromWhiteboard(std::string const& JID);
441
// Queue dispatching and UI setup
444
* Start the send queue for this session.
446
void startSendQueueDispatch();
449
* Stop the send queue for this session.
451
void stopSendQueueDispatch();
454
* Start the receive queue for this session.
456
void startReceiveQueueDispatch();
459
* Stop the receive queue for this session.
461
void stopReceiveQueueDispatch();
464
* Clear all layers, definitions, and metadata from the document with which a
465
* SessionManager instance is associated.
467
* Documents are cleared to assist synchronization between two clients
468
* or a client and a chatroom.
470
void clearDocument();
473
* Set up objects for handling actions generated by the user interacting with
474
* Inkscape. This includes marking the active session as being in a whiteboard session,
475
* starting send and receive queues, and creating an event serializer and deserializer.
477
* \see Inkscape::Whiteboard::SendMessageQueue
478
* \see Inkscape::Whiteboard::ReceiveMessageQueue
479
* \see Inkscape::Whiteboard::Serializer
480
* \see Inkscape::Whiteboard::Deserializer
482
void setupInkscapeInterface();
485
* Reset whiteboard verbs to INITIAL state.
487
void setInitialVerbSensitivity() {
488
this->_setVerbSensitivity(INITIAL);
492
* Set up the event commit listener.
494
* The event commit listener watches for events that are committed to the document's undo log,
495
* serializes those events, and then adds them to the message send queue.
497
* \see Inkscape::Whiteboard::SendMessageQueue
498
* \see Inkscape::Whiteboard::UndoStackObserver
500
void setupCommitListener();
502
// Private object retrieval
503
::SPDesktop* desktop();
504
::SPDocument* document();
505
Callbacks* callbacks();
506
Whiteboard::UndoStackObserver* undo_stack_observer();
507
Serializer* serializer();
508
XMLNodeTracker* node_tracker();
509
Deserializer* deserializer();
510
ChatMessageHandler* chat_handler();
511
SessionFilePlayer* session_player();
512
SessionFile* session_file();
515
// Internal logging methods
516
void _log(Glib::ustring const& message);
519
void _tryToStartLog();
521
enum SensitivityMode {
523
ESTABLISHED_CONNECTION,
525
DISCONNECTED_FROM_SESSION
528
void _setVerbSensitivity(SensitivityMode mode);
530
bool _pollReceiveConnectRequest(Glib::ustring const recipient);
532
::SPDesktop* _myDesktop;
533
::SPDocument* _myDoc;
534
Whiteboard::UndoStackObserver* _myUndoObserver;
535
XMLNodeTracker* _myTracker;
536
ChatMessageHandler* _myChatHandler;
537
Callbacks* _myCallbacks;
538
SessionFile* _mySessionFile;
539
SessionFilePlayer* _mySessionPlayer;
540
MessageHandler* _myMessageHandler;
541
Serializer* _mySerializer;
542
Deserializer* _myDeserializer;
544
sigc::connection _send_queue_dispatcher;
545
sigc::connection _receive_queue_dispatcher;
546
sigc::connection _notify_incoming_request;
548
// noncopyable, nonassignable
549
SessionManager(SessionManager const&);
550
SessionManager& operator=(SessionManager const&);
562
c-file-style:"stroustrup"
563
c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
568
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :