Import release 2.0beta1

This commit is contained in:
Mario Fetka
2009-03-23 23:26:37 +00:00
parent 8b3dac7ce6
commit a899084e37
373 changed files with 147541 additions and 68476 deletions
+97 -47
View File
@@ -17,8 +17,6 @@
#include "../kmessdebug.h"
#ifdef KMESS_NETWORK_WINDOW
#include "networkwindow.h"
#include "../network/mimemessage.h"
@@ -53,7 +51,8 @@ NetworkWindow::NetworkWindow( QWidget *parent )
, Ui::NetworkWindow()
{
// Set up the dialog and its buttons
setButtons( Close | User1 | User2 );
setObjectName( "Network" );
setButtons( Close | User1 | User2 | User3 );
setDefaultButton( Close );
setCaption( i18n("Network Window") );
restoreDialogSize( KMessConfig::instance()->getGlobalConfig( "NetworkWindow" ) );
@@ -76,12 +75,15 @@ NetworkWindow::NetworkWindow( QWidget *parent )
connect( sendCommandButton_, SIGNAL( released() ), this, SLOT( slotSendCommand() ) );
// Name our custom buttons and setup their behavior
setButtonText( User1, i18n("S&ave tab") );
setButtonText( User2, i18n("C&lear tab") );
setButtonText( User1, i18n("S&ave Tab") );
setButtonText( User2, i18n("C&lear Tab") );
setButtonText( User3, i18n("C&lose All Tabs") );
setButtonIcon( User1, KIcon("document-save") );
setButtonIcon( User2, KIcon("edit-clear-list") );
setButtonIcon( User3, KIcon("edit-clear") );
connect( this, SIGNAL( user1Clicked() ), this, SLOT( saveCurrentTab() ) );
connect( this, SIGNAL( user2Clicked() ), this, SLOT( clearCurrentTab() ) );
connect( this, SIGNAL( user3Clicked() ), this, SLOT( closeAllTabs() ) );
// Set the default state of the ui widgets
sendStandardCmdRadio_->setChecked( true );
@@ -117,7 +119,7 @@ NetworkWindow::~NetworkWindow()
entry->logView->append( "<p style='margin: 0; font-size: 8pt'>&nbsp;<!-- time spacer --></p>" );
}
entry->logView->append( html );
entry->logView->append( html.toUtf8() );
entry->lastMessage = now;
// Update the widgets for the currently visible tab
@@ -130,7 +132,7 @@ NetworkWindow::~NetworkWindow()
void NetworkWindow::addLogMessage(QObject *connection, const QString &message)
{
ConnectionEntry *entry = getConnectionEntry(connection);
QString html = "<p style='margin: 0'><font color='#333333'>&nbsp; " + message + "</font></p>\n";
QString html( "<p style='margin: 0'><font color='#333333'>&nbsp; " + message + "</font></p>\n" );
addMessage( entry, html );
}
@@ -140,7 +142,7 @@ NetworkWindow::~NetworkWindow()
void NetworkWindow::addIncomingMessage(QObject *connection, const QByteArray &message)
{
ConnectionEntry *entry = getConnectionEntry(connection);
QString html = "<p style='margin: 0; color: #0033FF'><hr style='padding: 0; margin: 0;'>" + formatMessage(entry, true, message) + "</p>\n";
QString html( "<p style='margin: 0; color: #0033FF'><hr style='padding: 0; margin: 0;'>" + formatMessage(entry, true, message) + "</p>\n" );
addMessage(entry, html);
}
@@ -150,7 +152,7 @@ NetworkWindow::~NetworkWindow()
void NetworkWindow::addOutgoingMessage(QObject *connection, const QByteArray &message)
{
ConnectionEntry *entry = getConnectionEntry(connection);
QString html = "<p style='margin: 0; color: #FF3300'><hr style='padding: 0; margin: 0;'>" + formatMessage(entry, false, message) + "</p>\n";
QString html( "<p style='margin: 0; color: #FF3300'><hr style='padding: 0; margin: 0;'>" + formatMessage(entry, false, message) + "</p>\n" );
addMessage(entry, html);
}
@@ -173,7 +175,7 @@ NetworkWindow::~NetworkWindow()
// Return a log description for a standard command.
QString NetworkWindow::describeCommand(const QString &command)
{
QString firstPart = command.left(3); // command[0] in normal code.
QString firstPart( command.left(3) ); // command[0] in normal code.
int errorCode = firstPart.toInt();
if( errorCode != 0 )
@@ -357,7 +359,7 @@ NetworkWindow::~NetworkWindow()
}
// Return a description based on the content type
QString contentType = rx.cap(1);
QString contentType( rx.cap(1) );
// Notification server messages
@@ -369,17 +371,17 @@ NetworkWindow::~NetworkWindow()
else if( contentType == "text/x-msmsgsinitialemailnotification" )
{
// The initial status of the mailbox
return formatDescription("Initial e-mail status message");
return formatDescription("Initial email status message");
}
else if( contentType == "text/x-msmsgsemailnotification" )
{
// A new e-mail was received
return formatDescription("New e-mail notification message");
// A new email was received
return formatDescription("New email notification message");
}
else if( contentType == "text/x-msmsgsactivemailnotification" )
{
// The number of unread e-mails has changed
return formatDescription("E-mail activity message");
// The number of unread emails has changed
return formatDescription("Email activity message");
}
else if( contentType == "application/x-msmsgssystemmessage" )
{
@@ -389,7 +391,7 @@ NetworkWindow::~NetworkWindow()
else if( contentType == "text/x-msmsgsinitialmdatanotification" )
{
// Another contact sent an Offline-IM, which is received upon logging-in
return formatDescription("Offline-IM notification or Hotmail e-mail status");
return formatDescription("Offline-IM notification or Hotmail email status");
}
else if( contentType == "text/x-msmsgsoimnotification" )
{
@@ -490,12 +492,13 @@ NetworkWindow::~NetworkWindow()
switch( flags )
{
case 0:
case 0x1000000: // since WLM 2009
// Check for abuse of the P2P system (datacast emulation)
if( sessionId == 64 )
{
if( dataOffset > 0 )
{
QString partName = ( dataOffset + dataSize ) >= totalSize ? "last part" : "next part";
QString partName( ( dataOffset + dataSize ) >= totalSize ? "last part" : "next part" );
return formatDescription("Ink message over P2P, " + partName);
}
else
@@ -504,6 +507,15 @@ NetworkWindow::~NetworkWindow()
}
}
// Another awkward data message (webcam setup)
if( sessionId != 0
&& flags == 0
&& dataSize >= 18
&& message[ headerStart + 48 ] == '\x80' )
{
return formatDescription("Webcam setup message");
}
// No flags means the contents is a string with SLP-like mime fields, used to negotiate the session.
// datasize of 0 is not handed here, is an invalid packet.
// KMess does parse it as ACK message for compatibility with broken clients.
@@ -513,13 +525,13 @@ NetworkWindow::~NetworkWindow()
}
else if( dataOffset > 0 )
{
QString partName = ( dataOffset + dataSize ) >= totalSize ? "last part" : "next part";
QString partName( ( dataOffset + dataSize ) >= totalSize ? "last part" : "next part" );
return formatDescription("P2P Session negotiation message, " + partName);
}
else if( sessionId == 0 && dataSize > 4 )
{
int preambleStart = headerStart + 48;
QString slpMessage = QString::fromUtf8( message.data() + preambleStart, message.size() - preambleStart - 5 ); // last 5 is for the footer code.
QString slpMessage ( QString::fromUtf8( message.data() + preambleStart, message.size() - preambleStart - 5 ) ); // last 5 is for the footer code.
bool isTransfer = slpMessage.contains("Content-Type: application/x-msnmsgr-trans");
if( slpMessage.startsWith("INVITE ") )
{
@@ -603,6 +615,7 @@ NetworkWindow::~NetworkWindow()
"ackSid " + QString::number(ackSessionId) + ", session should terminate");
case 0x20:
case 0x1000020: // since WLM 2009
return formatDescription("P2P MsnObject data,"
" bytes " + QString::number(dataOffset) + "-" + QString::number(dataOffset + dataSize) +
" of " + QString::number(totalSize));
@@ -681,7 +694,8 @@ NetworkWindow::~NetworkWindow()
entry->type = TYPE_SB;
}
else if( memcmp(message.data(), "GET ", 4) == 0
|| memcmp(message.data(), "POST ", 5) == 0)
|| memcmp(message.data(), "POST ", 5) == 0
|| memcmp(message.data(), "<?xml", 5) == 0)
{
entry->type = TYPE_HTTP;
}
@@ -747,7 +761,7 @@ NetworkWindow::~NetworkWindow()
// Assume it's a standard connection.
default:
// Convert the message to UTF-8
QString utf8Message = QString::fromUtf8( message.data(), message.size() );
QString utf8Message( QString::fromUtf8( message.data(), message.size() ) );
// Treat Mime messages with P2P content different.
if( utf8Message.contains("Content-Type: application/x-msnmsgrp2p") )
@@ -757,7 +771,7 @@ NetworkWindow::~NetworkWindow()
if( mimeEnd != -1 )
{
// Extract the first utf-8 mime part, locate start of p2p header
QString p2pMimePart = utf8Message.left(mimeEnd + 4);
QString p2pMimePart( utf8Message.left(mimeEnd + 4) );
int headerStart = p2pMimePart.toUtf8().size(); // convert mimeEnd index, utf-8 may have double characters
// Add the mime part and binary p2p part
@@ -862,7 +876,7 @@ NetworkWindow::~NetworkWindow()
}
// Show header information
logMessage += formatRawData(incoming, message, headerStart, 48, 16);
logMessage += formatRawData(incoming, message, headerStart, 48, 4, 16);
// Add header debug details
logMessage += "<font color='#333333'>";
@@ -887,29 +901,40 @@ NetworkWindow::~NetworkWindow()
logMessage += "</font>";
// The message a utf-8 (MSNSLP) payload if the session id is zero.
const char *dataPtr = ( message.data() + p2pDataStart );
bool hasSlpPayload = ( sessionId == 0 && dataSize > 0 );
int dataEnd = ( p2pDataStart + dataSize );
int realEnd = ( message.size() );
int safeEnd = qMin( message.size(), (int) ( p2pDataStart + dataSize ) );
int safeSize = qMin( (int) dataSize, ( message.size() - p2pDataStart ) );
if( hasSlpPayload )
{
// See if the SLP body is terminated with a final null character (should be).
bool hasSlpNullEnd = ( message[ dataEnd - 1 ] == 0x00 );
int slpLength = safeSize;
bool hasSlpNullEnd = ( message[ p2pDataStart + slpLength - 1 ] == 0x00 );
if( hasSlpNullEnd )
{
dataEnd--;
slpLength--;
}
// Display the SLP body
QString slpMessage = QString::fromUtf8( message.data() + p2pDataStart, qMin( dataSize, (quint32) qMin( dataEnd, realEnd ) - p2pDataStart ) );
logMessage += "\n<br>" + formatString(slpMessage);
QString slpMessage( QString::fromUtf8( dataPtr, slpLength ) );
logMessage += "\n<br>" + formatString( slpMessage );
// Add message footer
if( hasSlpNullEnd )
{
// Display the \0 that QString::fromUtf8() silently dropped
logMessage += formatRawData( incoming, message, dataEnd, 1 );
// Display the \0 that was dropped in the QString::fromUtf8() call.
logMessage += formatRawData( incoming, message, slpLength, 1 );
}
}
else if( dataSize >= 18 && message[ p2pDataStart ] == '\x80' )
{
// Webcam invitation
QString camMessage( QString::fromUtf16( reinterpret_cast<const ushort *>( dataPtr + 10 ), ( safeSize - 10 - 1 ) / 2 ) );
logMessage += "\n<br>" + formatRawData( incoming, message, p2pDataStart, 10, 1 ) // 1 per col.
+ "\n<br>" + formatString( camMessage )
+ "\n<br>" + formatRawData( incoming, message, safeEnd - 2, 2 ); // final null (in utf16).
}
else
{
// Don't display the data.
@@ -918,10 +943,9 @@ NetworkWindow::~NetworkWindow()
// Display the remaining bytes, if any.
// This is the footer when the p2p message is sent over the SB.
int remainingBytes = ( message.size() - dataEnd );
if( remainingBytes > 0 )
if( safeEnd < message.size() )
{
logMessage += "<br>" + formatRawData( incoming, message, dataEnd, remainingBytes );
logMessage += "<br>" + formatRawData( incoming, message, safeEnd, message.size() - safeEnd );
}
return logMessage;
@@ -930,7 +954,7 @@ NetworkWindow::~NetworkWindow()
// Format a utf-8 string to be displayed
QString NetworkWindow::formatRawData(bool incoming, const QByteArray &message, const int start, const int length, const int bytesPerRow)
QString NetworkWindow::formatRawData(bool incoming, const QByteArray &message, const int start, const int length, const int bytesPerCol, const int bytesPerRow)
{
QString logMessage;
logMessage += "<tt><font color=";
@@ -949,7 +973,7 @@ NetworkWindow::~NetworkWindow()
{
logMessage += "<br>";
}
else if( i % 4 == 0 )
else if( i % bytesPerCol == 0 )
{
logMessage += " ";
}
@@ -974,7 +998,7 @@ NetworkWindow::~NetworkWindow()
QString NetworkWindow::formatString(const QString &message)
{
// Parse any HTML characters.
QString logMessage = Qt::escape( message );
QString logMessage( Qt::escape( message ) );
// Format newline characters
logMessage = logMessage.replace("\r\n", "<tt><font color=gray>\\r\\n</font></tt><br>");
@@ -1009,6 +1033,9 @@ NetworkWindow::~NetworkWindow()
// Add new tab
connectionTabs_->addTab( entry->logView, KIcon( "edit-select-all" ), connection->objectName() );
// Enable the Close All Tabs button
enableButton( User3, ( connectionViews_.count() > 1 ) );
}
// Initialize new connections and reinitialize old ones as open
@@ -1067,15 +1094,13 @@ NetworkWindow::~NetworkWindow()
return;
QString path;
QString name = connectionTabs_->tabText( connectionTabs_->currentIndex() );
QString name( connectionTabs_->tabText( connectionTabs_->currentIndex() ) );
path = KFileDialog::getSaveFileName( KUrl(), "*.html" );
if( path.isEmpty() )
return;
#ifdef KMESSDEBUG_CHATWINDOW_GENERAL
kDebug() << "NetworkWindow - saving network log for window '" << name << "' to '" << path << "'.";
#endif
bool failed = false;
@@ -1088,7 +1113,7 @@ NetworkWindow::~NetworkWindow()
}
// Output the HTML with the right text encoding
QString text = static_cast<KTextBrowser *>( connectionTabs_->currentWidget() )->toHtml();
QString text( static_cast<KTextBrowser *>( connectionTabs_->currentWidget() )->toHtml() );
QTextStream textStream( &file );
textStream.setCodec( QTextCodec::codecForLocale() );
textStream << text;
@@ -1114,6 +1139,31 @@ NetworkWindow::~NetworkWindow()
// The 'close all tabs' button was pressed.
void NetworkWindow::closeAllTabs()
{
// Activate the tab of the main connection
connectionTabs_->setCurrentIndex( 0 );
// Get the main connection widget
QWidget *mainConnectionWidget = connectionTabs_->widget( 0 );
// Loop through all tabs
foreach( ConnectionEntry *entry, connectionViews_.values() )
{
// Don't close the main connection tab
if( entry->logView == mainConnectionWidget )
{
continue;
}
connectionTabs_->removeTab( connectionTabs_->indexOf( entry->logView ) );
closeTab( entry->logView );
}
}
// A 'close tab' button was pressed.
void NetworkWindow::closeTab( QWidget *removedWidget )
{
@@ -1138,6 +1188,9 @@ NetworkWindow::~NetworkWindow()
// Delete the page of the removed item
delete removedWidget;
// Disable the Close All Tabs button when there are no tabs
enableButton( User3, ( connectionViews_.count() > 1 ) );
}
@@ -1213,8 +1266,8 @@ NetworkWindow::~NetworkWindow()
// Warn the developer about what he or she is doing.
int result = KMessageBox::warningContinueCancel( this,
i18n( "Sending commands to the server is a risky operation.<br />"
"If you don't know how exactly send messages to the servers,"
"you could be lucky and just get disconnected, or <i>you may"
"If you don't know how to exactly do it, "
"you could be lucky and just get disconnected, or <i>you may "
"incur in more serious consequences</i>.<br />"
"You have been warned!<br />"
"<b>Do you want to continue sending this message?</b>" ),
@@ -1325,6 +1378,3 @@ NetworkWindow::~NetworkWindow()
#include "networkwindow.moc"
#endif // KMESS_NETWORK_WINDOW