/*************************************************************************** * 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 #include #include #include #include #include #include #include #include #include #include #include #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::Status const& status) { TQListViewItemIterator it(static_cast (this)); while(it.current()) { TreeViewItem* item = myItem(it.current()); if(!ResultView::displayableWithStatus(item->linkStatus(), status)) { item->setVisible(false); //kdDebug(23100) << "Hide: " << item->linkStatus()->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->linkStatus()->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->linkStatus())); 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()->repaint(); } void TreeView::slotPopupContextMenu(TQListViewItem* item, const TQPoint& pos, int col) { current_column_ = col; TreeViewItem* tree_item = myItem(item); if(tree_item) { TQValueVector referrers = tree_item->linkStatus()->referrers(); loadContextTableMenu(referrers, tree_item->linkStatus()->isRoot()); context_table_menu_.popup(pos); } } void TreeView::slotCopyUrlToClipboard() const { TreeViewItem* _item = myItem(currentItem()); TQString content(_item->linkStatus()->absoluteUrl().prettyURL()); TQClipboard* cb = kapp->clipboard(); cb->setText(content); } void TreeView::slotCopyParentUrlToClipboard() const { TreeViewItem* _item = myItem(currentItem()); TQString content(_item->linkStatus()->parent()->absoluteUrl().prettyURL()); TQClipboard* cb = kapp->clipboard(); cb->setText(content); } void TreeView::slotCopyCellTextToClipboard() const { TreeViewItem* _item = myItem(currentItem()); TQString cell_text(_item->text(current_column_)); TQClipboard* cb = kapp->clipboard(); cb->setText(cell_text); } void TreeView::slotEditReferrersWithQuanta() { TreeViewItem* _item = myItem(currentItem()); TQValueVector referrers = _item->linkStatus()->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 referrers = _item->linkStatus()->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("File %1 cannot be opened. Might be a DCOP problem.").arg(filePath); KMessageBox::error(parentWidget(), message); } } else { TQStringList args(url.url()); Global::openQuanta(args); } } void TreeView::slotViewUrlInBrowser() { TreeViewItem* _item = myItem(currentItem()); KURL url = _item->linkStatus()->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->linkStatus()->isRoot()) { KMessageBox::sorry(this, i18n("ROOT URL.")); } else { LinkStatus const* ls_parent = _item->linkStatus()->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 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 (item); Q_ASSERT(_item); return _item; } /* ******************************* TreeViewItem ******************************* */ TreeViewItem::TreeViewItem(TreeView* parent, TQListViewItem* after, LinkStatus const* linkstatus) : KListViewItem(parent, after), last_child_(0), root_(parent) { init(linkstatus); } TreeViewItem::TreeViewItem(TreeView* root, TQListViewItem* listview_item, TQListViewItem* after, LinkStatus const* linkstatus) : KListViewItem(listview_item, after), last_child_(0), root_(root) { init(linkstatus); } TreeViewItem::~TreeViewItem() {} void TreeViewItem::init(LinkStatus 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 linkStatus()->statusText(); } return text(column); } LinkStatus const* TreeViewItem::linkStatus() const { return column_items_[0].linkStatus(); } 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, LinkStatus 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_; } LinkStatus const* TreeColumnViewItem::linkStatus() const { Q_ASSERT(ls_); return ls_; } TQColor const& TreeColumnViewItem::textStatusColor() const { if(columnIndex() == root_->urlColumnIndex() || columnIndex() == root_->statusColumnIndex()) { if(linkStatus()->status() == LinkStatus::BROKEN) return TQt::red; else if(linkStatus()->status() == LinkStatus::HTTP_CLIENT_ERROR) return TQt::red; else if(linkStatus()->status() == LinkStatus::HTTP_REDIRECTION) return TQt::black; else if(linkStatus()->status() == LinkStatus::HTTP_SERVER_ERROR) return TQt::darkMagenta; else if(linkStatus()->status() == LinkStatus::MALFORMED) return TQt::red; else if(linkStatus()->status() == LinkStatus::NOT_SUPPORTED) return TQt::lightGray; else if(linkStatus()->status() == LinkStatus::SUCCESSFULL) return TQt::black; else if(linkStatus()->status() == LinkStatus::TIMEOUT) return TQt::darkMagenta; else if(linkStatus()->status() == LinkStatus::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(linkStatus()->node() && linkStatus()->malformed()) { if(linkStatus()->node()->url().isEmpty()) return linkStatus()->node()->content().simplifyWhiteSpace(); else return linkStatus()->node()->url(); } else { KURL url = linkStatus()->absoluteUrl(); return Url::convertToLocal(linkStatus()); } } else if(column == root_->statusColumnIndex()) { return TQString(); } else if(column == root_->labelColumnIndex()) { TQString label(linkStatus()->label()); if(!label.isNull()) return label.simplifyWhiteSpace(); } return TQString(); } TQPixmap TreeColumnViewItem::pixmap(int column) const { Q_ASSERT(column > 0); if(column == root_->statusColumnIndex()) { if(linkStatus()->status() == LinkStatus::BROKEN) return SmallIcon("no"); else if(linkStatus()->status() == LinkStatus::HTTP_CLIENT_ERROR) return SmallIcon("no"); else if(linkStatus()->status() == LinkStatus::HTTP_REDIRECTION) { if(linkStatus()->statusText() == "304") return UserIcon("304"); else return SmallIcon("redo"); } else if(linkStatus()->status() == LinkStatus::HTTP_SERVER_ERROR) return SmallIcon("no"); else if(linkStatus()->status() == LinkStatus::MALFORMED) return SmallIcon("editdelete"); else if(linkStatus()->status() == LinkStatus::NOT_SUPPORTED) return SmallIcon("help"); else if(linkStatus()->status() == LinkStatus::SUCCESSFULL) return SmallIcon("ok"); else if(linkStatus()->status() == LinkStatus::TIMEOUT) return SmallIcon("history_clear"); else if(linkStatus()->status() == LinkStatus::UNDETERMINED) return SmallIcon("help"); } return TQPixmap(); } #include "treeview.moc"