Common code paths
This is brief overview of very common code paths. It should help to to find out how messages are relayed through the various classes. Take your time to read the paths, or just pick the path only which is relevant for you.
About signals and slots
When signals/slots are involved the code path becomes a bit harder to follow (which is normal side effect of any "observer" pattern). There are three ways to find the code path of a signal/slot:
- Find the parent class which initializes one of the objects. It typically connects the signals or slots too.
- Follow the debugging output which the debug build produces.
- Search through all .cpp file for the name of the signal. This can be done with "Search in all files" in your IDE, or at the command line using using:
find . -name '*.cpp' | xargs grep --color=auto signalName
Typically, the connection is made in the parent class which initializes one of the two objects. To follow connections faster, it's important to know some common aggregate classes:
- MsnNotificationConnection is initialized in the KMess class, which handles the main window.
- MsnSwitchboardConnection is initialized in the ChatMaster class, and stored in the Chat class.
- ContactList is initialized in the KMess class, and stored in the CurrentAccount and MsnNotificationConnection class.
- ChatMaster is initialized in the KMess class.
- P2PApplication is initialized in the ApplicationList class, and ChatMaster afterwards.
Management of the contact list
- Adding a new contact:
KMess::addNewContact() -> MsnNotificationConnection::addNewContact() -> MsnConnection::sendCommand()
- Blocking a contact from the context menu in the contact list:
KMessView::slotForwardBlockContact() -> emit blockContact() -> MsnNotificationConnection::blockContact() -> MsnConnection::sendCommand()
Processing server notifications
- Signalling that a contact got online:
MsnNotificationConnection::gotNln() -> ContactList::changeContactStatus() -> Contact::setStatus() -> emit changedStatus(), emit contactOnline()`
A lot of GUI classes are updated on the Contact::changedStatus() and Contact::isOnline() signals. The ContactList class also sends ContactList::contactChangedStatus() and ContactList::contactOnline() signals so classes which like to receive updates from all contacts can connect to those.
Sending and receiving chat messages
- Sending a chat message:
ChatView::enterPressed() -> sendMessage() -> emit sendMessageToContact() -> MsnSwitchboardConnection::sendChatMessage()
- Sending data to the socket:
MsnSwithboadConnection::sendChatMessage() -> sendMimeMessageWhenReady() -> connection idle? -> MsnConnection::sendMimeMessage() -> writeBinaryData() -> MsnSocketTcp::writeBinaryData() -> QTcpSocket::write()
- Parsing a socket data for a mime message:
MsnSocket::slotSocketDataReceived() -> emit dataReceived() -> MsnConnection::slotDataReceived() -> MsnSwitchboardConnection::parseMimeMessage()
- Displaying a received chat message in the user interface:
MsnSwitchboardConnection::parseMimeMessage() -> parseChatMessage() -> emit chatMessage() -> Chat::receivedMessage() -> ChatView::showMessage() -> ChatMessageView::addHtmlMessage()
Transfer of application data
- Starting the download of a custom emoticon:
MsnSwitchboardConnection::parseMimeMessage() -> parseEmoticonMessage() -> emit gotMsnObject() -> ChatMaster::slotGotMsnObject() -> startMsnObjectDownload() -> startApplication() -> P2PApplication::start() -> MsnObjectTransferP2P::userStarted1_UserInvitesContact() -> P2PApplication::sendSlpSessionInvitation()
Starting chat sessions
The ChatMaster class has an overview of the started switchboard connections and chat windows, so it can determine if swithboard connection needs to be created, replace or deleted. It also creates or re-actives chat windows.
Requesting a chat happens in two steps. First, a new switchboard connection needs to be requested at the notification server. When the server returns the information, the switchboard connection can be made.
The switchboard is able to run in the background without a chat window. This way the memory usage remains low when a display pictures are downloaded in the background; those pictures are transferred over a switchboard connection. That's why there is a requestChatWindow() signal nowadays, so the switchboard can indicate when it's no longer in the background.
- Starting a chat by clicking on a contact:
KMessView::slotItemClicked() -> emit requestChat() -> ChatMaster::requestChat() -> no chat active? -> emit requestSwitchboard( handle, type ) -> MsnNotificationConnection::requestSwitchboard() -> sendCommand( "XFR", "SB" )
- Start a switchboard connection when the server responds:
MsnNotificationConnection::gotXfr() -> emit startSwitchboard() -> ChatMaster::startSwitchboard() ->MsnSwitchboardConnection::start() -> establish the connection, request chat window, enter the chat session, invite contacts
