You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdewebdev/klinkstatus/src/ui/tablelinkstatus.cpp

751 lines
21 KiB

/***************************************************************************
* Copyright (C) 2004 by Paulo Moura Guedes *
* moura@tdewebdev.org *
* *
* 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) any later version. *
* *
* 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, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
#include "tablelinkstatus.h"
#include "../utils/utils.h"
#include "../parser/url.h"
#include "../global.h"
#include <tqmemarray.h>
#include <tqtooltip.h>
#include <tqpixmap.h>
#include <tqclipboard.h>
#include <tqpainter.h>
#include <tqprocess.h>
#include <kapplication.h>
#include <kstandarddirs.h>
#include <krun.h>
#include <kiconloader.h>
#include <klocale.h>
#include <kmessagebox.h>
#include <dcopclient.h>
#include <dcopref.h>
/*
********************* TableLinkstatus ***************************
*/
TableLinkstatus::TableLinkstatus(TQWidget * parent, const char * name,
int column_index_status,
int column_index_label,
int column_index_URL)
: TQTable(parent, name),
ResultView(column_index_status, column_index_label, column_index_URL)
//context_table_menu_(this, "context_table_menu")
{
setShowGrid(false);
setSorting(false);
setSelectionMode(TQTable::NoSelection);
setFocusStyle(TQTable::FollowStyle);
setReadOnly(true);
verticalHeader()->hide();
setLeftMargin(0);
cell_tip_ = new CellToolTip(this);
sub_menu_ = new TQPopupMenu(this, "sub_menu_referrers");
connect(this, TQT_SIGNAL( contextMenuRequested ( int, int, const TQPoint& )),
this, TQT_SLOT( slotPopupContextMenu( int, int, const TQPoint&)) );
}
TableLinkstatus::~TableLinkstatus()
{
delete cell_tip_;
}
void TableLinkstatus::setColumns(TQStringList const& columns)
{
ResultView::setColumns(columns);
removeColunas();
setNumCols(columns.size());
TQHeader* horizontal_header = horizontalHeader();
for(uint i = 0; i != columns.size(); ++i)
{
if(i == 0)
{
Q_ASSERT(columns[i] == i18n("Status") && col_status_ == 1);
setColumnWidth(i, STATUS_COLUMN_WIDTH);
}
else if(i == 1)
{
Q_ASSERT(columns[i] == i18n("Label") && col_label_ == 2);
setColumnWidth(i, width() / 3);
}
else if(i == 2)
Q_ASSERT(columns[i] == i18n("URL") && col_url_ == 3);
horizontal_header->setLabel(i, i18n(columns[i]));
}
setColumnStretchable(col_url_ - 1, true);
horizontal_header->adjustHeaderSize();
}
void TableLinkstatus::insertResult(LinktqStatus const* linkstatus)
{
insereLinha(generateRowOfTableItems(linkstatus));
}
vector<TableItem*> TableLinkstatus::generateRowOfTableItems(LinktqStatus const* linkstatus)
{
vector<TableItem*> items;
int column = 1;
TableItem* item1 = new TableItemtqStatus(this, TQTableItem::Never,
linkstatus, column++);
TableItem* item2 = new TableItemNome(this, TQTableItem::Never,
linkstatus, column++);
TableItem* item3 = new TableItemURL(this, TQTableItem::Never,
linkstatus, column++);
items.push_back(item1);
items.push_back(item2);
items.push_back(item3);
// If more columns are choosed in the settings, create and add the items here
// ...
return items;
}
void TableLinkstatus::insereLinha(vector<TableItem*> items)
{
Q_ASSERT(items.size() == (uint)numCols());
setNumRows(numRows() + 1);
int row = numRows() - 1;
for(vector<TableItem*>::size_type i = 0; i != items.size(); ++i)
{
Q_ASSERT(items[i]);
int col = items[i]->columnIndex() - 1;
setItem(row, col, items[i]);
}
if(items[col_url_ - 1]->tqsizeHint().width() > columnWidth(col_url_ - 1))
{
setColumnStretchable(col_url_ - 1, false);
setColumnWidth(col_url_ - 1, items[col_url_ - 1]->tqsizeHint().width());
}
ensureCellVisible(row, 0);
}
void TableLinkstatus::clear()
{
TQMemArray<int> linhas(numRows());
for(uint i = 0; i != linhas.size(); ++i)
linhas[i] = i + 1;
removeRows(linhas);
Q_ASSERT(numRows() == 0);
}
void TableLinkstatus::removeColunas()
{
TQMemArray<int> columns(numCols());
for(uint i = 0; i != columns.size(); ++i)
columns[i] = i + 1;
removeColumns(columns);
Q_ASSERT(numCols() == 0);
}
void TableLinkstatus::show(ResultView::tqStatus const& status)
{
for(int i = 0; i != numRows(); ++i)
{
int row = i;
TableItem* _item = myItem(row, col_status_);
if(!ResultView::displayableWithtqStatus(_item->linktqStatus(), status))
hideRow(row);
else
showRow(row);
}
}
void TableLinkstatus::showAll()
{
for(int i = 0; i != numRows(); ++i)
showRow(i);
}
/*
void TableLinkstatus::mostraPorStatusCode(int status_code)
{
for(int i = 0; i != numRows(); ++i)
{
int row = i + 1;
TQTableItem* _item = myItem(row, col_status_);
if(status_code != _item->text().toInt())
hideRow(row);
}
}
*/
/**
Use this procedure when you insert a row at the bottom of the table,
and you only want the to scroll down if you were already at the bottom,
before inserting the row.
This allows you to see what's going on on other cells without having
the table always scrolling down when every row is inserted.
*/
void TableLinkstatus::ensureCellVisible(int row, int col)
{
// table viewport is at the bottom
if(rowPos(row - 1) <= (contentsY() + visibleHeight()))
TQTable::ensureCellVisible(row, col);
}
bool TableLinkstatus::textFitsInCell(int row, int col) const
{
TQTableItem* itm(myItem(row, col));
Q_ASSERT(itm);
TQSize size_hint(itm->tqsizeHint());
int visible_width = 0;
if(col == numCols() - 1)
visible_width = contentsX() + visibleWidth();
else
visible_width = columnPos(col) + columnWidth(col);
if(columnPos(col) + size_hint.width() > visible_width)
return false;
else
return true;
}
bool TableLinkstatus::isEmpty() const
{
return numRows() == 0;
}
TableItem* TableLinkstatus::myItem(int row, int col) const
{
TableItem* _item = dynamic_cast<TableItem*> (TQTable::item(row, col));
Q_ASSERT(_item);
return _item;
}
void TableLinkstatus::slotPopupContextMenu(int r, int w, const TQPoint& pos)
{
TableItem* table_item = myItem(r, w);
if(table_item)
{
TQValueVector<KURL> referrers = table_item->linktqStatus()->referrers();
loadContextTableMenu(referrers, table_item->linktqStatus()->isRoot());
context_table_menu_.popup(pos);
}
}
void TableLinkstatus::loadContextTableMenu(TQValueVector<KURL> const& referrers, bool is_root)
{
context_table_menu_.clear();
sub_menu_->clear();
if(!is_root)
{
sub_menu_->insertItem(i18n("All"), this, TQT_SLOT(slotEditReferrersWithQuanta()));
sub_menu_->insertSeparator();
for(uint i = 0; i != referrers.size(); ++i)
{
sub_menu_->insertItem(referrers[i].prettyURL());
}
connect(sub_menu_, TQT_SIGNAL(activated(int)), this, TQT_SLOT(slotEditReferrerWithQuanta(int)));
context_table_menu_.insertItem(SmallIconSet("fileopen"), i18n("Edit Referrer with Quanta"),
sub_menu_);
}
else
{
int id = context_table_menu_.insertItem(SmallIconSet("fileopen"), i18n("Edit Referrer with Quanta"));
context_table_menu_.setItemEnabled(id, false);
}
context_table_menu_.insertItem(SmallIconSet("fileopen"), i18n("Open URL"),
this, TQT_SLOT(slotViewUrlInBrowser()));
context_table_menu_.insertItem(SmallIconSet("fileopen"), i18n("Open Referrer URL"),
this, TQT_SLOT(slotViewParentUrlInBrowser()));
context_table_menu_.insertSeparator();
context_table_menu_.insertItem(SmallIconSet("editcopy"), i18n("Copy URL"),
this, TQT_SLOT(slotCopyUrlToClipboard()));
context_table_menu_.insertItem(SmallIconSet("editcopy"), i18n("Copy Referrer URL"),
this, TQT_SLOT(slotCopyParentUrlToClipboard()));
context_table_menu_.insertItem(SmallIconSet("editcopy"), i18n("Copy Cell Text"),
this, TQT_SLOT(slotCopyCellTextToClipboard()));
}
void TableLinkstatus::slotCopyUrlToClipboard() const
{
TableItem* _item = myItem(currentRow(), currentColumn());
TQString content(_item->linktqStatus()->absoluteUrl().prettyURL());
TQClipboard* cb = kapp->clipboard();
cb->setText(content);
}
void TableLinkstatus::slotCopyParentUrlToClipboard() const
{
TableItem* _item = myItem(currentRow(), currentColumn());
TQString content(_item->linktqStatus()->parent()->absoluteUrl().prettyURL());
TQClipboard* cb = kapp->clipboard();
cb->setText(content);
}
void TableLinkstatus::slotCopyCellTextToClipboard() const
{
TQString cell_text(text(currentRow(), currentColumn()));
TQClipboard* cb = kapp->clipboard();
cb->setText(cell_text);
}
void TableLinkstatus::slotEditReferrersWithQuanta()
{
TableItem* _item = myItem(currentRow(), currentColumn());
TQValueVector<KURL> referrers = _item->linktqStatus()->referrers();
if(Global::isQuantaAvailableViaDCOP())
{
for(uint i = 0; i != referrers.size(); ++i)
slotEditReferrerWithQuanta(referrers[i]);
}
else
{
TQStringList list_urls;
for(uint i = 0; i != referrers.size(); ++i)
list_urls.append(referrers[i].url());
Global::openQuanta(list_urls);
}
}
void TableLinkstatus::slotEditReferrerWithQuanta(int id)
{
int index = sub_menu_->indexOf(id);
if(index == 0)
return;
Q_ASSERT(index != -1);
Q_ASSERT(index != 1); // separator
//kdDebug(23100) << "id: " << id << endl;
//kdDebug(23100) << "index: " << index << endl;
index -= 2; // The list of referrers starts on index = 2
TableItem* _item = myItem(currentRow(), currentColumn());
TQValueVector<KURL> referrers = _item->linktqStatus()->referrers();
Q_ASSERT(index >= 0 && (uint)index < referrers.size());
slotEditReferrerWithQuanta(referrers[index]);
}
void TableLinkstatus::slotEditReferrerWithQuanta(KURL const& url)
{
TQString filePath = url.url();
if(Global::isQuantaAvailableViaDCOP())
{
DCOPRef quanta(Global::quantaDCOPAppId(),"WindowManagerIf");
bool success = quanta.send("openFile", filePath, 0, 0);
if(!success)
{
TQString message = i18n("<qt>File <b>%1</b> cannot be opened. Might be a DCOP problem.</qt>").tqarg(filePath);
KMessageBox::error(parentWidget(), message);
}
}
else
{
TQStringList args(url.url());
Global::openQuanta(args);
}
}
void TableLinkstatus::slotViewUrlInBrowser()
{
TableItem* _item = myItem(currentRow(), currentColumn());
KURL url = _item->linktqStatus()->absoluteUrl();
if(url.isValid())
{
(void) new KRun (url, 0, url.isLocalFile(), true);
}
else
KMessageBox::sorry(this, i18n("Invalid URL."));
}
void TableLinkstatus::slotViewParentUrlInBrowser()
{
TableItem* _item = myItem(currentRow(), currentColumn());
if(_item->linktqStatus()->isRoot())
{
KMessageBox::sorry(this, i18n("ROOT URL."));
}
else
{
LinktqStatus const* ls_parent = _item->linktqStatus()->parent();
Q_ASSERT(ls_parent);
KURL url = ls_parent->absoluteUrl();
if(url.isValid())
(void) new KRun (url, 0, url.isLocalFile(), true);
else
KMessageBox::sorry(this, i18n("Invalid URL."));
}
}
/*
********************* TableItem ***************************
*/
TableItem::TableItem(TQTable* table, EditType et,
LinktqStatus const* linkstatus,
int column_index, int tqalignment)
: TQTableItem(table, et, ""), ResultViewItem(linkstatus, column_index),
/*ls_((LinktqStatus*)linkstatus),
column_index_(column_index),*/ alignment_(tqalignment)
{
//Q_ASSERT(ls_);
//Q_ASSERT(column_index_ > 0);
}
TableItem::~TableItem()
{}
void TableItem::setColumnIndex(int i)
{
Q_ASSERT(i > 0 && i <= table()->numCols());
//column_index_ = i;
ResultViewItem::setColumnIndex(i);
}
int TableItem::columnIndex() const
{
Q_ASSERT(column_index_ <= table()->numCols());
return ResultViewItem::columnIndex();
}
void TableItem::tqsetAlignment(int aFlags)
{
alignment_ = aFlags;
}
int TableItem::tqalignment() const
{
return alignment_;
}
/*
LinktqStatus const* const TableItem::linktqStatus() const
{
Q_ASSERT(ls_);
return ls_;
}
TQColor const& TableItem::textStatusColor() const
{
if(linktqStatus()->errorOccurred())
{
//kdDebug(23100) << "ERROR: " << linkStatus()->error() << ": " << linktqStatus()->absoluteUrl().prettyURL() << endl;
if(linktqStatus()->error() == i18n( "Javascript not supported" ))
return TQt::lightGray;
else
return TQt::red;
}
else if(linktqStatus()->absoluteUrl().hasRef())
return TQt::blue;
else if(linktqStatus()->absoluteUrl().protocol() != "http" &&
linktqStatus()->absoluteUrl().protocol() != "https")
return TQt::darkGreen;
else
{
TQString status_code(TQString::number(linktqStatus()->httpHeader().statusCode()));
if(status_code[0] == '0')
{
kdWarning(23100) << "status code == 0: " << endl;
kdWarning(23100) << linktqStatus()->toString() << endl;
kdWarning(23100) << linktqStatus()->httpHeader().toString() << endl;
}
//Q_ASSERT(status_code[0] != '0');
if(status_code[0] == '5')
return TQt::darkMagenta;
else if(status_code[0] == '4')
return TQt::red;
else if(status_code[0] == '3')
return TQt::blue;
else if(status_code[0] == '2')
return TQt::darkGreen;
else
return TQt::red;
}
}
*/
/*
********************* TableItemURL ***************************
*/
TableItemURL::TableItemURL(TQTable* table, EditType et,
LinktqStatus const* linkstatus, int column_index)
: TableItem(table, et, linkstatus, column_index)
{
setText();
}
void TableItemURL::setText()
{
if(linktqStatus()->node() && linktqStatus()->malformed())
{
if(linktqStatus()->node()->url().isEmpty())
TQTableItem::setText( linktqStatus()->node()->content().simplifyWhiteSpace() );
else
TQTableItem::setText( linktqStatus()->node()->url() );
}
else
{
KURL url = linktqStatus()->absoluteUrl();
TQTableItem::setText(::convertToLocal(linktqStatus()));
}
}
void TableItemURL::setPixmap()
{}
TQString TableItemURL::toolTip() const
{
return text(); // Pode parecer repeticao mas nao eh... Ver construtor
}
void TableItemURL::paint( TQPainter *p, const TQColorGroup &cg,
const TQRect &cr, bool selected )
{
// Get a color to draw the text
TQColorGroup m_cg(cg);
TQColor color(textStatusColor());
m_cg.setColor(TQColorGroup::Text, color);
TQTableItem::paint(p, m_cg, cr, selected);
}
TQColor const& TableItemURL::textStatusColor() const
{
// TODO clean this code
TQString status_code(TQString::number(linktqStatus()->httpHeader().statusCode()));
if(linktqStatus()->errorOccurred())
{
if(linktqStatus()->error().contains(i18n( "Timeout" )))
return darkMagenta;
else if(linktqStatus()->error().contains(i18n( "not supported" )))
return lightGray;
else
return red;
}
else if(linktqStatus()->absoluteUrl().protocol() != "http" &&
linktqStatus()->absoluteUrl().protocol() != "https")
return black;
else if(status_code[0] == '5')
return darkMagenta;
else if(status_code[0] == '4')
return red;
else
return black;
}
/*
********************* TableItemtqStatus ***************************
*/
TableItemtqStatus::TableItemtqStatus(TQTable* table, EditType et,
LinktqStatus const* linkstatus, int column_index)
: TableItem(table, et, linkstatus, column_index)
{
tqsetAlignment(TQt::AlignHCenter /*| TQt :: AlignVCenter*/);
setText();
setPixmap();
}
void TableItemtqStatus::setText()
{
if(linktqStatus()->errorOccurred() ||
linktqStatus()->status() == "OK" ||
linktqStatus()->status() == "304")
{
TQTableItem::setText("");
}
else
{
/*
if(linktqStatus()->httpHeader().statusCode() == 0)
{
kdDebug(23100) << "TableItemStatus::setText : statusCode() == 0" << endl;
kdDebug(23100) << linktqStatus()->toString() << endl;
kdDebug(23100) << linktqStatus()->docHtml() << endl;
}
*/
//Q_ASSERT(linktqStatus()->httpHeader().statusCode() != 0); //<------------------------------------------------------------
//TQTableItem::setText( TQString::number(linktqStatus()->httpHeader().statusCode()) );
TQTableItem::setText( linktqStatus()->status() );
}
}
void TableItemtqStatus::setPixmap()
{
if(linktqStatus()->errorOccurred())
{
if(linktqStatus()->error().contains(i18n( "Timeout" )))
{
TQTableItem::setPixmap(SmallIcon("kalarm"));
}
else if(linktqStatus()->error() == i18n( "Malformed" ))
{
TQTableItem::setPixmap(SmallIcon("bug"));
}
else
{
TQTableItem::setPixmap(SmallIcon("no"));
}
}
else if(linktqStatus()->status() == "304")
TQTableItem::setPixmap(UserIcon("304"));
else if(linktqStatus()->status() == "OK")
TQTableItem::setPixmap(SmallIcon("ok"));
}
TQString TableItemtqStatus::toolTip() const
{
if(linktqStatus()->errorOccurred() ||
linktqStatus()->absoluteUrl().hasRef() ||
(linktqStatus()->absoluteUrl().protocol() != "http" &&
linktqStatus()->absoluteUrl().protocol() != "https"))
{
return i18n("%1").tqarg(linktqStatus()->status());
}
else
return i18n("%1").tqarg(linktqStatus()->httpHeader().reasonPhrase());
}
void TableItemtqStatus::paint( TQPainter *p, const TQColorGroup &cg,
const TQRect &cr, bool selected )
{
p->fillRect( 0, 0, cr.width(), cr.height(),
selected ? cg.brush( TQColorGroup::Highlight )
: cg.brush( TQColorGroup::Base ) );
int w = cr.width();
int h = cr.height();
int x = 0;
if ( !pixmap().isNull() )
{
p->drawPixmap( ( w - pixmap().width() ) / 2,
( h - pixmap().height() ) / 2,
pixmap() );
x = pixmap().width() + 2;
}
// Get a color to draw the text
TQColorGroup m_cg(cg);
TQColor color(textStatusColor());
m_cg.setColor(TQColorGroup::Text, color);
//TQTableItem::paint(p, m_cg, cr, selected);
if ( selected )
p->setPen( m_cg.highlightedText() );
else
p->setPen( m_cg.text() );
p->drawText( x + 2, 0, w - x - 4, h,
wordWrap() ? (tqalignment() | WordBreak) : tqalignment(), text() );
}
/*
********************* TableItemNome ***************************
*/
TableItemNome::TableItemNome(TQTable* table, EditType et,
LinktqStatus const* linkstatus, int column_index)
: TableItem(table, et, linkstatus, column_index)
{
setText();
}
void TableItemNome::setText()
{
TQString label(linktqStatus()->label());
if(!label.isNull())
TQTableItem::setText(label.simplifyWhiteSpace());
}
void TableItemNome::setPixmap()
{}
TQString TableItemNome::toolTip() const
{
return text(); // Pode parecer repeticao mas nao eh... Ver construtor
}
#include "tablelinkstatus.moc"