Import release 2.0beta1
This commit is contained in:
@@ -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'> <!-- 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'> " + message + "</font></p>\n";
|
||||
QString html( "<p style='margin: 0'><font color='#333333'> " + 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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user