/* ============================================================ * * This file is a part of the rekonq project * * Copyright (C) 2009-2010 by Richard J. Moore * Copyright (C) 2010-2011 by Andrea Diamantini * * * This program 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 2 of * the License or (at your option) version 3 or any later version * accepted by the membership of KDE e.V. (or its successor approved * by the membership of KDE e.V.), which shall act as a proxy * defined in Section 14 of version 3 of the license. * * This program 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 this program. If not, see . * * ============================================================ */ // Self Includes #include "networkanalyzer.h" #include "networkanalyzer.moc" // KDE Includes #include #include #include #include #include // Qt Includes #include #include #include #include #include #include #include NetworkAnalyzer::NetworkAnalyzer(QWidget *parent) : QWidget(parent) , _mapper(new QSignalMapper(this)) , _requestList(new QTreeWidget(this)) { QStringList headers; headers << i18n("Method") << i18n("URL") << i18n("Response") << i18n("Length") << i18n("Content Type") << i18n("Info"); _requestList->setHeaderLabels( headers ); _requestList->header()->setResizeMode(0, QHeaderView::Interactive); _requestList->header()->setResizeMode(1, QHeaderView::Interactive); _requestList->header()->setResizeMode(2, QHeaderView::Interactive); _requestList->header()->setResizeMode(3, QHeaderView::Interactive); _requestList->header()->setResizeMode(4, QHeaderView::Interactive); _requestList->setAlternatingRowColors(true); QVBoxLayout *lay = new QVBoxLayout(this); lay->addWidget( _requestList ); _requestList->setContextMenuPolicy(Qt::CustomContextMenu); connect( _mapper, SIGNAL(mapped(QObject *)), this, SLOT(requestFinished(QObject *)) ); connect( _requestList, SIGNAL(itemDoubleClicked( QTreeWidgetItem*, int ) ), this, SLOT( showItemDetails( QTreeWidgetItem *) ) ); connect( _requestList, SIGNAL(customContextMenuRequested(QPoint) ), this, SLOT( popupContextMenu(QPoint))); } NetworkAnalyzer::~NetworkAnalyzer() { } void NetworkAnalyzer::popupContextMenu(const QPoint& pos) { if(_requestList->topLevelItemCount() >= 1) { KMenu menu(_requestList); KAction *copy; copy = new KAction(KIcon("edit-copy"),i18n("Copy URL"), this); connect(copy,SIGNAL(triggered(bool)),this,SLOT(copyURL())); menu.addAction(copy); menu.exec(mapToGlobal(pos)); } } void NetworkAnalyzer::copyURL() { QClipboard *clipboard = QApplication::clipboard(); clipboard->setText(_requestList->currentItem()->text(1)); } void NetworkAnalyzer::addRequest( QNetworkAccessManager::Operation op, const QNetworkRequest &req, QNetworkReply *reply ) { // Add to list of requests QStringList cols; switch( op ) { case QNetworkAccessManager::HeadOperation: cols << QL1S("HEAD"); break; case QNetworkAccessManager::GetOperation: cols << QL1S("GET"); break; case QNetworkAccessManager::PutOperation: cols << QL1S("PUT"); break; case QNetworkAccessManager::PostOperation: cols << QL1S("POST"); break; case QNetworkAccessManager::DeleteOperation: cols << QL1S("DELETE"); break; case QNetworkAccessManager::CustomOperation: cols << QL1S("CUSTOM"); break; default: kDebug() << "Unknown network operation"; } cols << req.url().toString(); cols << i18n("Pending"); QTreeWidgetItem *item = new QTreeWidgetItem( cols ); _requestList->addTopLevelItem( item ); // Add to maps _requestMap.insert( reply, req ); _itemMap.insert( reply, item ); _itemRequestMap.insert( item, req ); _mapper->setMapping( reply, reply ); connect( reply, SIGNAL( finished() ), _mapper, SLOT( map() ) ); _requestList->header()->resizeSections(QHeaderView::ResizeToContents); } void NetworkAnalyzer::clear() { _requestMap.clear(); _itemMap.clear(); _itemReplyMap.clear(); _itemRequestMap.clear(); _requestList->clear(); } void NetworkAnalyzer::requestFinished( QObject *replyObject ) { QNetworkReply *reply = qobject_cast( replyObject ); if ( !reply ) { kDebug() << "Failed to downcast reply"; return; } QTreeWidgetItem *item = _itemMap[reply]; // Record the reply headers QList headerValues; foreach(const QByteArray &header, reply->rawHeaderList() ) { headerValues += reply->rawHeader( header ); } QPair< QList, QList > replyHeaders; replyHeaders.first = reply->rawHeaderList(); replyHeaders.second = headerValues; _itemReplyMap[item] = replyHeaders; // Display the request int status = reply->attribute( QNetworkRequest::HttpStatusCodeAttribute ).toInt(); QString reason = reply->attribute( QNetworkRequest::HttpReasonPhraseAttribute ).toString(); item->setText( 2, i18n("%1 %2", status, reason) ); QString length = reply->header( QNetworkRequest::ContentLengthHeader ).toString(); item->setText( 3, length ); QString contentType = reply->header( QNetworkRequest::ContentTypeHeader ).toString(); item->setText( 4, contentType ); if ( status == 302 ) { QUrl target = reply->attribute( QNetworkRequest::RedirectionTargetAttribute ).toUrl(); item->setText( 5, i18n("Redirect: %1", target.toString() ) ); } } void NetworkAnalyzer::showItemDetails( QTreeWidgetItem *item ) { // Show request details QString details; QNetworkRequest req = _itemRequestMap[item]; details += i18n("

Request Details

"); details += QL1S("
    "); foreach(const QByteArray &header, req.rawHeaderList() ) { details += QL1S("
  • "); details += QL1S( header ); details += QL1S(": "); details += QL1S( req.rawHeader( header ) ); details += QL1S("
  • "); } details += QL1S("
"); QPair< QList, QList > replyHeaders = _itemReplyMap[item]; details += i18n("

Response Details

"); details += QL1S("
    "); for ( int i = 0; i < replyHeaders.first.count(); i++ ) { details += QL1S("
  • "); details += QL1S( replyHeaders.first[i] ); details += QL1S(": "); details += QL1S( replyHeaders.second[i] ); details += QL1S("
  • "); } details += QL1S("
"); // QLabel *label = new QLabel(details, this); // KPassivePopup *popup = new KPassivePopup(this); // popup->setView(label); // popup->show(_requestList->mapToGlobal(_requestList->pos())); KPassivePopup::message(details,this); }