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/treeview.cpp

610 lines
18 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 <klocale.h>
#include <kiconloader.h>
#include <kapplication.h>
#include <kurl.h>
#include <krun.h>
#include <dcopref.h>
#include <kmessagebox.h>
#include <dcopclient.h>
#include <kcharsets.h>
#include <tqvaluevector.h>
#include <tqheader.h>
#include <tqclipboard.h>
#include "treeview.h"
#include "../global.h"
#include "../engine/linkstatus.h"
#include "../engine/linkfilter.h"
#include "../cfg/klsconfig.h"
TreeView::TreeView(TQWidget *parent, const char *name)
: KListView(parent, name),
ResultView(),
current_column_(0)
{
setShowToolTips(true);
//setAllColumnsShowFocus(true);
setSorting(1000); // don't start sorting any column
setShowSortIndicator(true);
//setFocusPolicy( WheelFocus );
setRootIsDecorated(KLSConfig::displayTreeView());
// setResizeMode(TQListView::LastColumn);
sub_menu_ = new TQPopupMenu(this, "sub_menu_referrers");
connect(this, TQT_SIGNAL( rightButtonClicked ( TQListViewItem *, const TQPoint &, int )),
this, TQT_SLOT( slotPopupContextMenu( TQListViewItem *, const TQPoint &, int )) );
}
TreeView::~TreeView()
{
saveLayout(KLSConfig::self()->config(), "klinkstatus");
}
void TreeView::setColumns(TQStringList const& columns)
{
ResultView::setColumns(columns);
removeColunas();
// resetColumns is called automatically
for(uint i = 0; i != columns.size(); ++i)
{
addColumn(i18n(columns[i]));
setColumnWidthMode(i, TQListView::Manual);
}
setColumnAlignment(col_status_ - 1, TQt::AlignCenter);
if(KLSConfig::showMarkupStatus())
setColumnAlignment(col_markup_ - 1, TQt::AlignCenter);
}
void TreeView::resetColumns()
{
setColumnWidth(col_url_ - 1, (int)(0.45 * width()));
setResizeMode(TQListView::LastColumn); // fit to the window
// resize again
setColumnWidthMode(col_label_ - 1, TQListView::Manual);
setResizeMode(TQListView::NoColumn);
}
double TreeView::columnsWidth() const
{
kdDebug(23100) << "columns: " << columns() << endl;
double width = 0.0;
for(int i = 0; i != columns(); ++i)
{
kdDebug(23100) << "column width: " << columnWidth(i) << endl;
width += columnWidth(i);
}
return width;
}
void TreeView::clear()
{
KListView::clear();
}
void TreeView::removeColunas()
{
clear();
}
void TreeView::show(ResultView::tqStatus const& status)
{
TQListViewItemIterator it(static_cast<KListView*> (this));
while(it.current())
{
TreeViewItem* item = myItem(it.current());
if(!ResultView::displayableWithtqStatus(item->linktqStatus(), status))
{
item->setVisible(false);
//kdDebug(23100) << "Hide: " << item->linktqStatus()->absoluteUrl().url() << endl;
}
else
{
item->setVisible(true);
//item->setEnabled(true);
/*
if(KLSConfig::displayTreeView() && status != ResultView::good && item->parent())
{
TreeViewItem* parent = myItem(item->parent());
while(parent)
{
kdDebug(23100) << "Show: " << parent->linktqStatus()->absoluteUrl().url() << endl;
parent->setVisible(true);
//parent->setEnabled(false);
if(parent->parent())
parent = myItem(parent->parent());
else
parent = 0;
}
}
*/
}
//
++it;
}
}
void TreeView::show(LinkMatcher link_matcher)
{
TQListViewItemIterator it(this);
while(it.current())
{
TreeViewItem* item = myItem(it.current());
bool match = link_matcher.matches(*(item->linktqStatus()));
if(tree_display_)
item->setEnabled(match);
else
item->setVisible(match);
++it;
}
}
void TreeView::showAll()
{
TQListViewItemIterator it(this);
while(it.current())
{
it.current()->setVisible(true);
//it.current()->setEnabled(true);
++it;
}
}
void TreeView::ensureRowVisible(const TQListViewItem * i, bool tree_display)
{
TQScrollBar* vertical_scroll_bar = verticalScrollBar();
if(tree_display ||
vertical_scroll_bar->value() > (vertical_scroll_bar->maxValue() - vertical_scroll_bar->lineStep()))
ensureItemVisible(i);
}
bool TreeView::isEmpty() const
{
return !childCount();
}
void TreeView::resizeEvent(TQResizeEvent *e)
{
KListView::resizeEvent(e);
resetColumns();
clipper()->tqrepaint();
}
void TreeView::slotPopupContextMenu(TQListViewItem* item, const TQPoint& pos, int col)
{
current_column_ = col;
TreeViewItem* tree_item = myItem(item);
if(tree_item)
{
TQValueVector<KURL> referrers = tree_item->linktqStatus()->referrers();
loadContextTableMenu(referrers, tree_item->linktqStatus()->isRoot());
context_table_menu_.popup(pos);
}
}
void TreeView::slotCopyUrlToClipboard() const
{
TreeViewItem* _item = myItem(currentItem());
TQString content(_item->linktqStatus()->absoluteUrl().prettyURL());
TQClipboard* cb = kapp->tqclipboard();
cb->setText(content);
}
void TreeView::slotCopyParentUrlToClipboard() const
{
TreeViewItem* _item = myItem(currentItem());
TQString content(_item->linktqStatus()->parent()->absoluteUrl().prettyURL());
TQClipboard* cb = kapp->tqclipboard();
cb->setText(content);
}
void TreeView::slotCopyCellTextToClipboard() const
{
TreeViewItem* _item = myItem(currentItem());
TQString cell_text(_item->text(current_column_));
TQClipboard* cb = kapp->tqclipboard();
cb->setText(cell_text);
}
void TreeView::slotEditReferrersWithQuanta()
{
TreeViewItem* _item = myItem(currentItem());
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 TreeView::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
TreeViewItem* _item = myItem(currentItem());
TQValueVector<KURL> referrers = _item->linktqStatus()->referrers();
Q_ASSERT(index >= 0 && (uint)index < referrers.size());
slotEditReferrerWithQuanta(referrers[index]);
}
void TreeView::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 TreeView::slotViewUrlInBrowser()
{
TreeViewItem* _item = myItem(currentItem());
KURL url = _item->linktqStatus()->absoluteUrl();
if(url.isValid())
{
(void) new KRun (url, 0, url.isLocalFile(), true);
}
else
KMessageBox::sorry(this, i18n("Invalid URL."));
}
void TreeView::slotViewParentUrlInBrowser()
{
TreeViewItem* _item = myItem(currentItem());
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."));
}
}
void TreeView::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("edit"), i18n("Edit Referrer with Quanta"),
sub_menu_);
context_table_menu_.insertSeparator();
}
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()));
}
TreeViewItem* TreeView::myItem(TQListViewItem* item) const
{
TreeViewItem* _item = dynamic_cast<TreeViewItem*> (item);
Q_ASSERT(_item);
return _item;
}
/* ******************************* TreeViewItem ******************************* */
TreeViewItem::TreeViewItem(TreeView* parent, TQListViewItem* after,
LinktqStatus const* linkstatus)
: KListViewItem(parent, after),
last_child_(0), root_(parent)
{
init(linkstatus);
}
TreeViewItem::TreeViewItem(TreeView* root, TQListViewItem* listview_item, TQListViewItem* after,
LinktqStatus const* linkstatus)
: KListViewItem(listview_item, after),
last_child_(0), root_(root)
{
init(linkstatus);
}
TreeViewItem::~TreeViewItem()
{}
void TreeViewItem::init(LinktqStatus const* linkstatus)
{
setOpen(true);
for(int i = 0; i != root_->numberOfColumns(); ++i)
{
TreeColumnViewItem item(root_, linkstatus, i + 1);
column_items_.push_back(item);
if(i + 1 == root_->urlColumnIndex()) {
setText(item.columnIndex() - 1, KURL::decode_string(
KCharsets::resolveEntities(item.text(i + 1))));
}
else {
setText(item.columnIndex() - 1, KCharsets::resolveEntities(item.text(i + 1)));
}
setPixmap(item.columnIndex() - 1, item.pixmap(i + 1));
}
}
void TreeViewItem::setLastChild(TQListViewItem* last_child)
{
Q_ASSERT(last_child);
last_child_ = last_child;
}
TQListViewItem* TreeViewItem::lastChild() const
{
return last_child_;
}
TQString TreeViewItem::key(int column, bool) const
{
// FIXME magic numbers
switch(column)
{
case 1: // status column
return linktqStatus()->statusText();
}
return text(column);
}
LinktqStatus const* TreeViewItem::linktqStatus() const
{
return column_items_[0].linktqStatus();
}
void TreeViewItem::paintCell(TQPainter * p, const TQColorGroup & cg, int column, int width, int align)
{
TreeColumnViewItem item = column_items_[column];
// Get a color to draw the text
TQColorGroup m_cg(cg);
TQColor color(item.textStatusColor());
m_cg.setColor(TQColorGroup::Text, color);
KListViewItem::paintCell(p, m_cg, column, width, align);
setHeight(22);
}
/* ******************************* TreeColumnViewItem ******************************* */
TreeColumnViewItem::TreeColumnViewItem(TreeView* root, LinktqStatus const* linkstatus, int column_index)
: root_(root), ls_(linkstatus), column_index_(column_index)
{
Q_ASSERT(ls_);
// Q_ASSERT(column_index_ > 0);
}
TreeColumnViewItem::~TreeColumnViewItem()
{}
/*
void TreeColumnViewItem::setColumnIndex(int i)
{
Q_ASSERT(i > 0);
column_index_ = i;
}
*/
int TreeColumnViewItem::columnIndex() const
{
return column_index_;
}
LinktqStatus const* TreeColumnViewItem::linktqStatus() const
{
Q_ASSERT(ls_);
return ls_;
}
TQColor const& TreeColumnViewItem::textStatusColor() const
{
if(columnIndex() == root_->urlColumnIndex() || columnIndex() == root_->statusColumnIndex())
{
if(linktqStatus()->status() == LinktqStatus::BROKEN)
return TQt::red;
else if(linktqStatus()->status() == LinktqStatus::HTTP_CLIENT_ERROR)
return TQt::red;
else if(linktqStatus()->status() == LinktqStatus::HTTP_REDIRECTION)
return TQt::black;
else if(linktqStatus()->status() == LinktqStatus::HTTP_SERVER_ERROR)
return TQt::darkMagenta;
else if(linktqStatus()->status() == LinktqStatus::MALFORMED)
return TQt::red;
else if(linktqStatus()->status() == LinktqStatus::NOT_SUPPORTED)
return TQt::lightGray;
else if(linktqStatus()->status() == LinktqStatus::SUCCESSFULL)
return TQt::black;
else if(linktqStatus()->status() == LinktqStatus::TIMEOUT)
return TQt::darkMagenta;
else if(linktqStatus()->status() == LinktqStatus::UNDETERMINED)
return TQt::blue;
return TQt::red;
}
else
return TQt::black;
}
TQString TreeColumnViewItem::text(int column) const
{
Q_ASSERT(column > 0);
if(column == root_->urlColumnIndex())
{
if(linktqStatus()->node() && linktqStatus()->malformed())
{
if(linktqStatus()->node()->url().isEmpty())
return linktqStatus()->node()->content().simplifyWhiteSpace();
else
return linktqStatus()->node()->url();
}
else
{
KURL url = linktqStatus()->absoluteUrl();
return Url::convertToLocal(linktqStatus());
}
}
else if(column == root_->statusColumnIndex())
{
return TQString();
}
else if(column == root_->labelColumnIndex())
{
TQString label(linktqStatus()->label());
if(!label.isNull())
return label.simplifyWhiteSpace();
}
return TQString();
}
TQPixmap TreeColumnViewItem::pixmap(int column) const
{
Q_ASSERT(column > 0);
if(column == root_->statusColumnIndex())
{
if(linktqStatus()->status() == LinktqStatus::BROKEN)
return SmallIcon("no");
else if(linktqStatus()->status() == LinktqStatus::HTTP_CLIENT_ERROR)
return SmallIcon("no");
else if(linktqStatus()->status() == LinktqStatus::HTTP_REDIRECTION)
{
if(linktqStatus()->statusText() == "304")
return UserIcon("304");
else
return SmallIcon("redo");
}
else if(linktqStatus()->status() == LinktqStatus::HTTP_SERVER_ERROR)
return SmallIcon("no");
else if(linktqStatus()->status() == LinktqStatus::MALFORMED)
return SmallIcon("editdelete");
else if(linktqStatus()->status() == LinktqStatus::NOT_SUPPORTED)
return SmallIcon("help");
else if(linktqStatus()->status() == LinktqStatus::SUCCESSFULL)
return SmallIcon("ok");
else if(linktqStatus()->status() == LinktqStatus::TIMEOUT)
return SmallIcon("history_clear");
else if(linktqStatus()->status() == LinktqStatus::UNDETERMINED)
return SmallIcon("help");
}
return TQPixmap();
}
#include "treeview.moc"