mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-07-31 11:20:22 +02:00
Merge branch 'master' into osxrelesae
This commit is contained in:
@@ -197,4 +197,3 @@ ResolversModel::addInstalledResolvers()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -11,6 +11,7 @@ set( jabberSources
|
|||||||
tomahawksipmessage.cpp
|
tomahawksipmessage.cpp
|
||||||
tomahawksipmessagefactory.cpp
|
tomahawksipmessagefactory.cpp
|
||||||
avatarmanager.cpp
|
avatarmanager.cpp
|
||||||
|
xmlconsole.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
set( jabberHeaders
|
set( jabberHeaders
|
||||||
@@ -18,10 +19,12 @@ set( jabberHeaders
|
|||||||
tomahawksipmessage.h
|
tomahawksipmessage.h
|
||||||
tomahawksipmessagefactory.h
|
tomahawksipmessagefactory.h
|
||||||
avatarmanager.h
|
avatarmanager.h
|
||||||
|
xmlconsole.h
|
||||||
)
|
)
|
||||||
|
|
||||||
set( jabberUI
|
set( jabberUI
|
||||||
configwidget.ui
|
configwidget.ui
|
||||||
|
xmlconsole.ui
|
||||||
)
|
)
|
||||||
|
|
||||||
include_directories( . ${CMAKE_CURRENT_BINARY_DIR} ..
|
include_directories( . ${CMAKE_CURRENT_BINARY_DIR} ..
|
||||||
|
@@ -6,6 +6,7 @@ set( googleHeaders
|
|||||||
../tomahawksipmessage.h
|
../tomahawksipmessage.h
|
||||||
../tomahawksipmessagefactory.h
|
../tomahawksipmessagefactory.h
|
||||||
../avatarmanager.h
|
../avatarmanager.h
|
||||||
|
../xmlconsole.h
|
||||||
googlewrapper.h )
|
googlewrapper.h )
|
||||||
|
|
||||||
set( googleSources
|
set( googleSources
|
||||||
@@ -13,13 +14,14 @@ set( googleSources
|
|||||||
../tomahawksipmessage.cpp
|
../tomahawksipmessage.cpp
|
||||||
../tomahawksipmessagefactory.cpp
|
../tomahawksipmessagefactory.cpp
|
||||||
../avatarmanager.cpp
|
../avatarmanager.cpp
|
||||||
|
../xmlconsole.cpp
|
||||||
googlewrapper.cpp )
|
googlewrapper.cpp )
|
||||||
|
|
||||||
add_definitions(-DGOOGLE_WRAPPER)
|
add_definitions(-DGOOGLE_WRAPPER)
|
||||||
|
|
||||||
qt4_add_resources( RCX_SRCS "resources.qrc" )
|
qt4_add_resources( RCX_SRCS "resources.qrc" )
|
||||||
|
|
||||||
qt4_wrap_cpp( googleMoc ../jabber.h ../avatarmanager.h googlewrapper.h )
|
qt4_wrap_cpp( googleMoc ${googleHeaders} )
|
||||||
add_library( tomahawk_sipgoogle SHARED ${googleSources} ${googleMoc} ${googleMoc} ${RCX_SRCS} )
|
add_library( tomahawk_sipgoogle SHARED ${googleSources} ${googleMoc} ${googleMoc} ${RCX_SRCS} )
|
||||||
|
|
||||||
target_link_libraries( tomahawk_sipgoogle
|
target_link_libraries( tomahawk_sipgoogle
|
||||||
|
@@ -18,6 +18,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "jabber.h"
|
#include "jabber.h"
|
||||||
|
#include "ui_configwidget.h"
|
||||||
|
|
||||||
|
#include "xmlconsole.h"
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
@@ -43,8 +46,6 @@
|
|||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
|
||||||
#include "ui_configwidget.h"
|
|
||||||
|
|
||||||
SipPlugin*
|
SipPlugin*
|
||||||
JabberFactory::createPlugin( const QString& pluginId )
|
JabberFactory::createPlugin( const QString& pluginId )
|
||||||
{
|
{
|
||||||
@@ -60,7 +61,7 @@ JabberFactory::icon() const
|
|||||||
JabberPlugin::JabberPlugin( const QString& pluginId )
|
JabberPlugin::JabberPlugin( const QString& pluginId )
|
||||||
: SipPlugin( pluginId )
|
: SipPlugin( pluginId )
|
||||||
, m_menu( 0 )
|
, m_menu( 0 )
|
||||||
, m_addFriendAction( 0 )
|
, m_xmlConsole( 0 )
|
||||||
, m_state( Disconnected )
|
, m_state( Disconnected )
|
||||||
{
|
{
|
||||||
qDebug() << Q_FUNC_INFO;
|
qDebug() << Q_FUNC_INFO;
|
||||||
@@ -92,6 +93,13 @@ JabberPlugin::JabberPlugin( const QString& pluginId )
|
|||||||
m_currentResource = QString::fromAscii( "tomahawk%1" ).arg( QString::number( qrand() % 10000 ) );
|
m_currentResource = QString::fromAscii( "tomahawk%1" ).arg( QString::number( qrand() % 10000 ) );
|
||||||
m_client->setResource( m_currentResource );
|
m_client->setResource( m_currentResource );
|
||||||
|
|
||||||
|
// instantiate XmlConsole
|
||||||
|
if( readXmlConsoleEnabled() )
|
||||||
|
{
|
||||||
|
m_xmlConsole = new XmlConsole( m_client );
|
||||||
|
m_xmlConsole->show();
|
||||||
|
}
|
||||||
|
|
||||||
// add VCardUpdate extension to own presence
|
// add VCardUpdate extension to own presence
|
||||||
m_client->presence().addExtension( new Jreen::VCardUpdate() );
|
m_client->presence().addExtension( new Jreen::VCardUpdate() );
|
||||||
|
|
||||||
@@ -470,6 +478,12 @@ JabberPlugin::showAddFriendDialog()
|
|||||||
addContact( id );
|
addContact( id );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
JabberPlugin::showXmlConsole()
|
||||||
|
{
|
||||||
|
m_xmlConsole->show();
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
JabberPlugin::checkSettings()
|
JabberPlugin::checkSettings()
|
||||||
{
|
{
|
||||||
@@ -531,9 +545,15 @@ void JabberPlugin::addMenuHelper()
|
|||||||
if( !m_menu )
|
if( !m_menu )
|
||||||
{
|
{
|
||||||
m_menu = new QMenu( QString( "%1 (" ).arg( friendlyName() ).append( accountName() ).append(")" ) );
|
m_menu = new QMenu( QString( "%1 (" ).arg( friendlyName() ).append( accountName() ).append(")" ) );
|
||||||
m_addFriendAction = m_menu->addAction( "Add Friend..." );
|
|
||||||
|
|
||||||
connect( m_addFriendAction, SIGNAL( triggered() ), this, SLOT( showAddFriendDialog() ) );
|
QAction* addFriendAction = m_menu->addAction( tr( "Add Friend..." ) );
|
||||||
|
connect( addFriendAction, SIGNAL( triggered() ), this, SLOT( showAddFriendDialog() ) );
|
||||||
|
|
||||||
|
if( readXmlConsoleEnabled() )
|
||||||
|
{
|
||||||
|
QAction* showXmlConsoleAction = m_menu->addAction( tr( "XML Console...") );
|
||||||
|
connect( showXmlConsoleAction, SIGNAL( triggered() ), this, SLOT( showXmlConsole() ) );
|
||||||
|
}
|
||||||
|
|
||||||
emit addMenu( m_menu );
|
emit addMenu( m_menu );
|
||||||
}
|
}
|
||||||
@@ -541,13 +561,12 @@ void JabberPlugin::addMenuHelper()
|
|||||||
|
|
||||||
void JabberPlugin::removeMenuHelper()
|
void JabberPlugin::removeMenuHelper()
|
||||||
{
|
{
|
||||||
if( m_menu && m_addFriendAction )
|
if( m_menu )
|
||||||
{
|
{
|
||||||
emit removeMenu( m_menu );
|
emit removeMenu( m_menu );
|
||||||
|
|
||||||
delete m_menu;
|
delete m_menu;
|
||||||
m_menu = 0;
|
m_menu = 0;
|
||||||
m_addFriendAction = 0; // deleted by menu
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -880,6 +899,12 @@ void JabberPlugin::onNewAvatar(const QString& jid)
|
|||||||
emit avatarReceived ( jid, m_avatarManager->avatar( jid ) );
|
emit avatarReceived ( jid, m_avatarManager->avatar( jid ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
JabberPlugin::readXmlConsoleEnabled()
|
||||||
|
{
|
||||||
|
return TomahawkSettings::instance()->value( pluginId() + "/xmlconsole", QVariant( false ) ).toBool();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
QString
|
QString
|
||||||
JabberPlugin::readPassword()
|
JabberPlugin::readPassword()
|
||||||
|
@@ -23,6 +23,7 @@
|
|||||||
#include "sip/SipPlugin.h"
|
#include "sip/SipPlugin.h"
|
||||||
|
|
||||||
#include "avatarmanager.h"
|
#include "avatarmanager.h"
|
||||||
|
#include "xmlconsole.h"
|
||||||
|
|
||||||
#include <jreen/client.h>
|
#include <jreen/client.h>
|
||||||
#include <jreen/disco.h>
|
#include <jreen/disco.h>
|
||||||
@@ -99,6 +100,7 @@ protected:
|
|||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void showAddFriendDialog();
|
void showAddFriendDialog();
|
||||||
|
void showXmlConsole();
|
||||||
void onConnect();
|
void onConnect();
|
||||||
void onDisconnect(Jreen::Client::DisconnectReason reason);
|
void onDisconnect(Jreen::Client::DisconnectReason reason);
|
||||||
|
|
||||||
@@ -115,6 +117,7 @@ private slots:
|
|||||||
void onNewAvatar( const QString &jid );
|
void onNewAvatar( const QString &jid );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool readXmlConsoleEnabled();
|
||||||
QString readPassword();
|
QString readPassword();
|
||||||
QString readServer();
|
QString readServer();
|
||||||
int readPort();
|
int readPort();
|
||||||
@@ -128,8 +131,7 @@ private:
|
|||||||
void handlePeerStatus( const Jreen::JID &jid, Jreen::Presence::Type presenceType );
|
void handlePeerStatus( const Jreen::JID &jid, Jreen::Presence::Type presenceType );
|
||||||
|
|
||||||
QMenu* m_menu;
|
QMenu* m_menu;
|
||||||
QAction* m_addFriendAction;
|
XmlConsole* m_xmlConsole;
|
||||||
|
|
||||||
QString m_currentUsername;
|
QString m_currentUsername;
|
||||||
QString m_currentPassword;
|
QString m_currentPassword;
|
||||||
QString m_currentServer;
|
QString m_currentServer;
|
||||||
|
356
src/sip/jreen/xmlconsole.cpp
Normal file
356
src/sip/jreen/xmlconsole.cpp
Normal file
@@ -0,0 +1,356 @@
|
|||||||
|
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||||
|
*
|
||||||
|
* Copyright 2011, Ruslan Nigmatullin <euroelessar@ya.ru>
|
||||||
|
* Copyright 2011, Dominik Schmidt <dev@dominik-schmidt.de>
|
||||||
|
*
|
||||||
|
* Tomahawk is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Tomahawk is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "xmlconsole.h"
|
||||||
|
#include "ui_xmlconsole.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include <QMenu>
|
||||||
|
#include <QActionGroup>
|
||||||
|
#include <QStringBuilder>
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QTextLayout>
|
||||||
|
#include <QPlainTextDocumentLayout>
|
||||||
|
#include <QFileDialog>
|
||||||
|
#include <QTextDocumentWriter>
|
||||||
|
|
||||||
|
using namespace Jreen;
|
||||||
|
|
||||||
|
XmlConsole::XmlConsole(Client* client, QWidget *parent) :
|
||||||
|
QWidget(parent),
|
||||||
|
m_ui(new Ui::XmlConsole),
|
||||||
|
m_client(client), m_filter(0x1f)
|
||||||
|
{
|
||||||
|
m_ui->setupUi(this);
|
||||||
|
|
||||||
|
m_client->addXmlStreamHandler(this);
|
||||||
|
|
||||||
|
QPalette pal = palette();
|
||||||
|
pal.setColor(QPalette::Base, Qt::black);
|
||||||
|
pal.setColor(QPalette::Text, Qt::white);
|
||||||
|
m_ui->xmlBrowser->viewport()->setPalette(pal);
|
||||||
|
QTextDocument *doc = m_ui->xmlBrowser->document();
|
||||||
|
doc->setDocumentLayout(new QPlainTextDocumentLayout(doc));
|
||||||
|
doc->clear();
|
||||||
|
|
||||||
|
QTextFrameFormat format = doc->rootFrame()->frameFormat();
|
||||||
|
format.setBackground(QColor(Qt::black));
|
||||||
|
format.setMargin(0);
|
||||||
|
doc->rootFrame()->setFrameFormat(format);
|
||||||
|
QMenu *menu = new QMenu(m_ui->filterButton);
|
||||||
|
menu->setSeparatorsCollapsible(false);
|
||||||
|
menu->addSeparator()->setText(tr("Filter"));
|
||||||
|
QActionGroup *group = new QActionGroup(menu);
|
||||||
|
QAction *disabled = group->addAction(menu->addAction(tr("Disabled")));
|
||||||
|
disabled->setCheckable(true);
|
||||||
|
disabled->setData(Disabled);
|
||||||
|
QAction *jid = group->addAction(menu->addAction(tr("By JID")));
|
||||||
|
jid->setCheckable(true);
|
||||||
|
jid->setData(ByJid);
|
||||||
|
QAction *xmlns = group->addAction(menu->addAction(tr("By namespace uri")));
|
||||||
|
xmlns->setCheckable(true);
|
||||||
|
xmlns->setData(ByXmlns);
|
||||||
|
QAction *attrb = group->addAction(menu->addAction(tr("By all attributes")));
|
||||||
|
attrb->setCheckable(true);
|
||||||
|
attrb->setData(ByAllAttributes);
|
||||||
|
disabled->setChecked(true);
|
||||||
|
connect(group, SIGNAL(triggered(QAction*)), this, SLOT(onActionGroupTriggered(QAction*)));
|
||||||
|
menu->addSeparator()->setText(tr("Visible stanzas"));
|
||||||
|
group = new QActionGroup(menu);
|
||||||
|
group->setExclusive(false);
|
||||||
|
QAction *iq = group->addAction(menu->addAction(tr("Information query")));
|
||||||
|
iq->setCheckable(true);
|
||||||
|
iq->setData(XmlNode::Iq);
|
||||||
|
iq->setChecked(true);
|
||||||
|
QAction *message = group->addAction(menu->addAction(tr("Message")));
|
||||||
|
message->setCheckable(true);
|
||||||
|
message->setData(XmlNode::Message);
|
||||||
|
message->setChecked(true);
|
||||||
|
QAction *presence = group->addAction(menu->addAction(tr("Presence")));
|
||||||
|
presence->setCheckable(true);
|
||||||
|
presence->setData(XmlNode::Presence);
|
||||||
|
presence->setChecked(true);
|
||||||
|
QAction *custom = group->addAction(menu->addAction(tr("Custom")));
|
||||||
|
custom->setCheckable(true);
|
||||||
|
custom->setData(XmlNode::Custom);
|
||||||
|
custom->setChecked(true);
|
||||||
|
connect(group, SIGNAL(triggered(QAction*)), this, SLOT(onActionGroupTriggered(QAction*)));
|
||||||
|
m_ui->filterButton->setMenu(menu);
|
||||||
|
m_stackBracketsColor = QColor(0x666666);
|
||||||
|
m_stackIncoming.bodyColor = QColor(0xbb66bb);
|
||||||
|
m_stackIncoming.tagColor = QColor(0x006666);
|
||||||
|
m_stackIncoming.attributeColor = QColor(0x009933);
|
||||||
|
m_stackIncoming.paramColor = QColor(0xcc0000);
|
||||||
|
m_stackOutgoing.bodyColor = QColor(0x999999);
|
||||||
|
m_stackOutgoing.tagColor = QColor(0x22aa22);
|
||||||
|
m_stackOutgoing.attributeColor = QColor(0xffff33);
|
||||||
|
m_stackOutgoing.paramColor = QColor(0xdd8811);
|
||||||
|
|
||||||
|
QAction *action = new QAction(tr("Close"),this);
|
||||||
|
action->setSoftKeyRole(QAction::NegativeSoftKey);
|
||||||
|
connect(action, SIGNAL(triggered()), SLOT(close()));
|
||||||
|
addAction(action);
|
||||||
|
}
|
||||||
|
|
||||||
|
XmlConsole::~XmlConsole()
|
||||||
|
{
|
||||||
|
delete m_ui;
|
||||||
|
}
|
||||||
|
|
||||||
|
void XmlConsole::handleStreamBegin()
|
||||||
|
{
|
||||||
|
m_stackIncoming.reader.clear();
|
||||||
|
m_stackOutgoing.reader.clear();
|
||||||
|
m_stackIncoming.depth = 0;
|
||||||
|
m_stackOutgoing.depth = 0;
|
||||||
|
qDeleteAll(m_stackIncoming.tokens);
|
||||||
|
qDeleteAll(m_stackOutgoing.tokens);
|
||||||
|
m_stackIncoming.tokens.clear();
|
||||||
|
m_stackOutgoing.tokens.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void XmlConsole::handleStreamEnd()
|
||||||
|
{
|
||||||
|
m_stackIncoming.reader.clear();
|
||||||
|
m_stackOutgoing.reader.clear();
|
||||||
|
m_stackIncoming.depth = 0;
|
||||||
|
m_stackOutgoing.depth = 0;
|
||||||
|
qDeleteAll(m_stackIncoming.tokens);
|
||||||
|
qDeleteAll(m_stackOutgoing.tokens);
|
||||||
|
m_stackIncoming.tokens.clear();
|
||||||
|
m_stackOutgoing.tokens.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void XmlConsole::handleIncomingData(const char *data, qint64 size)
|
||||||
|
{
|
||||||
|
stackProcess(QByteArray::fromRawData(data, size), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void XmlConsole::handleOutgoingData(const char *data, qint64 size)
|
||||||
|
{
|
||||||
|
stackProcess(QByteArray::fromRawData(data, size), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString generate_stacked_space(int depth)
|
||||||
|
{
|
||||||
|
return QString(depth * 2, QLatin1Char(' '));
|
||||||
|
}
|
||||||
|
|
||||||
|
void XmlConsole::stackProcess(const QByteArray &data, bool incoming)
|
||||||
|
{
|
||||||
|
StackEnvironment *d = &(incoming ? m_stackIncoming : m_stackOutgoing);
|
||||||
|
d->reader.addData(data);
|
||||||
|
StackToken *token;
|
||||||
|
// debug() << incoming << data;
|
||||||
|
// debug() << "==================================================================";
|
||||||
|
while (d->reader.readNext() > QXmlStreamReader::Invalid) {
|
||||||
|
// QDebug dbg = debug() << incoming << d->reader.tokenString();
|
||||||
|
switch(d->reader.tokenType()) {
|
||||||
|
case QXmlStreamReader::StartElement:
|
||||||
|
// dbg << d->reader.name().toString() << d->depth
|
||||||
|
// << d->reader.attributes().value(QLatin1String("from")).toString();
|
||||||
|
d->depth++;
|
||||||
|
if (d->depth > 1) {
|
||||||
|
if (!d->tokens.isEmpty() && d->tokens.last()->type == QXmlStreamReader::Characters)
|
||||||
|
delete d->tokens.takeLast();
|
||||||
|
d->tokens << new StackToken(d->reader);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case QXmlStreamReader::EndElement:
|
||||||
|
// dbg << d->reader.name().toString() << d->depth;
|
||||||
|
if (d->tokens.isEmpty())
|
||||||
|
break;
|
||||||
|
token = d->tokens.last();
|
||||||
|
if (token->type == QXmlStreamReader::StartElement && !token->startTag.empty)
|
||||||
|
token->startTag.empty = true;
|
||||||
|
else if (d->depth > 1)
|
||||||
|
d->tokens << new StackToken(d->reader);
|
||||||
|
if (d->depth == 2) {
|
||||||
|
QTextCursor cursor(m_ui->xmlBrowser->document());
|
||||||
|
cursor.movePosition(QTextCursor::End);
|
||||||
|
cursor.beginEditBlock();
|
||||||
|
QTextCharFormat zeroFormat = cursor.charFormat();
|
||||||
|
zeroFormat.setForeground(QColor(Qt::white));
|
||||||
|
QTextCharFormat bodyFormat = zeroFormat;
|
||||||
|
bodyFormat.setForeground(d->bodyColor);
|
||||||
|
QTextCharFormat tagFormat = zeroFormat;
|
||||||
|
tagFormat.setForeground(d->tagColor);
|
||||||
|
QTextCharFormat attributeFormat = zeroFormat;
|
||||||
|
attributeFormat.setForeground(d->attributeColor);
|
||||||
|
QTextCharFormat paramsFormat = zeroFormat;
|
||||||
|
paramsFormat.setForeground(d->paramColor);
|
||||||
|
QTextCharFormat bracketFormat = zeroFormat;
|
||||||
|
bracketFormat.setForeground(m_stackBracketsColor);
|
||||||
|
QString singleSpace = QLatin1String(" ");
|
||||||
|
cursor.insertBlock();
|
||||||
|
int depth = 0;
|
||||||
|
QString currentXmlns;
|
||||||
|
QXmlStreamReader::TokenType lastType = QXmlStreamReader::StartElement;
|
||||||
|
for (int i = 0; i < d->tokens.size(); i++) {
|
||||||
|
token = d->tokens.at(i);
|
||||||
|
if (token->type == QXmlStreamReader::StartElement) {
|
||||||
|
QString space = generate_stacked_space(depth);
|
||||||
|
cursor.insertText(QLatin1String("\n"));
|
||||||
|
cursor.insertText(space);
|
||||||
|
cursor.insertText(QLatin1String("<"), bracketFormat);
|
||||||
|
cursor.insertText(token->startTag.name->toString(), tagFormat);
|
||||||
|
const QStringRef &xmlns = *token->startTag.xmlns;
|
||||||
|
if (i == 0 || xmlns != currentXmlns) {
|
||||||
|
currentXmlns = xmlns.toString();
|
||||||
|
cursor.insertText(singleSpace);
|
||||||
|
cursor.insertText(QLatin1String("xmlns"), attributeFormat);
|
||||||
|
cursor.insertText(QLatin1String("="), zeroFormat);
|
||||||
|
cursor.insertText(QLatin1String("'"), paramsFormat);
|
||||||
|
cursor.insertText(currentXmlns, paramsFormat);
|
||||||
|
cursor.insertText(QLatin1String("'"), paramsFormat);
|
||||||
|
}
|
||||||
|
QXmlStreamAttributes *attributes = token->startTag.attributes;
|
||||||
|
for (int j = 0; j < attributes->count(); j++) {
|
||||||
|
const QXmlStreamAttribute &attr = attributes->at(j);
|
||||||
|
cursor.insertText(singleSpace);
|
||||||
|
cursor.insertText(attr.name().toString(), attributeFormat);
|
||||||
|
cursor.insertText(QLatin1String("="), zeroFormat);
|
||||||
|
cursor.insertText(QLatin1String("'"), paramsFormat);
|
||||||
|
cursor.insertText(attr.value().toString(), paramsFormat);
|
||||||
|
cursor.insertText(QLatin1String("'"), paramsFormat);
|
||||||
|
}
|
||||||
|
if (token->startTag.empty) {
|
||||||
|
cursor.insertText(QLatin1String("/>"), bracketFormat);
|
||||||
|
} else {
|
||||||
|
cursor.insertText(QLatin1String(">"), bracketFormat);
|
||||||
|
depth++;
|
||||||
|
}
|
||||||
|
} else if (token->type == QXmlStreamReader::EndElement) {
|
||||||
|
if (lastType == QXmlStreamReader::EndElement) {
|
||||||
|
QString space = generate_stacked_space(depth - 1);
|
||||||
|
cursor.insertText(QLatin1String("\n"));
|
||||||
|
cursor.insertText(space);
|
||||||
|
}
|
||||||
|
cursor.insertText(QLatin1String("</"), bracketFormat);
|
||||||
|
cursor.insertText(token->endTag.name->toString(), tagFormat);
|
||||||
|
cursor.insertText(QLatin1String(">"), bracketFormat);
|
||||||
|
depth--;
|
||||||
|
} else if (token->type == QXmlStreamReader::Characters) {
|
||||||
|
cursor.setCharFormat(bodyFormat);
|
||||||
|
QString text = token->charachters.text->toString();
|
||||||
|
if (text.contains(QLatin1Char('\n'))) {
|
||||||
|
QString space = generate_stacked_space(depth);
|
||||||
|
space.prepend(QLatin1Char('\n'));
|
||||||
|
QStringList lines = text.split(QLatin1Char('\n'));
|
||||||
|
for (int j = 0; j < lines.size(); j++) {
|
||||||
|
cursor.insertText(space);
|
||||||
|
cursor.insertText(lines.at(j));
|
||||||
|
}
|
||||||
|
space.chop(1);
|
||||||
|
cursor.insertText(space);
|
||||||
|
} else {
|
||||||
|
cursor.insertText(text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lastType = token->type;
|
||||||
|
if (lastType == QXmlStreamReader::StartElement && token->startTag.empty)
|
||||||
|
lastType = QXmlStreamReader::EndElement;
|
||||||
|
delete token;
|
||||||
|
}
|
||||||
|
cursor.endEditBlock();
|
||||||
|
d->tokens.clear();
|
||||||
|
}
|
||||||
|
d->depth--;
|
||||||
|
break;
|
||||||
|
case QXmlStreamReader::Characters:
|
||||||
|
token = d->tokens.isEmpty() ? 0 : d->tokens.last();
|
||||||
|
if (token && token->type == QXmlStreamReader::StartElement && !token->startTag.empty)
|
||||||
|
d->tokens << new StackToken(d->reader);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// QDebug dbg = debug() << d->reader.tokenString();
|
||||||
|
// if (d->reader.tokenType() == QXmlStreamReader::Invalid)
|
||||||
|
// dbg << d->reader.error() << d->reader.errorString();
|
||||||
|
if (!incoming && d->depth > 1) {
|
||||||
|
qFatal("outgoing depth %d on\n\"%s\"", d->depth,
|
||||||
|
qPrintable(QString::fromUtf8(data, data.size())));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void XmlConsole::changeEvent(QEvent *e)
|
||||||
|
{
|
||||||
|
QWidget::changeEvent(e);
|
||||||
|
switch (e->type()) {
|
||||||
|
case QEvent::LanguageChange:
|
||||||
|
m_ui->retranslateUi(this);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void XmlConsole::onActionGroupTriggered(QAction *action)
|
||||||
|
{
|
||||||
|
int type = action->data().toInt();
|
||||||
|
if (type >= 0x10) {
|
||||||
|
m_filter = (m_filter & 0xf) | type;
|
||||||
|
m_ui->lineEdit->setEnabled(type != 0x10);
|
||||||
|
} else {
|
||||||
|
m_filter = m_filter ^ type;
|
||||||
|
}
|
||||||
|
on_lineEdit_textChanged(m_ui->lineEdit->text());
|
||||||
|
}
|
||||||
|
|
||||||
|
void XmlConsole::on_lineEdit_textChanged(const QString &text)
|
||||||
|
{
|
||||||
|
int filterType = m_filter & 0xf0;
|
||||||
|
JID filterJid = (filterType == ByJid) ? text : QString();
|
||||||
|
for (int i = 0; i < m_nodes.size(); i++) {
|
||||||
|
XmlNode &node = m_nodes[i];
|
||||||
|
bool ok = true;
|
||||||
|
switch (filterType) {
|
||||||
|
case ByXmlns:
|
||||||
|
ok = node.xmlns.contains(text);
|
||||||
|
break;
|
||||||
|
case ByJid:
|
||||||
|
ok = node.jid.full() == filterJid.full() || node.jid.bare() == filterJid.full();
|
||||||
|
break;
|
||||||
|
case ByAllAttributes:
|
||||||
|
ok = node.attributes.contains(text);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ok &= bool(node.type & m_filter);
|
||||||
|
node.block.setVisible(ok);
|
||||||
|
node.block.setLineCount(ok ? node.lineCount : 0);
|
||||||
|
// qDebug() << node.block.lineCount();
|
||||||
|
}
|
||||||
|
QAbstractTextDocumentLayout *layout = m_ui->xmlBrowser->document()->documentLayout();
|
||||||
|
Q_ASSERT(qobject_cast<QPlainTextDocumentLayout*>(layout));
|
||||||
|
qobject_cast<QPlainTextDocumentLayout*>(layout)->requestUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
void XmlConsole::on_saveButton_clicked()
|
||||||
|
{
|
||||||
|
QString fileName = QFileDialog::getSaveFileName(this, tr("Save XMPP log to file"),
|
||||||
|
QString(), tr("OpenDocument Format (*.odf);;HTML file (*.html);;Plain text (*.txt)"));
|
||||||
|
if (!fileName.isEmpty()) {
|
||||||
|
QTextDocumentWriter writer(fileName);
|
||||||
|
writer.write(m_ui->xmlBrowser->document());
|
||||||
|
}
|
||||||
|
}
|
176
src/sip/jreen/xmlconsole.h
Normal file
176
src/sip/jreen/xmlconsole.h
Normal file
@@ -0,0 +1,176 @@
|
|||||||
|
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||||
|
*
|
||||||
|
* Copyright 2011, Ruslan Nigmatullin <euroelessar@ya.ru>
|
||||||
|
* Copyright 2011, Dominik Schmidt <dev@dominik-schmidt.de>
|
||||||
|
*
|
||||||
|
* Tomahawk is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Tomahawk is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef XMLCONSOLE_H
|
||||||
|
#define XMLCONSOLE_H
|
||||||
|
|
||||||
|
#include <jreen/client.h>
|
||||||
|
#include <jreen/jid.h>
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
#include <QXmlStreamReader>
|
||||||
|
#include <QDateTime>
|
||||||
|
#include <QTextBlock>
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class XmlConsole;
|
||||||
|
}
|
||||||
|
|
||||||
|
class XmlConsole : public QWidget, public Jreen::XmlStreamHandler
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
XmlConsole(Jreen::Client* client, QWidget *parent = 0);
|
||||||
|
~XmlConsole();
|
||||||
|
|
||||||
|
virtual void handleStreamBegin();
|
||||||
|
virtual void handleStreamEnd();
|
||||||
|
virtual void handleIncomingData(const char *data, qint64 size);
|
||||||
|
virtual void handleOutgoingData(const char *data, qint64 size);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void changeEvent(QEvent *e);
|
||||||
|
private:
|
||||||
|
void stackProcess(const QByteArray &data, bool incoming);
|
||||||
|
|
||||||
|
struct XmlNode
|
||||||
|
{
|
||||||
|
enum Type
|
||||||
|
{
|
||||||
|
Iq = 1,
|
||||||
|
Presence = 2,
|
||||||
|
Message = 4,
|
||||||
|
Custom = 8
|
||||||
|
};
|
||||||
|
QDateTime time;
|
||||||
|
Type type;
|
||||||
|
bool incoming;
|
||||||
|
QSet<QString> xmlns;
|
||||||
|
Jreen::JID jid;
|
||||||
|
QSet<QString> attributes;
|
||||||
|
QTextBlock block;
|
||||||
|
int lineCount;
|
||||||
|
};
|
||||||
|
enum FilterType
|
||||||
|
{
|
||||||
|
Disabled = 0x10,
|
||||||
|
ByJid = 0x20,
|
||||||
|
ByXmlns = 0x30,
|
||||||
|
ByAllAttributes = 0x40
|
||||||
|
};
|
||||||
|
|
||||||
|
enum State
|
||||||
|
{
|
||||||
|
WaitingForStanza,
|
||||||
|
ReadFeatures,
|
||||||
|
ReadStanza,
|
||||||
|
ReadCustom
|
||||||
|
};
|
||||||
|
|
||||||
|
struct StackToken
|
||||||
|
{
|
||||||
|
StackToken(QXmlStreamReader &reader)
|
||||||
|
{
|
||||||
|
type = reader.tokenType();
|
||||||
|
if (type == QXmlStreamReader::StartElement) {
|
||||||
|
QStringRef tmp = reader.name();
|
||||||
|
startTag.namePointer = new QString(*tmp.string());
|
||||||
|
startTag.name = new QStringRef(startTag.namePointer, tmp.position(), tmp.length());
|
||||||
|
tmp = reader.namespaceUri();
|
||||||
|
startTag.xmlnsPointer = new QString(*tmp.string());
|
||||||
|
startTag.xmlns = new QStringRef(startTag.xmlnsPointer, tmp.position(), tmp.length());
|
||||||
|
startTag.attributes = new QXmlStreamAttributes(reader.attributes());
|
||||||
|
startTag.empty = false;
|
||||||
|
} else if (type == QXmlStreamReader::Characters) {
|
||||||
|
QStringRef tmp = reader.text();
|
||||||
|
charachters.textPointer = new QString(*tmp.string());
|
||||||
|
charachters.text = new QStringRef(charachters.textPointer, tmp.position(), tmp.length());
|
||||||
|
} else if (type == QXmlStreamReader::EndElement) {
|
||||||
|
QStringRef tmp = reader.name();
|
||||||
|
endTag.namePointer = new QString(*tmp.string());
|
||||||
|
endTag.name = new QStringRef(endTag.namePointer, tmp.position(), tmp.length());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
~StackToken()
|
||||||
|
{
|
||||||
|
if (type == QXmlStreamReader::StartElement) {
|
||||||
|
delete startTag.namePointer;
|
||||||
|
delete startTag.name;
|
||||||
|
delete startTag.xmlnsPointer;
|
||||||
|
delete startTag.xmlns;
|
||||||
|
delete startTag.attributes;
|
||||||
|
} else if (type == QXmlStreamReader::Characters) {
|
||||||
|
delete charachters.textPointer;
|
||||||
|
delete charachters.text;
|
||||||
|
} else if (type == QXmlStreamReader::EndElement) {
|
||||||
|
delete endTag.namePointer;
|
||||||
|
delete endTag.name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QXmlStreamReader::TokenType type;
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
QString *namePointer;
|
||||||
|
QStringRef *name;
|
||||||
|
QString *xmlnsPointer;
|
||||||
|
QStringRef *xmlns;
|
||||||
|
QXmlStreamAttributes *attributes;
|
||||||
|
bool empty;
|
||||||
|
} startTag;
|
||||||
|
struct {
|
||||||
|
QString *textPointer;
|
||||||
|
QStringRef *text;
|
||||||
|
} charachters;
|
||||||
|
struct {
|
||||||
|
QString *namePointer;
|
||||||
|
QStringRef *name;
|
||||||
|
} endTag;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct StackEnvironment
|
||||||
|
{
|
||||||
|
QXmlStreamReader reader;
|
||||||
|
State state;
|
||||||
|
int depth;
|
||||||
|
QList<StackToken*> tokens;
|
||||||
|
QColor bodyColor;
|
||||||
|
QColor tagColor;
|
||||||
|
QColor attributeColor;
|
||||||
|
QColor paramColor;
|
||||||
|
};
|
||||||
|
|
||||||
|
Ui::XmlConsole *m_ui;
|
||||||
|
Jreen::Client *m_client;
|
||||||
|
QList<XmlNode> m_nodes;
|
||||||
|
StackEnvironment m_stackIncoming;
|
||||||
|
StackEnvironment m_stackOutgoing;
|
||||||
|
QColor m_stackBracketsColor;
|
||||||
|
int m_filter;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void on_lineEdit_textChanged(const QString &);
|
||||||
|
void onActionGroupTriggered(QAction *action);
|
||||||
|
void on_saveButton_clicked();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // XMLCONSOLE_H
|
51
src/sip/jreen/xmlconsole.ui
Normal file
51
src/sip/jreen/xmlconsole.ui
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>XmlConsole</class>
|
||||||
|
<widget class="QWidget" name="XmlConsole">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>400</width>
|
||||||
|
<height>300</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Xml stream console</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<property name="margin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="spacing">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLineEdit" name="lineEdit">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QPushButton" name="filterButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>Filter</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="0" colspan="3">
|
||||||
|
<widget class="QPlainTextEdit" name="xmlBrowser"/>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="2">
|
||||||
|
<widget class="QPushButton" name="saveButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>Save log</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
Reference in New Issue
Block a user