diff options
Diffstat (limited to 'klinkstatus/src/ui')
27 files changed, 5320 insertions, 0 deletions
diff --git a/klinkstatus/src/ui/Makefile.am b/klinkstatus/src/ui/Makefile.am new file mode 100644 index 00000000..7f687d39 --- /dev/null +++ b/klinkstatus/src/ui/Makefile.am @@ -0,0 +1,11 @@ +INCLUDES = -I$(top_srcdir)/src -I$(top_builddir)/klinkstatus/src/cfg \ + -I$(top_builddir)/klinkstatus/src $(all_includes) +METASOURCES = AUTO +noinst_HEADERS = sessionwidget.h tabwidgetsession.h klshistorycombo.h \ + resultview.h resultssearchbar.h +libui_la_LDFLAGS = $(all_libraries) +libui_la_LIBADD = $(top_builddir)/klinkstatus/src/cfg/libcfg.la +noinst_LTLIBRARIES = libui.la +libui_la_SOURCES = sessionwidgetbase.ui sessionwidget.cpp tabwidgetsession.cpp \ + klshistorycombo.cpp resultview.cpp treeview.cpp resultssearchbar.cpp documentrootdialog.cpp +SUBDIRS = settings diff --git a/klinkstatus/src/ui/celltooltip.cpp b/klinkstatus/src/ui/celltooltip.cpp new file mode 100644 index 00000000..b449cbce --- /dev/null +++ b/klinkstatus/src/ui/celltooltip.cpp @@ -0,0 +1,54 @@ +/*************************************************************************** + * Copyright (C) 2004 by Paulo Moura Guedes * + * moura@kdewebdev.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 "celltooltip.h" +#include "tablelinkstatus.h" + +#include <qscrollview.h> + +#include <iostream> +using namespace std; + + +CellToolTip::CellToolTip ( TableLinkstatus * table, QToolTipGroup * group) + : QToolTip(table->viewport(), group), table_(table) +{} + +void CellToolTip::maybeTip ( const QPoint & p ) +{ + QPoint cp = table_->viewportToContents(p); + + int row = table_->rowAt(cp.y()); + int col = table_->columnAt(cp.x()); + + if( row != -1 && col != -1) + { + if(col == 0 || !table_->textFitsInCell(row, col)) + { + TableItem* item = table_->myItem(row, col); + QString tip_string = item->toolTip(); + + QRect cr = table_->cellGeometry( row, col ); + cr.moveTopLeft( table_->contentsToViewport( cr.topLeft() ) ); + + tip(cr, tip_string); + } + } +} diff --git a/klinkstatus/src/ui/celltooltip.h b/klinkstatus/src/ui/celltooltip.h new file mode 100644 index 00000000..33136ceb --- /dev/null +++ b/klinkstatus/src/ui/celltooltip.h @@ -0,0 +1,45 @@ +/*************************************************************************** + * Copyright (C) 2004 by Paulo Moura Guedes * + * moura@kdewebdev.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. * + ***************************************************************************/ + +#ifndef CELLTOOLTIP_H +#define CELLTOOLTIP_H + +#include <qtooltip.h> + + +class TableLinkstatus; + +class CellToolTip: public QToolTip +{ +public: + + CellToolTip ( TableLinkstatus * table, QToolTipGroup * group = 0 ); + +protected: + + virtual void maybeTip ( const QPoint & p ); + +private: + + TableLinkstatus * table_; +}; + + +#endif diff --git a/klinkstatus/src/ui/documentrootdialog.cpp b/klinkstatus/src/ui/documentrootdialog.cpp new file mode 100644 index 00000000..c2ed3e7d --- /dev/null +++ b/klinkstatus/src/ui/documentrootdialog.cpp @@ -0,0 +1,89 @@ +/*************************************************************************** + * Copyright (C) 2006 by Paulo Moura Guedes * + * moura@kdewebdev.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 "documentrootdialog.h" + +#include <kurlrequester.h> +#include <klocale.h> +#include <kurl.h> + +#include <qstring.h> +#include <qlayout.h> +#include <qlabel.h> + + +DocumentRootDialog::DocumentRootDialog(QWidget *parent, QString const& url) + : KDialogBase(parent, "DocumentRootDialog", true, "Choose a Document Root", + KDialogBase::Ok, KDialogBase::Ok, true), + m_url(url) +{ + QWidget* page = new QWidget(this); + setMainWidget(page); + QVBoxLayout* topLayout = new QVBoxLayout(page, 0, spacingHint()); + + QLabel* label = new QLabel(i18n("As you are using a protocol different than HTTP, \nthere is no way to guess where the document root is, \nin order to resolve relative URLs like the ones started with \"/\".\n\nPlease specify one:"), page); + topLayout->addWidget(label); + + m_urlRequester = new KURLRequester(page); + m_urlRequester->setURL(url); + m_urlRequester->setMinimumWidth(fontMetrics().maxWidth()*20); + m_urlRequester->setFocus(); + topLayout->addWidget(m_urlRequester); + + topLayout->addStretch(10); + + // setInitialSize(configDialogSize("klinkstatus")); + + m_urlRequester->setMode(KFile::Directory); +// enableButtonOK(false); + + connect(m_urlRequester, SIGNAL(textChanged (const QString &)), + this, SLOT(slotTextChanged (const QString &))); + connect(m_urlRequester, SIGNAL(returnPressed (const QString &)), + this, SLOT(slotReturnPressed (const QString &))); + connect(m_urlRequester, SIGNAL(urlSelected (const QString &)), + this, SLOT(slotTextChanged (const QString &))); +} + +DocumentRootDialog::~DocumentRootDialog() +{ + saveDialogSize("klinkstatus", true); +} + +void DocumentRootDialog::slotReturnPressed( const QString & ) +{ + slotOk(); +} + +void DocumentRootDialog::slotTextChanged( const QString & s) +{ + KURL url(s); + enableButtonOK(!s.isEmpty() && url.isValid()); +} + +void DocumentRootDialog::slotOk( ) +{ + m_url = m_urlRequester->url(); + + KDialogBase::slotOk(); +} + + + +#include "documentrootdialog.moc" diff --git a/klinkstatus/src/ui/documentrootdialog.h b/klinkstatus/src/ui/documentrootdialog.h new file mode 100644 index 00000000..52696727 --- /dev/null +++ b/klinkstatus/src/ui/documentrootdialog.h @@ -0,0 +1,57 @@ +/*************************************************************************** + * Copyright (C) 2006 by Paulo Moura Guedes * + * moura@kdewebdev.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. * + ***************************************************************************/ +#ifndef DOCUMENTROOTDIALOG_H +#define DOCUMENTROOTDIALOG_H + +#include <kdialogbase.h> + +class KURLRequester; + +/** + @author Paulo Moura Guedes <moura@kdewebdev.org> +*/ +class DocumentRootDialog : public KDialogBase +{ +Q_OBJECT +public: + DocumentRootDialog(QWidget *parent, QString const& url); + ~DocumentRootDialog(); + + void setUrl(const QString& theValue) { m_url = theValue; } + QString url() const { return m_url; } + + +protected: + virtual void closeEvent (QCloseEvent*) {} + +protected slots: + virtual void reject() {} + virtual void slotOk(); + +private slots: + void slotTextChanged(const QString &); + void slotReturnPressed(const QString &); + +private: + KURLRequester* m_urlRequester; + QString m_url; +}; + +#endif diff --git a/klinkstatus/src/ui/klshistorycombo.cpp b/klinkstatus/src/ui/klshistorycombo.cpp new file mode 100644 index 00000000..36deb385 --- /dev/null +++ b/klinkstatus/src/ui/klshistorycombo.cpp @@ -0,0 +1,198 @@ +// +// C++ Implementation: klshistorycombo +// +// Description: +// +// +// Author: Paulo Moura Guedes <moura@kdewebdev.org>, (C) 2004 +// +// Copyright: See COPYING file that comes with this distribution +// +// +#include "klshistorycombo.h" +#include "klsconfig.h" + +#include <kapplication.h> +#include <kconfig.h> +#include <kcompletionbox.h> +#include <kdebug.h> +#include <kstdaccel.h> +#include <kurldrag.h> +#include <kglobalsettings.h> + + +bool KLSHistoryCombo::items_saved_ = false; + + +KLSHistoryCombo::KLSHistoryCombo(QWidget *parent, const char *name) + : KHistoryCombo(parent, name) +{ + setMaxCount(KLSConfig::maxCountComboUrl()); + + setDuplicatesEnabled(false); + setAutoCompletion(false); + + connect(this, SIGNAL(activated(const QString& )), + this, SLOT(addToHistory(const QString& ))); +} + +KLSHistoryCombo::~KLSHistoryCombo() +{} + +void KLSHistoryCombo::init() +{ + loadItems(); +} + +void KLSHistoryCombo::saveItems() +{ + if(items_saved_) + return; + + QStringList items = historyItems(); + + KLSConfig::setComboUrlHistory(items); + KLSConfig::writeConfig(); + + items_saved_ = true; +} + +void KLSHistoryCombo::loadItems() +{ + clear(); + + QStringList items = KLSConfig::comboUrlHistory(); + + bool block = signalsBlocked(); + blockSignals( true ); + + setHistoryItems(items); + blockSignals(block); + + completionObject()->setItems(items); + + setCompletionMode(KGlobalSettings::completionMode()); +} + +bool KLSHistoryCombo::eventFilter( QObject *o, QEvent *ev ) +{ + // Handle Ctrl+Del/Backspace etc better than the Qt widget, which always + // jumps to the next whitespace. + QLineEdit *edit = lineEdit(); + if ( o == edit ) + { + int type = ev->type(); + if ( type == QEvent::KeyPress ) + { + QKeyEvent *e = static_cast<QKeyEvent *>( ev ); + + if ( e->key() == Key_Return || e->key() == Key_Enter ) + { + //m_modifier = e->state(); + return false; + } + + int delete_word_back = KStdAccel::deleteWordBack().keyCodeQt(); + int delete_word_forward = KStdAccel::deleteWordForward().keyCodeQt(); + + if ( KKey( e ) == KKey(delete_word_back) || + KKey( e ) == KKey(delete_word_forward) || + ((e->state() & ControlButton) && + (e->key() == Key_Left || e->key() == Key_Right) ) ) + { + selectWord(e); + e->accept(); + return true; + } + } + + else if ( type == QEvent::MouseButtonDblClick ) + { + edit->selectAll(); + return true; + } + } + return KComboBox::eventFilter( o, ev ); +} + +/* + Handle Ctrl+Cursor etc better than the Qt widget, which always + jumps to the next whitespace. This code additionally jumps to + the next [/#?:], which makes more sense for URLs. The list of + chars that will stop the cursor are '/', '.', '?', '#', ':'. +*/ +void KLSHistoryCombo::selectWord(QKeyEvent *e) +{ + QLineEdit* edit = lineEdit(); + QString text = edit->text(); + int pos = edit->cursorPosition(); + int pos_old = pos; + int count = 0; + + // TODO: make these a parameter when in kdelibs/kdeui... + QValueList<QChar> chars; + chars << QChar('/') << QChar('.') << QChar('?') << QChar('#') << QChar(':'); + bool allow_space_break = true; + + if( e->key() == Key_Left || e->key() == Key_Backspace ) + { + do + { + pos--; + count++; + if( allow_space_break && text[pos].isSpace() && count > 1 ) + break; + } + while( pos >= 0 && (chars.findIndex(text[pos]) == -1 || count <= 1) ); + + if( e->state() & ShiftButton ) + { + edit->cursorForward(true, 1-count); + } + else if( e->key() == Key_Backspace ) + { + edit->cursorForward(false, 1-count); + QString text = edit->text(); + int pos_to_right = edit->text().length() - pos_old; + QString cut = text.left(edit->cursorPosition()) + text.right(pos_to_right); + edit->setText(cut); + edit->setCursorPosition(pos_old-count+1); + } + else + { + edit->cursorForward(false, 1-count); + } + } + else if( e->key() == Key_Right || e->key() == Key_Delete ) + { + do + { + pos++; + count++; + if( allow_space_break && text[pos].isSpace() ) + break; + } + while( pos < (int) text.length() && chars.findIndex(text[pos]) == -1 ); + + if( e->state() & ShiftButton ) + { + edit->cursorForward(true, count+1); + } + else if( e->key() == Key_Delete ) + { + edit->cursorForward(false, -count-1); + QString text = edit->text(); + int pos_to_right = text.length() - pos - 1; + QString cut = text.left(pos_old) + + (pos_to_right > 0 ? text.right(pos_to_right) : QString() ); + edit->setText(cut); + edit->setCursorPosition(pos_old); + } + else + { + edit->cursorForward(false, count+1); + } + } +} + +#include "klshistorycombo.moc" diff --git a/klinkstatus/src/ui/klshistorycombo.h b/klinkstatus/src/ui/klshistorycombo.h new file mode 100644 index 00000000..ab990a1e --- /dev/null +++ b/klinkstatus/src/ui/klshistorycombo.h @@ -0,0 +1,42 @@ +// +// C++ Interface: klshistorycombo +// +// Description: +// +// +// Author: Paulo Moura Guedes <moura@kdewebdev.org>, (C) 2004 +// +// Copyright: See COPYING file that comes with this distribution +// +// +#ifndef KLSHISTORYCOMBO_H +#define KLSHISTORYCOMBO_H + +#include <kcombobox.h> +class KConfig; + +/** +@author Paulo Moura Guedes +Based on KonqCombo +*/ +class KLSHistoryCombo : public KHistoryCombo +{ + Q_OBJECT + +public: + KLSHistoryCombo(QWidget* parent, const char* name); + ~KLSHistoryCombo(); + + void init(); + void loadItems(); + void saveItems(); + +protected: + virtual bool eventFilter(QObject* o, QEvent* ev); + void selectWord(QKeyEvent* e); + +private: + static bool items_saved_; +}; + +#endif diff --git a/klinkstatus/src/ui/resultssearchbar.cpp b/klinkstatus/src/ui/resultssearchbar.cpp new file mode 100644 index 00000000..7f772b54 --- /dev/null +++ b/klinkstatus/src/ui/resultssearchbar.cpp @@ -0,0 +1,236 @@ +/*************************************************************************** + * Copyright (C) 2004 by Paulo Moura Guedes * + * moura@kdewebdev.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 "resultssearchbar.h" + +#include <kcombobox.h> +#include <kiconloader.h> +#include <klineedit.h> +#include <klocale.h> +#include <kstandarddirs.h> +#include <kdebug.h> + +#include <qapplication.h> +#include <qhbox.h> +#include <qlabel.h> +#include <qpixmap.h> +#include <qstring.h> +#include <qtimer.h> +#include <qtoolbutton.h> +#include <qtooltip.h> +#include <qlayout.h> + + +class ResultsSearchBar::ResultsSearchBarPrivate +{ +public: + ResultsSearchBarPrivate() + : layout(0), searchLine(0), searchCombo(0), delay(400), m_lastComboIndex(0) + {} + + QString searchText; + QTimer timer; + QHBoxLayout* layout; + KLineEdit* searchLine; + KComboBox* searchCombo; + int delay; + int m_lastComboIndex; +}; + +ResultsSearchBar::ResultsSearchBar(QWidget* parent, const char* name) + : QWidget(parent, name), d(new ResultsSearchBar::ResultsSearchBarPrivate) +{ + setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed)); + + d->layout = new QHBoxLayout(this); + d->layout->setMargin(2); + d->layout->setSpacing(5); + + QToolButton* clearButton = new QToolButton(this); + clearButton->setIconSet(SmallIconSet(QApplication::reverseLayout() ? "clear_left" : "locationbar_erase")); + clearButton->setAutoRaise(true); + d->layout->addWidget(clearButton); + + QLabel* searchLabel = new QLabel(this); + searchLabel->setText(i18n("S&earch:")); + d->layout->addWidget(searchLabel); + + d->searchLine = new KLineEdit(this, "searchline"); + connect(d->searchLine, SIGNAL(textChanged(const QString &)), + this, SLOT(slotSearchStringChanged(const QString &))); + + searchLabel->setBuddy(d->searchLine); + d->layout->addWidget(d->searchLine); + + QLabel* statusLabel = new QLabel(this); + statusLabel->setText( i18n("Status:") ); + d->layout->addWidget(statusLabel); + + d->searchCombo = new KComboBox(this, "searchcombo"); + QPixmap iconAll = KGlobal::iconLoader()->loadIcon("exec", KIcon::Small); + QPixmap iconGood = KGlobal::iconLoader()->loadIcon("ok", KIcon::Small); + QPixmap iconBroken = KGlobal::iconLoader()->loadIcon("no", KIcon::Small); + QPixmap iconMalformed = KGlobal::iconLoader()->loadIcon("bug", KIcon::Small); + QPixmap iconUndetermined = KGlobal::iconLoader()->loadIcon("help", KIcon::Small); + + d->searchCombo->insertItem(iconAll, i18n("All Links")); + d->searchCombo->insertItem(iconGood, i18n("Good Links")); + d->searchCombo->insertItem(iconBroken, i18n("Broken Links")); + d->searchCombo->insertItem(iconMalformed, i18n("Malformed Links")); + d->searchCombo->insertItem(iconUndetermined, i18n("Undetermined Links")); + d->layout->addWidget(d->searchCombo); + + QToolTip::add(clearButton, i18n("Clear filter")); + QToolTip::add( d->searchLine, i18n("Enter the terms to filter the result link list")); + QToolTip::add( d->searchCombo, i18n("Choose what kind of link status to show in result list")); + + connect(clearButton, SIGNAL( clicked() ), + this, SLOT(slotClearSearch()) ); + + connect(d->searchCombo, SIGNAL(activated(int)), + this, SLOT(slotSearchComboChanged(int))); + + connect(&(d->timer), SIGNAL(timeout()), this, SLOT(slotActivateSearch())); +} + +ResultsSearchBar::~ResultsSearchBar() +{ + delete d; + d = 0; +} + +QString const& ResultsSearchBar::text() const +{ + return d->searchText; +} + +int ResultsSearchBar::status() const +{ + return d->searchCombo->currentItem(); +} + +void ResultsSearchBar::setDelay(int ms) +{ + d->delay = ms; +} + +int ResultsSearchBar::delay() const +{ + return d->delay; +} + +void ResultsSearchBar::slotClearSearch() +{ + if(status() != 0 || !d->searchLine->text().isEmpty()) + { + d->searchLine->clear(); + d->searchCombo->setCurrentItem(0); + d->timer.stop(); + slotActivateSearch(); + } +} + +void ResultsSearchBar::slotSetStatus(int status) +{ + d->searchCombo->setCurrentItem(status); +} + +void ResultsSearchBar::slotSetText(const QString& text) +{ + d->searchLine->setText(text); +} + +void ResultsSearchBar::slotSearchComboChanged(int index) +{ + if(d->timer.isActive()) + d->timer.stop(); + + if(d->m_lastComboIndex == index) + return; + + d->m_lastComboIndex = index; + + d->timer.start(200, true); +} + +void ResultsSearchBar::slotSearchStringChanged(const QString& search) +{ + if(d->timer.isActive()) + d->timer.stop(); + + if(d->searchText == search) + return; + + d->searchText = search; + + d->timer.start(200, true); +} + +void ResultsSearchBar::slotActivateSearch() +{ + kdDebug(23100) << "ResultsSearchBar::slotActivateSearch" << endl; + + ResultView::Status status = selectedStatus(); + + emit signalSearch(LinkMatcher(d->searchLine->text(), status)); +} + +LinkMatcher ResultsSearchBar::currentLinkMatcher() const +{ + return LinkMatcher(d->searchLine->text(), selectedStatus()); +} + +ResultView::Status ResultsSearchBar::selectedStatus() const +{ + ResultView::Status status = ResultView::none; + + if(d->searchCombo->currentItem()) + { + switch(d->searchCombo->currentItem()) + { + case 1: // Good + { + status = ResultView::good; + break; + } + case 2: // Broken + { + status = ResultView::bad; + break; + } + case 3: // Malformed + { + status = ResultView::malformed; + break; + } + case 4: // Undetermined + { + status = ResultView::undetermined; + break; + } + default: + break; + } + } + return status; +} + + +#include "resultssearchbar.moc" diff --git a/klinkstatus/src/ui/resultssearchbar.h b/klinkstatus/src/ui/resultssearchbar.h new file mode 100644 index 00000000..67d30a99 --- /dev/null +++ b/klinkstatus/src/ui/resultssearchbar.h @@ -0,0 +1,73 @@ +/*************************************************************************** + * Copyright (C) 2004 by Paulo Moura Guedes * + * moura@kdewebdev.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. * + ***************************************************************************/ + +#ifndef RESULTSSEARCHBAR_H +#define RESULTSSEARCHBAR_H + +#include <qstring.h> + +#include "resultview.h" +#include "../engine/linkfilter.h" + +/** + @author Paulo Moura Guedes <moura@kdewebdev.org> + Based on Akregator code. Kudos ;) +*/ +class ResultsSearchBar : public QWidget +{ + Q_OBJECT +public: + ResultsSearchBar(QWidget *parent = 0, const char *name = 0); + ~ResultsSearchBar(); + + QString const& text() const; + int status() const; + + void setDelay(int ms); + int delay() const; + + LinkMatcher currentLinkMatcher() const; + +signals: + /** emitted when the text and status filters were updated. Params are textfilter, statusfilter */ + void signalSearch(LinkMatcher); + +public slots: + void slotClearSearch(); + void slotSetStatus(int status); + void slotSetText(const QString& text); + +private slots: + + void slotSearchStringChanged(const QString& search); + void slotSearchComboChanged(int index); + void slotActivateSearch(); + +private: + + ResultView::Status selectedStatus() const; + +private: + + class ResultsSearchBarPrivate; + ResultsSearchBarPrivate* d; +}; + +#endif diff --git a/klinkstatus/src/ui/resultview.cpp b/klinkstatus/src/ui/resultview.cpp new file mode 100644 index 00000000..4078bfca --- /dev/null +++ b/klinkstatus/src/ui/resultview.cpp @@ -0,0 +1,184 @@ +// +// C++ Implementation: resultlinkview +// +// Description: +// +// +// Author: Paulo Moura Guedes <moura@kdewebdev.org>, (C) 2004 +// +// Copyright: See COPYING file that comes with this distribution +// +// +#include "resultview.h" +#include "../engine/linkstatus.h" + +#include <qpainter.h> +#include <qcolor.h> + +#include <klocale.h> +#include <kurl.h> +#include <kiconloader.h> + +const QString ResultView::URL_LABEL = "URL"; +const QString ResultView::STATUS_LABEL = "Status"; +const QString ResultView::MARKUP_LABEL = "Markup"; +const QString ResultView::LINK_LABEL_LABEL = "Label"; + + +// ******************************* ResultView ******************************** + +ResultView::ResultView() + : col_status_(-1), + col_label_(-1), + col_url_(-1), + col_markup_(-1), + sub_menu_(0), + cell_tip_(0) +{} + + +ResultView::~ResultView() +{} + +void ResultView::setColumns(QStringList const& columns) +{ + Q_ASSERT(columns.size() != 0); + + columns_.clear(); + for(uint i = 0; i != columns.size(); ++i) + { + if(columns[i] == ResultView::URL_LABEL) + { + col_url_ = i + 1; + } + else if(columns[i] == ResultView::STATUS_LABEL) + { + col_status_ = i + 1; + } + else if(columns[i] == ResultView::MARKUP_LABEL) + { + col_markup_ = i + 1; + } + else if(columns[i] == ResultView::LINK_LABEL_LABEL) + { + col_label_ = i + 1; + } + + columns_.push_back(columns[i]); + } + number_of_columns_ = columns.size(); +} + +bool ResultView::displayableWithStatus(LinkStatus const* ls, Status const& status) +{ + if(status == ResultView::good) + { + return + ls->status() == LinkStatus::SUCCESSFULL || + ls->status() == LinkStatus::HTTP_REDIRECTION; + } + else if(status == ResultView::bad) + { + return + ls->status() == LinkStatus::BROKEN || + ls->status() == LinkStatus::HTTP_CLIENT_ERROR || + ls->status() == LinkStatus::HTTP_SERVER_ERROR; + } + else if(status == ResultView::malformed) + { + return ls->status() == LinkStatus::MALFORMED; + } + else if(status == ResultView::undetermined) + { + return + ls->status() == LinkStatus::UNDETERMINED || + ls->status() == LinkStatus::TIMEOUT || + ls->status() == LinkStatus::NOT_SUPPORTED; + } + else + return true; +} + + +// ******************************* ResultViewItem ***************************** + +ResultViewItem::ResultViewItem(LinkStatus const* linkstatus, int column_index) + : ls_((LinkStatus*)linkstatus), column_index_(column_index) +{ + Q_ASSERT(ls_); + Q_ASSERT(column_index_ > 0); +} + +ResultViewItem::~ResultViewItem() +{} + +void ResultViewItem::setColumnIndex(int i) +{ + Q_ASSERT(i > 0); + column_index_ = i; +} + +int ResultViewItem::columnIndex() const +{ + return column_index_; +} + +LinkStatus const* ResultViewItem::linkStatus() const +{ + Q_ASSERT(ls_); + return ls_; +} + +QColor const& ResultViewItem::textStatusColor() const +{ + if(linkStatus()->errorOccurred()) + { + //kdDebug(23100) << "ERROR: " << linkStatus()->error() << ": " << linkStatus()->absoluteUrl().prettyURL() << endl; + if(linkStatus()->error() == i18n( "Javascript not supported" )) + return Qt::lightGray; + else + return Qt::red; + } + + else if(linkStatus()->absoluteUrl().hasRef()) + return Qt::blue; + + else if(!linkStatus()->absoluteUrl().protocol().startsWith("http")) + return Qt::darkGreen; + + else + { + QString status_code(QString::number(linkStatus()->httpHeader().statusCode())); + + if(status_code[0] == '0') + { + kdWarning(23100) << "status code == 0: " << endl; + kdWarning(23100) << linkStatus()->toString() << endl; + kdWarning(23100) << linkStatus()->httpHeader().toString() << endl; + } + //Q_ASSERT(status_code[0] != '0'); + + if(status_code[0] == '5') + return Qt::darkMagenta; + + else if(status_code[0] == '4') + return Qt::red; + + else if(status_code[0] == '3') + return Qt::blue; + + else if(status_code[0] == '2') + return Qt::darkGreen; + + else + return Qt::red; + } +} + + + + + + + + diff --git a/klinkstatus/src/ui/resultview.h b/klinkstatus/src/ui/resultview.h new file mode 100644 index 00000000..e6d3e789 --- /dev/null +++ b/klinkstatus/src/ui/resultview.h @@ -0,0 +1,134 @@ +/*************************************************************************** + * Copyright (C) 2004 by Paulo Moura Guedes * + * moura@kdewebdev.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. * + ***************************************************************************/ + +#ifndef RESULTVIEW_H +#define RESULTVIEW_H + +#include <qvaluevector.h> +#include <qpopupmenu.h> +#include <qstringlist.h> + +class KURL; + +class LinkStatus; +class CellToolTip; + + +/** +@author Paulo Moura Guedes +*/ +class ResultView +{ +public: + + static const QString URL_LABEL; + static const QString STATUS_LABEL; + static const QString MARKUP_LABEL; + static const QString LINK_LABEL_LABEL; + + enum Status { + none = 0, + good, + bad, + malformed, + undetermined // timeouts and refs + }; + + ResultView(); + virtual ~ResultView(); + + //virtual void insertResult(LinkStatus const* linkstatus) = 0; + virtual void clear() = 0; + virtual void show(Status const& status) = 0; + virtual void showAll() = 0; + //virtual void ensureCellVisible(int row, int col) = 0; + + virtual void setColumns(QStringList const& columns); + static bool displayableWithStatus(LinkStatus const* ls, Status const& status); + + int numberOfColumns() const { return number_of_columns_; } + + int urlColumnIndex() const {return col_url_; } + int statusColumnIndex() const {return col_status_; } + int markupColumnIndex() const {return col_markup_; } + int labelColumnIndex() const {return col_label_; } + +protected: + //virtual bool textFitsInCell(int row, int col) const = 0; + virtual bool isEmpty() const = 0; + virtual void loadContextTableMenu(QValueVector<KURL> const& referrers, bool is_root = false) = 0; + +protected slots: + + //virtual void slotPopupContextMenu(int row, int col, const QPoint& pos) = 0; + virtual void slotCopyUrlToClipboard() const = 0; + virtual void slotCopyParentUrlToClipboard() const = 0; + virtual void slotCopyCellTextToClipboard() const = 0; + virtual void slotEditReferrersWithQuanta() = 0; + virtual void slotEditReferrerWithQuanta(int id) = 0; + virtual void slotEditReferrerWithQuanta(KURL const& url) = 0; + virtual void slotViewUrlInBrowser() = 0; + virtual void slotViewParentUrlInBrowser() = 0; + +protected: + QStringList columns_; + int col_status_; + int col_label_; + int col_url_; + int col_markup_; // optional + QPopupMenu context_table_menu_; + QPopupMenu* sub_menu_; + CellToolTip* cell_tip_; + +private: + int number_of_columns_; +}; + + +class ResultViewItem +{ +public: + ResultViewItem(LinkStatus const* linkstatus, + int column_index); + virtual ~ResultViewItem(); + + virtual void setColumnIndex(int i); + virtual int columnIndex() const; + + virtual QString toolTip() const = 0; + LinkStatus const* linkStatus() const; + +protected: + + QColor const& textStatusColor() const; + virtual void paint( QPainter *p, const QColorGroup &cg, + const QRect &cr, bool selected ) = 0; + virtual void setText() = 0; + virtual void setPixmap() = 0; + +protected: + + LinkStatus* ls_; + int column_index_; + int alignment_; +}; + + +#endif diff --git a/klinkstatus/src/ui/sessionwidget.cpp b/klinkstatus/src/ui/sessionwidget.cpp new file mode 100644 index 00000000..da128070 --- /dev/null +++ b/klinkstatus/src/ui/sessionwidget.cpp @@ -0,0 +1,723 @@ +/*************************************************************************** + * Copyright (C) 2004 by Paulo Moura Guedes * + * moura@kdewebdev.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 <kapplication.h> +#include <kurl.h> +#include <kcombobox.h> +#include <ksqueezedtextlabel.h> +#include <kprogress.h> +#include <kmessagebox.h> +#include <kconfig.h> +#include <kiconloader.h> +#include <kglobal.h> +#include <kpushbutton.h> +#include <kfiledialog.h> +#include <kactionclasses.h> +#include <ktempfile.h> +#include <ksavefile.h> +#include <kstandarddirs.h> +#include <kio/netaccess.h> + +#include <qevent.h> +#include <qlineedit.h> +#include <qspinbox.h> +#include <qcheckbox.h> +#include <qpushbutton.h> +#include <qlayout.h> +#include <qlabel.h> +#include <qlistbox.h> +#include <qstringlist.h> +#include <qbuttongroup.h> +#include <qtoolbutton.h> +#include <qregexp.h> + +#include "sessionwidget.h" +#include "tablelinkstatus.h" +#include "treeview.h" +#include "documentrootdialog.h" +#include "klshistorycombo.h" +#include "klsconfig.h" +#include "resultview.h" +#include "../global.h" +#include "../engine/linkstatus.h" +#include "../engine/linkchecker.h" +#include "../engine/searchmanager.h" +#include "resultssearchbar.h" +#include "../actionmanager.h" +#include "../utils/utils.h" +#include "../utils/xsl.h" + + +SessionWidget::SessionWidget(int max_simultaneous_connections, int time_out, + QWidget* parent, const char* name, WFlags f) + : SessionWidgetBase(parent, name, f), search_manager_(0), + action_manager_(ActionManager::getInstance()), + ready_(true), to_start_(false), to_pause_(false), to_stop_(false), + in_progress_(false), paused_(false), stopped_(true), + bottom_status_timer_(this, "bottom_status_timer"), + max_simultaneous_connections_(max_simultaneous_connections), + time_out_(time_out), tree_display_(false), follow_last_link_checked_(KLSConfig::followLastLinkChecked()), + start_search_action_(0) +{ + newSearchManager(); + + init(); + slotLoadSettings(); + + connect(combobox_url, SIGNAL( textChanged ( const QString & ) ), + this, SLOT( slotEnableCheckButton( const QString & ) ) ); + + connect(tree_view, SIGNAL( clicked ( QListViewItem * ) ), + this, SLOT( showBottomStatusLabel( QListViewItem * ) ) ); + + connect(&bottom_status_timer_, SIGNAL(timeout()), this, SLOT(clearBottomStatusLabel()) ); +} + +SessionWidget::~SessionWidget() +{ + //combobox_url->saveItems(); This is done every time a URL is checked + + if(KLSConfig::rememberCheckSettings()) + saveCurrentCheckSettings(); +} + +void SessionWidget::init() +{ + combobox_url->init(); + + toolButton_clear_combo->setIconSet(SmallIconSet("locationbar_erase")); + + pushbutton_url->setIconSet(KGlobal::iconLoader()->loadIconSet("fileopen", KIcon::Small)); + QPixmap pixMap = KGlobal::iconLoader()->loadIcon("fileopen", KIcon::Small); + pushbutton_url->setFixedSize(pixMap.width() + 8, pixMap.height() + 8); + connect(pushbutton_url, SIGNAL(clicked()), this, SLOT(slotChooseUrlDialog())); + + resultsSearchBar->hide(); + + start_search_action_ = static_cast<KToggleAction*> (action_manager_->action("start_search")); + + connect(resultsSearchBar, SIGNAL(signalSearch(LinkMatcher)), + this, SLOT(slotApplyFilter(LinkMatcher))); +} + +void SessionWidget::slotLoadSettings(bool modify_current_widget_settings) +{ + if(modify_current_widget_settings) + { + checkbox_recursively->setChecked(KLSConfig::recursiveCheck()); + spinbox_depth->setValue(KLSConfig::depth()); + checkbox_subdirs_only->setChecked(!KLSConfig::checkParentFolders()); + checkbox_external_links->setChecked(KLSConfig::checkExternalLinks()); + tree_display_ = KLSConfig::displayTreeView(); + tree_view->setTreeDisplay(tree_display_); + } + + search_manager_->setTimeOut(KLSConfig::timeOut()); + + //kdDebug(23100) << "tree_display_: " << tree_display_ << endl; +} + +void SessionWidget::saveCurrentCheckSettings() +{ + KLSConfig::setRecursiveCheck(checkbox_recursively->isChecked()); + KLSConfig::setDepth(spinbox_depth->value()); + KLSConfig::setCheckParentFolders(!checkbox_subdirs_only->isChecked()); + KLSConfig::setCheckExternalLinks(checkbox_external_links->isChecked()); + + KLSConfig::writeConfig(); +} + +void SessionWidget::newSearchManager() +{ + if(search_manager_) + delete search_manager_; + + search_manager_ = new SearchManager(KLSConfig::maxConnectionsNumber(), + KLSConfig::timeOut(), + this, "search_manager"); + Q_ASSERT(search_manager_); + + connect(search_manager_, SIGNAL(signalRootChecked(const LinkStatus *, LinkChecker *)), + this, SLOT(slotRootChecked(const LinkStatus *, LinkChecker *))); + connect(search_manager_, SIGNAL(signalLinkChecked(const LinkStatus *, LinkChecker *)), + this, SLOT(slotLinkChecked(const LinkStatus *, LinkChecker *))); + connect(search_manager_, SIGNAL(signalSearchFinished()), + this, SLOT(slotSearchFinished())); + connect(search_manager_, SIGNAL(signalSearchPaused()), + this, SLOT(slotSearchPaused())); + connect(search_manager_, SIGNAL(signalAddingLevelTotalSteps(uint)), + this, SLOT(slotAddingLevelTotalSteps(uint))); + connect(search_manager_, SIGNAL(signalAddingLevelProgress()), + this, SLOT(slotAddingLevelProgress())); + connect(search_manager_, SIGNAL(signalLinksToCheckTotalSteps(uint)), + this, SLOT(slotLinksToCheckTotalSteps(uint))); +} + +void SessionWidget::setColumns(QStringList const& colunas) +{ + tree_view->setColumns(colunas); +} + +void SessionWidget::setUrl(KURL const& url) +{ + combobox_url->setCurrentText(url.prettyURL()); + combobox_url->setFocus(); +} + +bool SessionWidget::isEmpty() const +{ + Q_ASSERT(tree_view); + return tree_view->isEmpty(); +} + +SearchManager const* SessionWidget::getSearchManager() const +{ + return search_manager_; +} + +void SessionWidget::slotEnableCheckButton(const QString & s) +{ + if(!(stopped_ && !pendingActions())) + return; + + if(!s.isEmpty() && !search_manager_->searching()) + { + start_search_action_->setEnabled(true); + } + else + { + start_search_action_->setEnabled(false); + } +} + +void SessionWidget::slotCheck() +{ + Q_ASSERT(to_start_); + Q_ASSERT(!in_progress_); + Q_ASSERT(!paused_); + Q_ASSERT(stopped_); + + ready_ = false; + if(!validFields()) + { + ready_ = true; + KApplication::beep(); + return; + } + + emit signalSearchStarted(); + + in_progress_ = true; + paused_ = false; + stopped_ = false; + + slotLoadSettings(false); // it seems that KConfigDialogManager is not trigering this slot + + newSearchManager(); + + insertUrlAtCombobox(combobox_url->currentText()); + combobox_url->saveItems(); + progressbar_checker->reset(); + progressbar_checker->setPercentageVisible(true); + progressbar_checker->setTotalSteps(1); // check root page + progressbar_checker->setProgress(0); + textlabel_progressbar->setText(i18n( "Checking..." )); + + textlabel_elapsed_time->setEnabled(true); + //textlabel_elapsed_time_value->setText(""); + textlabel_elapsed_time_value->setEnabled(true); + + //table_linkstatus->clear(); + tree_view->clear(); + + KURL url = Url::normalizeUrl(combobox_url->currentText()); + + if(!url.protocol().startsWith("http")) + { + QString documentRootHint = url.directory().isEmpty() ? "/" : url.directory(); + DocumentRootDialog dialog(this, documentRootHint); + dialog.exec(); + search_manager_->setDocumentRoot(KURL::fromPathOrURL(dialog.url())); + } + + if(KLSConfig::useQuantaUrlPreviewPrefix() && Global::isKLinkStatusEmbeddedInQuanta()) + { + KURL url_aux = Global::urlWithQuantaPreviewPrefix(url); + if(url_aux.isValid() && !url_aux.isEmpty()) + url = url_aux; + } + + if(!checkbox_recursively->isChecked()) + { + search_manager_->setSearchMode(SearchManager::depth); + search_manager_->setDepth(0); + } + + else if(checkbox_recursively->isChecked()) + { + if(spinbox_depth->value() == 0) + { + search_manager_->setSearchMode(SearchManager::domain); + } + else + { + search_manager_->setSearchMode(SearchManager::depth_and_domain); + search_manager_->setDepth(spinbox_depth->value()); + } + + if(checkbox_subdirs_only->isChecked()) + { + search_manager_->setCheckParentDirs(false); + + if(url.hasHost()) + search_manager_->setDomain(url.host() + url.directory(true, false)); + } + else + { + search_manager_->setCheckParentDirs(true); + + if(url.hasHost()) + search_manager_->setDomain(url.host()); + } + if(checkbox_external_links->isChecked()) + { + search_manager_->setCheckExternalLinks(true); + search_manager_->setExternalDomainDepth(1); + } + else + { + search_manager_->setCheckExternalLinks(false); + search_manager_->setExternalDomainDepth(0); + } + } + if(!lineedit_reg_exp->text().isEmpty()) + { + search_manager_->setCheckRegularExpressions(true); + search_manager_->setRegularExpression(lineedit_reg_exp->text(), false); + } + + kdDebug(23100) << "URI: " << url.prettyURL() << endl; + combobox_url->setCurrentText(url.prettyURL()); + search_manager_->startSearch(url); + slotSetTimeElapsed(); +} + +void SessionWidget::keyPressEvent ( QKeyEvent* e ) +{ + if( e->key() == Qt::Key_Return && + ( combobox_url->hasFocus() || + //lineedit_domain->hasFocus() || + //checkbox_depth->hasFocus() || + spinbox_depth->hasFocus() || + //checkbox_domain->hasFocus() || + //spinbox_external_domain->hasFocus() + checkbox_recursively->hasFocus() || + checkbox_external_links->hasFocus() || + checkbox_subdirs_only->hasFocus() ) ) + { + if(validFields()) + { + slotStartSearch(); + } + } + + else if(e->key() == Qt::Key_F6) + { + combobox_url->lineEdit()->selectAll(); + } +} + +bool SessionWidget::validFields() +{ + if(combobox_url->currentText().isEmpty()) + { + KMessageBox::sorry(this, i18n("Cowardly refusing to check an empty URL.")); + return false; + } + + else + return true; +} + +void SessionWidget::slotRootChecked(LinkStatus const* linkstatus, LinkChecker * anal) +{ + slotSetTimeElapsed(); + emit signalUpdateTabLabel(search_manager_->linkStatusRoot(), this); + + Q_ASSERT(textlabel_progressbar->text() == i18n("Checking...") || + textlabel_progressbar->text() == i18n("Stopped")); + + progressbar_checker->setProgress(1); + + //table_linkstatus->insertResult(linkstatus); + TreeViewItem* tree_view_item = new TreeViewItem(tree_view, tree_view->lastItem(), linkstatus); + LinkStatus* ls = const_cast<LinkStatus*> (linkstatus); + ls->setTreeViewItem(tree_view_item); + + if(linkstatus->isRedirection() && linkstatus->redirection()) + slotLinkChecked(linkstatus->redirection(), anal); + + resultsSearchBar->show(); + ActionManager::getInstance()->action("file_export_html")->setEnabled(!isEmpty()); +} + +void SessionWidget::slotLinkChecked(LinkStatus const* linkstatus, LinkChecker * anal) +{ + slotSetTimeElapsed(); + + kdDebug(23100) << textlabel_progressbar->text() << endl; + + Q_ASSERT(textlabel_progressbar->text() == i18n("Checking...") || + textlabel_progressbar->text() == i18n("Stopped")); + + progressbar_checker->setProgress(progressbar_checker->progress() + 1); + + if(linkstatus->checked()) + { + TreeViewItem* tree_view_item = 0; + TreeViewItem* parent_item = linkstatus->parent()->treeViewItem(); + bool match = resultsSearchBar->currentLinkMatcher().matches(*linkstatus); + + if(tree_display_) + { + //kdDebug(23100) << "TREE!!!!!" << endl; + tree_view_item = new TreeViewItem(tree_view, parent_item, parent_item->lastChild(), linkstatus); + + parent_item->setLastChild(tree_view_item); + if(follow_last_link_checked_) + tree_view->ensureRowVisible(tree_view_item, tree_display_); + + tree_view_item->setEnabled(match); + } + else + { + //kdDebug(23100) << "FLAT!!!!!" << endl; + tree_view_item = new TreeViewItem(tree_view, tree_view->lastItem(), linkstatus); + if(follow_last_link_checked_) + tree_view->ensureRowVisible(tree_view_item, tree_display_); + + tree_view_item->setVisible(match); + } + + LinkStatus* ls = const_cast<LinkStatus*> (linkstatus); + ls->setTreeViewItem(tree_view_item); + + if(linkstatus->isRedirection() && linkstatus->redirection()) + slotLinkChecked(linkstatus->redirection(), anal); + } +} + +void SessionWidget::slotSearchFinished() +{ + Q_ASSERT(in_progress_); + Q_ASSERT(!paused_); + Q_ASSERT(!stopped_); + + KApplication::beep (); + + textlabel_progressbar->setText(i18n( "Ready" )); + progressbar_checker->reset(); + progressbar_checker->setPercentageVisible(false); + progressbar_checker->setTotalSteps(1); + progressbar_checker->setProgress(0); + + ready_ = true; + + textlabel_elapsed_time->setEnabled(true); + textlabel_elapsed_time_value->setEnabled(true); + textlabel_elapsed_time_value->setText(search_manager_->timeElapsed().toString("hh:mm:ss")); + + in_progress_ = false; + paused_ = false; + stopped_ = true; + resetPendingActions(); + action_manager_->slotUpdateSessionWidgetActions(this); + + emit signalSearchFinnished(); +} + +void SessionWidget::slotSearchPaused() +{ + Q_ASSERT(pendingActions()); + Q_ASSERT(in_progress_); + + KApplication::beep(); + + textlabel_progressbar->setText(i18n("Stopped")); + + ready_ = true; + + if(to_stop_) + { + in_progress_ = false; + paused_ = false; + stopped_ = true; + } + else + { + Q_ASSERT(to_pause_); + Q_ASSERT(!stopped_); + + paused_ = true; + } + + textlabel_elapsed_time->setEnabled(true); + textlabel_elapsed_time_value->setEnabled(true); + textlabel_elapsed_time_value->setText(search_manager_->timeElapsed().toString("hh:mm:ss")); + + resetPendingActions(); + action_manager_->slotUpdateSessionWidgetActions(this); + + emit signalSearchPaused(); +} + +void SessionWidget::insertUrlAtCombobox(QString const& url) +{ + combobox_url->addToHistory(url); +} + +void SessionWidget::showBottomStatusLabel(QListViewItem* item) +{ + kdDebug(23100) << "SessionWidget::showBottomStatusLabel" << endl; + + if(!item) + return; + + TreeViewItem* _item = tree_view->myItem(item); + if(_item) + { + QString status = _item->linkStatus()->statusText(); + textlabel_status->setText(status); + + if(textlabel_status->sizeHint().width() > textlabel_status->maximumWidth()) + QToolTip::add(textlabel_status, status); + else + QToolTip::remove(textlabel_status); + + bottom_status_timer_.stop(); + bottom_status_timer_.start(5 * 1000, true); + } +} + +void SessionWidget::clearBottomStatusLabel() +{ + textlabel_status->clear(); +} + +void SessionWidget::slotSetTimeElapsed() +{ + textlabel_elapsed_time_value->setText(search_manager_->timeElapsed().toString("hh:mm:ss")); +} + +void SessionWidget::slotAddingLevelTotalSteps(uint steps) +{ + textlabel_progressbar->setText(i18n( "Adding level..." )); + progressbar_checker->reset(); + progressbar_checker->setTotalSteps(steps); + progressbar_checker->setProgress(0); +} + +void SessionWidget::slotAddingLevelProgress() +{ + Q_ASSERT(textlabel_progressbar->text() == i18n( "Adding level..." )); + progressbar_checker->setProgress(progressbar_checker->progress() + 1); +} + +void SessionWidget::slotLinksToCheckTotalSteps(uint steps) +{ + textlabel_progressbar->setText(i18n( "Checking..." )); + progressbar_checker->reset(); + progressbar_checker->setTotalSteps(steps); + progressbar_checker->setProgress(0); +} + +void SessionWidget::slotClearComboUrl() +{ + combobox_url->setCurrentText(""); +} + +void SessionWidget::slotChooseUrlDialog() +{ + setUrl(KFileDialog::getOpenURL()); +} + +void SessionWidget::slotHideSearchPanel() +{ + if(buttongroup_search->isHidden()) + buttongroup_search->show(); + else + buttongroup_search->hide(); +} + +void SessionWidget::setFollowLastLinkChecked(bool follow) +{ + kdDebug(23100) << "setFollowLastLinkChecked: " << follow << endl; + follow_last_link_checked_ = follow; +} + +void SessionWidget::slotFollowLastLinkChecked() +{ + follow_last_link_checked_ = !follow_last_link_checked_; +} + +void SessionWidget::slotResetSearchOptions() +{ + slotLoadSettings(true); + + combobox_url->clear(); + lineedit_reg_exp->clear(); +} + +void SessionWidget::slotStartSearch() +{ + if(in_progress_) + { + start_search_action_->setChecked(true); // do not toggle + Q_ASSERT(!stopped_); + KApplication::beep(); + return; + } + + to_start_ = true; + slotLoadSettings(false); + slotCheck(); + resetPendingActions(); + + action_manager_->slotUpdateSessionWidgetActions(this); +} + +void SessionWidget::slotPauseSearch() +{ + Q_ASSERT(in_progress_); + Q_ASSERT(!stopped_); + + if(pendingActions()) + return; + + to_pause_ = true; + + if(!paused_) + { + Q_ASSERT(!ready_); + Q_ASSERT(search_manager_->searching()); + + search_manager_->cancelSearch(); + } + else + { + Q_ASSERT(ready_); + + paused_ = false; + + textlabel_progressbar->setText(i18n("Checking...")); + ready_ = false; + search_manager_->resume(); + + emit signalSearchStarted(); + slotLoadSettings(isEmpty()); // it seems that KConfigDialogManager is not trigering this slot + + resetPendingActions(); + } +} + +void SessionWidget::slotStopSearch() +{ + Q_ASSERT(in_progress_); + Q_ASSERT(!stopped_); + + if(pendingActions()) + return; + + to_stop_ = true; + + if(!paused_) + { + Q_ASSERT(!ready_); + Q_ASSERT(search_manager_->searching()); + + search_manager_->cancelSearch(); + } + else + { + in_progress_ = false; + paused_ = false; + stopped_ = true; + + action_manager_->slotUpdateSessionWidgetActions(this); + } +} + +bool SessionWidget::pendingActions() const +{ + return (to_start_ || to_pause_ || to_stop_); +} + +void SessionWidget::resetPendingActions() +{ + to_start_ = false; + to_pause_ = false; + to_stop_ = false; +} + +void SessionWidget::slotApplyFilter(LinkMatcher link_matcher) +{ + tree_view->show(link_matcher); +} + +void SessionWidget::slotExportAsHTML( ) +{ + KURL url = KFileDialog::getSaveURL(QString::null,"text/html", 0, i18n("Export Results as HTML")); + + if(url.isEmpty()) + return; + + QString filename; + KTempFile tmp; // ### only used for network export + + if(url.isLocalFile()) + filename = url.path(); + else + filename = tmp.name(); + + KSaveFile *savefile = new KSaveFile(filename); + if(savefile->status() == 0) // ok + { + QTextStream *outputStream = savefile->textStream(); + outputStream->setEncoding(QTextStream::UnicodeUTF8); + + QString xslt_doc = FileManager::read(locate("appdata", "styles/results_stylesheet.xsl")); + XSLT xslt(xslt_doc); +// kdDebug(23100) << search_manager_->toXML() << endl; + QString html_ouptut = xslt.transform(search_manager_->toXML()); + (*outputStream) << html_ouptut << endl; + + savefile->close(); + } + + delete savefile; + + if (url.isLocalFile()) + return; + + KIO::NetAccess::upload(filename, url, 0); +} + + +#include "sessionwidget.moc" diff --git a/klinkstatus/src/ui/sessionwidget.h b/klinkstatus/src/ui/sessionwidget.h new file mode 100644 index 00000000..af525a08 --- /dev/null +++ b/klinkstatus/src/ui/sessionwidget.h @@ -0,0 +1,149 @@ +/*************************************************************************** + * Copyright (C) 2004 by Paulo Moura Guedes * + * moura@kdewebdev.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. * + ***************************************************************************/ + +#ifndef SESSION_WIDGET_H +#define SESSION_WIDGET_H + +#include "sessionwidgetbase.h" +#include "../engine/linkchecker.h" +#include "../engine/linkstatus.h" +class SearchManager; +class TableItem; +class ActionManager; +class LinkMatcher; + +#include <qtimer.h> +#include <qstring.h> +class QStringList; +class QListViewItem; + +class KURL; +class KConfig; +class KToggleAction; + +#include <vector> + +using namespace std; + +class SessionWidget: public SessionWidgetBase +{ + Q_OBJECT + +public: + + SessionWidget(int max_simultaneous_connections = 3, int time_out = 50, + QWidget* parent = 0, const char* name = 0, WFlags f = 0); + + ~SessionWidget(); + + void setColumns(QStringList const& colunas); + void setUrl(KURL const& url); + + bool treeDisplay() const { return tree_display_; } + + bool followLastLinkChecked() const { return follow_last_link_checked_; } + void setFollowLastLinkChecked(bool follow); + + bool isEmpty() const; + SearchManager const* getSearchManager() const; + + bool inProgress() const { return in_progress_; } + bool paused() const { return paused_; } + bool stopped() const { return stopped_; } + +signals: + void signalUpdateTabLabel(const LinkStatus *, SessionWidget*); + void signalSearchStarted(); + void signalSearchPaused(); + void signalSearchFinnished(); + +public slots: + + virtual void slotClearComboUrl(); + void slotLoadSettings(bool modify_current_widget_settings = true); + + void slotStartSearch(); + void slotPauseSearch(); + void slotStopSearch(); + + void slotHideSearchPanel(); + void slotResetSearchOptions(); + void slotFollowLastLinkChecked(); + + void slotExportAsHTML(); + +private slots: + + virtual void slotCheck(); + virtual void slotCancel() {} // FIXME hack + //virtual void slotSuggestDomain(bool toogle); + + void slotEnableCheckButton(const QString &); + void slotRootChecked(LinkStatus const* linkstatus, LinkChecker * anal); + void slotLinkChecked(LinkStatus const* linkstatus, LinkChecker * anal); + void slotSearchFinished(); + void slotSearchPaused(); + /** Shows the status of the clicked URL (row) for 5 seconds */ + void showBottomStatusLabel(QListViewItem* item); + void clearBottomStatusLabel(); + void slotSetTimeElapsed(); + void newSearchManager(); + + void slotAddingLevelTotalSteps(uint steps); + void slotAddingLevelProgress(); + void slotLinksToCheckTotalSteps(uint steps); + + void slotChooseUrlDialog(); + + void slotApplyFilter(LinkMatcher); + +private: + + virtual void keyPressEvent ( QKeyEvent* e ); + bool validFields(); + void insertUrlAtCombobox(QString const& url); + void init(); + void saveCurrentCheckSettings(); + bool pendingActions() const; + void resetPendingActions(); + +private: + SearchManager* search_manager_; + ActionManager* action_manager_; + + bool ready_; + bool to_start_; + bool to_pause_; + bool to_stop_; + bool in_progress_; + bool paused_; + bool stopped_; + + QTimer bottom_status_timer_; + int max_simultaneous_connections_; + int time_out_; + bool tree_display_; // tree/flat result display + bool follow_last_link_checked_; + KToggleAction* start_search_action_; +}; + + + +#endif diff --git a/klinkstatus/src/ui/sessionwidgetbase.ui b/klinkstatus/src/ui/sessionwidgetbase.ui new file mode 100644 index 00000000..0d194143 --- /dev/null +++ b/klinkstatus/src/ui/sessionwidgetbase.ui @@ -0,0 +1,602 @@ +<!DOCTYPE UI><UI version="3.2" stdsetdef="1"> +<class>SessionWidgetBase</class> +<widget class="QWidget"> + <property name="name"> + <cstring>SessionWidgetBase</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>689</width> + <height>683</height> + </rect> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>300</height> + </size> + </property> + <property name="baseSize"> + <size> + <width>1000</width> + <height>500</height> + </size> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QButtonGroup"> + <property name="name"> + <cstring>buttongroup_search</cstring> + </property> + <property name="title"> + <string>Search</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout15</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout14</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout13</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QToolButton"> + <property name="name"> + <cstring>toolButton_clear_combo</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string></string> + </property> + <property name="autoRaise"> + <bool>true</bool> + </property> + </widget> + <widget class="QLabel"> + <property name="name"> + <cstring>textlabel_url</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>4</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>URL: </string> + </property> + <property name="alignment"> + <set>AlignVCenter|AlignLeft</set> + </property> + </widget> + <widget class="KLSHistoryCombo"> + <property name="name"> + <cstring>combobox_url</cstring> + </property> + <property name="focusPolicy"> + <enum>StrongFocus</enum> + </property> + <property name="acceptDrops"> + <bool>false</bool> + </property> + </widget> + <widget class="KPushButton"> + <property name="name"> + <cstring>pushbutton_url</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>4</hsizetype> + <vsizetype>1</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string></string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>Spacer11</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Maximum</enum> + </property> + <property name="sizeHint"> + <size> + <width>16</width> + <height>20</height> + </size> + </property> + </spacer> + </hbox> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout10</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QCheckBox"> + <property name="name"> + <cstring>checkbox_recursively</cstring> + </property> + <property name="text"> + <string>Recursivel&y:</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + <property name="toolTip" stdset="0"> + <string>Check pages recursively</string> + </property> + </widget> + <widget class="QSpinBox"> + <property name="name"> + <cstring>spinbox_depth</cstring> + </property> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="specialValueText"> + <string>Unlimited</string> + </property> + <property name="maxValue"> + <number>15</number> + </property> + <property name="minValue"> + <number>0</number> + </property> + <property name="value"> + <number>0</number> + </property> + <property name="toolTip" stdset="0"> + <string></string> + </property> + </widget> + <widget class="QCheckBox"> + <property name="name"> + <cstring>checkbox_subdirs_only</cstring> + </property> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="text"> + <string>Do &not check parent folders</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer4</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>160</width> + <height>20</height> + </size> + </property> + </spacer> + </hbox> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout11</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QCheckBox"> + <property name="name"> + <cstring>checkbox_external_links</cstring> + </property> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="text"> + <string>Chec&k external links</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer5</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>MinimumExpanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>174</width> + <height>20</height> + </size> + </property> + </spacer> + </hbox> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout11</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>textLabel1</cstring> + </property> + <property name="text"> + <string>Do not check regular expression:</string> + </property> + </widget> + <widget class="QLineEdit"> + <property name="name"> + <cstring>lineedit_reg_exp</cstring> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer5_2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Maximum</enum> + </property> + <property name="sizeHint"> + <size> + <width>16</width> + <height>20</height> + </size> + </property> + </spacer> + </hbox> + </widget> + </vbox> + </widget> + </hbox> + </widget> + </vbox> + </widget> + <widget class="ResultsSearchBar"> + <property name="name"> + <cstring>resultsSearchBar</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + <widget class="TreeView"> + <property name="name"> + <cstring>tree_view</cstring> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>300</height> + </size> + </property> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout10</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>textlabel_progressbar</cstring> + </property> + <property name="minimumSize"> + <size> + <width>94</width> + <height>0</height> + </size> + </property> + <property name="text"> + <string>Ready</string> + </property> + </widget> + <widget class="KProgress"> + <property name="name"> + <cstring>progressbar_checker</cstring> + </property> + <property name="totalSteps"> + <number>1</number> + </property> + <property name="progress"> + <number>0</number> + </property> + <property name="percentageVisible"> + <bool>false</bool> + </property> + </widget> + </hbox> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout11</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="KSqueezedTextLabel"> + <property name="name"> + <cstring>textlabel_status</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>3</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="maximumSize"> + <size> + <width>470</width> + <height>32767</height> + </size> + </property> + <property name="text"> + <string></string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer5_2_3</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Preferred</enum> + </property> + <property name="sizeHint"> + <size> + <width>30</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout12_2</cstring> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel" row="1" column="0"> + <property name="name"> + <cstring>textlabel_elapsed_time</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>4</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Elapsed time:</string> + </property> + <property name="toolTip" stdset="0"> + <string>hh:mm:ss.zzz</string> + </property> + </widget> + <widget class="QLabel" row="1" column="1"> + <property name="name"> + <cstring>textlabel_elapsed_time_value</cstring> + </property> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>4</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>80</width> + <height>0</height> + </size> + </property> + <property name="text"> + <string></string> + </property> + <property name="toolTip" stdset="0"> + <string>hh:mm:ss.zzz</string> + </property> + </widget> + </grid> + </widget> + </hbox> + </widget> + </vbox> +</widget> +<customwidgets> + <customwidget> + <class>KLSHistoryCombo</class> + <header location="global">klshistorycombo.h</header> + <sizehint> + <width>-1</width> + <height>-1</height> + </sizehint> + <container>0</container> + <sizepolicy> + <hordata>5</hordata> + <verdata>5</verdata> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + <pixmap>image0</pixmap> + </customwidget> + <customwidget> + <class>TreeView</class> + <header location="local">treeview.h</header> + <sizehint> + <width>-1</width> + <height>-1</height> + </sizehint> + <container>0</container> + <sizepolicy> + <hordata>7</hordata> + <verdata>7</verdata> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + <pixmap>image0</pixmap> + </customwidget> + <customwidget> + <class>ResultsSearchBar</class> + <header location="local">resultssearchbar.h</header> + <sizehint> + <width>-1</width> + <height>-1</height> + </sizehint> + <container>0</container> + <sizepolicy> + <hordata>5</hordata> + <verdata>5</verdata> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + <pixmap>image1</pixmap> + </customwidget> +</customwidgets> +<images> + <image name="image0"> + <data format="XBM.GZ" length="79">789c534e494dcbcc4b554829cdcdad8c2fcf4c29c95030e0524611cd48cd4ccf28010a1797249664262b2467241641a592324b8aa363156c15aab914146aadb90067111b1f</data> + </image> + <image name="image1"> + <data format="PNG" length="824">89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b000002ff49444154388db59531681c4714863f992dde820cb370815b50600f54e8ca0ba43970712a8fb838438a3895634813d238a5ab80e314ae4d0a812060a4226017c27221c8a9da6b8c4fe0e00d28b0571cec82043b85611f78c12966efa4bb8bc085f29a6567df7cef9f7fdeccaec571cc2cbaddee47ae21e2385e5b9b815f1ebcfcd8de6a63ad25cb338af7c52741acb5a4a729a3d723a82ec6bd99d267bf3f23fc1c4cab2442d14a915986e792fdfa59569766573049417784f1b12e8267954dab24b78714450a28beaf941f847c2a14e70a0841035a2d45d641eb027213c210c69756320767794684d6508bef0befde1a860796e4c402333542b4256c0f0cdd1e50b97191458be6e0e27d81563a87c643d8fb2d7793d685d696413cc8a6cae46f65f7d79c7c62b87b4f2e15fd0fb0d302be0fefde4a0d557a5f35e90f84e0334014d590f855c9de4ecee17e4eb319d1ff3a00ec02f8c67299f283307c61e7d06fbf1782d082588a33e1cf1705fd81cf773f3601e1f9bec59e2f4b5c7ef5209f0ac95f16630cfd818067c103b586dd274a726229cee0fe8380d191cb4d1267d3d58aa1de7d258ceae5d7d0a78fdd269a86f0c52d414c49bbe3762c9b686de41560d7a72e41c4795a6486a78f95e4c4151481d686efbe7b3398ac58b1a23868b8c474aaa8068c8e714a8dd06c1af2a9e5d1c38c641c909dba6e08237f19b358a7ac5cf3479bc2e41f257e55d2ffc6a73833746f09e186cfa387904f2cbffc90a2aa9886d0e99464d3c5965b512cebd01f1800f67672e2a392fb0f023a3d883a053ffddcc2340dd65ab452b6074dc2cd15c1cbceb863daed413e353cdfcfd97d92333a12da6d0181ec3443cf753ef3cdd092de0e116ff1a02cdc157338ca9d7b8269461cfee1ba2139b9286e1a427f10110f2d561555b076d18a39383d4d99a4c0cd0b787f20747b214962c8266e3cdcf0e97c59126ec2f6edd089f40a92f115e0d1eb11ba238461dd6a15f32b53666de841965bb203575a3cc15a48c64a965fe57105e3635db8fa96dcffc431172b5d715d7103dc3fea7f015f373c8ee3b57f0135105a0fae7717960000000049454e44ae426082</data> + </image> +</images> +<connections> + <connection> + <sender>checkbox_recursively</sender> + <signal>toggled(bool)</signal> + <receiver>spinbox_depth</receiver> + <slot>setEnabled(bool)</slot> + </connection> + <connection> + <sender>checkbox_recursively</sender> + <signal>toggled(bool)</signal> + <receiver>checkbox_external_links</receiver> + <slot>setEnabled(bool)</slot> + </connection> + <connection> + <sender>checkbox_recursively</sender> + <signal>toggled(bool)</signal> + <receiver>checkbox_subdirs_only</receiver> + <slot>setEnabled(bool)</slot> + </connection> + <connection> + <sender>toolButton_clear_combo</sender> + <signal>clicked()</signal> + <receiver>SessionWidgetBase</receiver> + <slot>slotClearComboUrl()</slot> + </connection> +</connections> +<tabstops> + <tabstop>combobox_url</tabstop> + <tabstop>checkbox_recursively</tabstop> + <tabstop>spinbox_depth</tabstop> + <tabstop>checkbox_subdirs_only</tabstop> + <tabstop>checkbox_external_links</tabstop> +</tabstops> +<slots> + <slot specifier="pure virtual">slotCheck()</slot> + <slot specifier="pure virtual">slotCancel()</slot> + <slot specifier="pure virtual">slotClearComboUrl()</slot> +</slots> +<layoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>klshistorycombo.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>resultssearchbar.h</includehint> + <includehint>treeview.h</includehint> + <includehint>kprogress.h</includehint> + <includehint>ksqueezedtextlabel.h</includehint> +</includehints> +</UI> diff --git a/klinkstatus/src/ui/settings/Makefile.am b/klinkstatus/src/ui/settings/Makefile.am new file mode 100644 index 00000000..777e9e5c --- /dev/null +++ b/klinkstatus/src/ui/settings/Makefile.am @@ -0,0 +1,7 @@ +INCLUDES = -I$(top_builddir)/klinkstatus/src/cfg -I$(top_builddir)/klinkstatus/src $(all_includes) +METASOURCES = AUTO +libsettings_la_LDFLAGS = $(all_libraries) +noinst_LTLIBRARIES = libsettings.la +libsettings_la_SOURCES = configsearchdialog.ui dummy.cpp configresultsdialog.ui \ + configidentificationdialog.cpp configidentificationdialogui.ui +noinst_HEADERS = configidentificationdialog.h diff --git a/klinkstatus/src/ui/settings/configidentificationdialog.cpp b/klinkstatus/src/ui/settings/configidentificationdialog.cpp new file mode 100644 index 00000000..3dcd1239 --- /dev/null +++ b/klinkstatus/src/ui/settings/configidentificationdialog.cpp @@ -0,0 +1,55 @@ +/*************************************************************************** + * Copyright (C) 2006 by Paulo Moura Guedes * + * moura@kdewebdev.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 "configidentificationdialog.h" + +#include <kprotocolmanager.h> +#include <kpushbutton.h> +#include <klineedit.h> + +#include <qstring.h> + +#include "../cfg/klsconfig.h" + + +ConfigIdentificationDialog::ConfigIdentificationDialog(QWidget *parent, const char *name) + : ConfigIdentificationDialogUi(parent, name) +{ + if(KLSConfig::userAgent().isEmpty()) + { + slotDefaultUA(); + } + + connect(buttonDefault, SIGNAL(clicked()), this, SLOT(slotDefaultUA())); +} + + +ConfigIdentificationDialog::~ConfigIdentificationDialog() +{ +} + +void ConfigIdentificationDialog::slotDefaultUA() +{ + KLSConfig::setUserAgent(KProtocolManager::defaultUserAgent()); + kcfg_UserAgent->setText(KLSConfig::userAgent()); +} + + +#include "configidentificationdialog.moc" diff --git a/klinkstatus/src/ui/settings/configidentificationdialog.h b/klinkstatus/src/ui/settings/configidentificationdialog.h new file mode 100644 index 00000000..e75a65a6 --- /dev/null +++ b/klinkstatus/src/ui/settings/configidentificationdialog.h @@ -0,0 +1,40 @@ +/*************************************************************************** + * Copyright (C) 2006 by Paulo Moura Guedes * + * moura@kdewebdev.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. * + ***************************************************************************/ + +#ifndef CONFIGIDENTIFICATIONDIALOG_H +#define CONFIGIDENTIFICATIONDIALOG_H + +#include "configidentificationdialogui.h" + +/** + @author Paulo Moura Guedes <moura@kdewebdev.org> +*/ +class ConfigIdentificationDialog : public ConfigIdentificationDialogUi +{ +Q_OBJECT +public: + ConfigIdentificationDialog(QWidget *parent = 0, const char *name = 0); + ~ConfigIdentificationDialog(); + +private slots: + void slotDefaultUA(); +}; + +#endif diff --git a/klinkstatus/src/ui/settings/configidentificationdialogui.ui b/klinkstatus/src/ui/settings/configidentificationdialogui.ui new file mode 100644 index 00000000..29723358 --- /dev/null +++ b/klinkstatus/src/ui/settings/configidentificationdialogui.ui @@ -0,0 +1,134 @@ +<!DOCTYPE UI><UI version="3.2" stdsetdef="1"> +<class>ConfigIdentificationDialogUi</class> +<widget class="QWidget"> + <property name="name"> + <cstring>ConfigIdentificationDialogUi</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>570</width> + <height>113</height> + </rect> + </property> + <property name="font"> + <font> + <bold>1</bold> + </font> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QButtonGroup"> + <property name="name"> + <cstring>buttonGroup4</cstring> + </property> + <property name="font"> + <font> + <bold>0</bold> + </font> + </property> + <property name="title"> + <string>Identification</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel" row="1" column="0"> + <property name="name"> + <cstring>textLabel1</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="font"> + <font> + </font> + </property> + <property name="text"> + <string>User-Agent</string> + </property> + </widget> + <widget class="KLineEdit" row="1" column="1"> + <property name="name"> + <cstring>kcfg_UserAgent</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>3</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>300</width> + <height>0</height> + </size> + </property> + </widget> + <widget class="KPushButton" row="1" column="2"> + <property name="name"> + <cstring>buttonDefault</cstring> + </property> + <property name="text"> + <string>Default</string> + </property> + </widget> + <widget class="QCheckBox" row="0" column="0" rowspan="1" colspan="3"> + <property name="name"> + <cstring>kcfg_SendIdentification</cstring> + </property> + <property name="text"> + <string>Send Identification</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + </grid> + </widget> + </vbox> +</widget> +<customwidgets> +</customwidgets> +<connections> + <connection> + <sender>kcfg_SendIdentification</sender> + <signal>toggled(bool)</signal> + <receiver>textLabel1</receiver> + <slot>setEnabled(bool)</slot> + </connection> + <connection> + <sender>kcfg_SendIdentification</sender> + <signal>toggled(bool)</signal> + <receiver>kcfg_UserAgent</receiver> + <slot>setEnabled(bool)</slot> + </connection> + <connection> + <sender>kcfg_SendIdentification</sender> + <signal>toggled(bool)</signal> + <receiver>buttonDefault</receiver> + <slot>setEnabled(bool)</slot> + </connection> +</connections> +<tabstops> + <tabstop>kcfg_SendIdentification</tabstop> + <tabstop>kcfg_UserAgent</tabstop> + <tabstop>buttonDefault</tabstop> +</tabstops> +<layoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>klineedit.h</includehint> + <includehint>kpushbutton.h</includehint> +</includehints> +</UI> diff --git a/klinkstatus/src/ui/settings/configresultsdialog.ui b/klinkstatus/src/ui/settings/configresultsdialog.ui new file mode 100644 index 00000000..544f3273 --- /dev/null +++ b/klinkstatus/src/ui/settings/configresultsdialog.ui @@ -0,0 +1,72 @@ +<!DOCTYPE UI><UI version="3.2" stdsetdef="1"> +<class>ConfigResultsDialog</class> +<widget class="QWidget"> + <property name="name"> + <cstring>ConfigResultsDialog</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>233</width> + <height>183</height> + </rect> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QButtonGroup"> + <property name="name"> + <cstring>buttonGroup13</cstring> + </property> + <property name="title"> + <string>View</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QRadioButton"> + <property name="name"> + <cstring>kcfg_DisplayTreeView</cstring> + </property> + <property name="text"> + <string>Tree</string> + </property> + </widget> + <widget class="QRadioButton"> + <property name="name"> + <cstring>kcfg_DisplayFlatView</cstring> + </property> + <property name="text"> + <string>Flat</string> + </property> + </widget> + </vbox> + </widget> + <widget class="QButtonGroup"> + <property name="name"> + <cstring>buttonGroup13_2</cstring> + </property> + <property name="title"> + <string>Misc</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QRadioButton"> + <property name="name"> + <cstring>kcfg_FollowLastLinkChecked</cstring> + </property> + <property name="text"> + <string>Follow Last Link Checked</string> + </property> + </widget> + </vbox> + </widget> + </vbox> +</widget> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/klinkstatus/src/ui/settings/configsearchdialog.ui b/klinkstatus/src/ui/settings/configsearchdialog.ui new file mode 100644 index 00000000..604a431c --- /dev/null +++ b/klinkstatus/src/ui/settings/configsearchdialog.ui @@ -0,0 +1,353 @@ +<!DOCTYPE UI><UI version="3.2" stdsetdef="1"> +<class>ConfigSearchDialog</class> +<widget class="QWidget"> + <property name="name"> + <cstring>ConfigSearchDialog</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>459</width> + <height>365</height> + </rect> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QButtonGroup"> + <property name="name"> + <cstring>buttonGroup13</cstring> + </property> + <property name="title"> + <string>Network</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="KIntSpinBox" row="0" column="1"> + <property name="name"> + <cstring>kcfg_MaxConnectionsNumber</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="maxValue"> + <number>1000</number> + </property> + <property name="minValue"> + <number>1</number> + </property> + <property name="value"> + <number>5</number> + </property> + </widget> + <widget class="QLabel" row="1" column="0"> + <property name="name"> + <cstring>textLabel1_2_2</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>4</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Timeout in seconds:</string> + </property> + </widget> + <widget class="KIntSpinBox" row="1" column="1"> + <property name="name"> + <cstring>kcfg_TimeOut</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="maxValue"> + <number>3600</number> + </property> + <property name="minValue"> + <number>1</number> + </property> + <property name="value"> + <number>40</number> + </property> + </widget> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel1_2</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>4</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Number of simultaneous connections:</string> + </property> + </widget> + </grid> + </widget> + <widget class="QButtonGroup"> + <property name="name"> + <cstring>buttonGroup8</cstring> + </property> + <property name="title"> + <string>Input</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="KIntSpinBox" row="0" column="1"> + <property name="name"> + <cstring>kcfg_MaxCountComboUrl</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="maxValue"> + <number>1000</number> + </property> + <property name="minValue"> + <number>5</number> + </property> + <property name="value"> + <number>50</number> + </property> + </widget> + <widget class="QCheckBox" row="2" column="0"> + <property name="name"> + <cstring>kcfg_CheckParentFolders</cstring> + </property> + <property name="text"> + <string>Check parent folders</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel1</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>4</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Number of items in URL history:</string> + </property> + </widget> + <widget class="QCheckBox" row="3" column="0"> + <property name="name"> + <cstring>kcfg_CheckExternalLinks</cstring> + </property> + <property name="text"> + <string>Check external links</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + <widget class="QLayoutWidget" row="1" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>layout21</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QCheckBox"> + <property name="name"> + <cstring>kcfg_RecursiveCheck</cstring> + </property> + <property name="text"> + <string>Recursive</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer25</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Maximum</enum> + </property> + <property name="sizeHint"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout20</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>textLabel1_2_2_2</cstring> + </property> + <property name="text"> + <string>Depth:</string> + </property> + </widget> + <widget class="KIntSpinBox"> + <property name="name"> + <cstring>kcfg_Depth</cstring> + </property> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="specialValueText"> + <string>Unlimited</string> + </property> + <property name="maxValue"> + <number>15</number> + </property> + <property name="minValue"> + <number>0</number> + </property> + <property name="value"> + <number>1</number> + </property> + </widget> + </hbox> + </widget> + </hbox> + </widget> + </grid> + </widget> + <widget class="QButtonGroup"> + <property name="name"> + <cstring>buttonGroup3</cstring> + </property> + <property name="title"> + <string>Quanta</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QCheckBox" row="0" column="0"> + <property name="name"> + <cstring>kcfg_UseQuantaUrlPreviewPrefix</cstring> + </property> + <property name="text"> + <string>Use preview prefix</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + <property name="toolTip" stdset="0"> + <string>Check this one if you want to use Quanta's project preview prefix in the URL to check</string> + </property> + </widget> + </grid> + </widget> + <widget class="QCheckBox"> + <property name="name"> + <cstring>kcfg_RememberCheckSettings</cstring> + </property> + <property name="text"> + <string>Remember settings when exit</string> + </property> + </widget> + </vbox> +</widget> +<customwidgets> +</customwidgets> +<connections> + <connection> + <sender>kcfg_RecursiveCheck</sender> + <signal>toggled(bool)</signal> + <receiver>kcfg_Depth</receiver> + <slot>setEnabled(bool)</slot> + </connection> + <connection> + <sender>kcfg_RecursiveCheck</sender> + <signal>toggled(bool)</signal> + <receiver>textLabel1_2_2_2</receiver> + <slot>setEnabled(bool)</slot> + </connection> + <connection> + <sender>kcfg_RecursiveCheck</sender> + <signal>toggled(bool)</signal> + <receiver>kcfg_CheckParentFolders</receiver> + <slot>setEnabled(bool)</slot> + </connection> + <connection> + <sender>kcfg_RecursiveCheck</sender> + <signal>toggled(bool)</signal> + <receiver>kcfg_CheckExternalLinks</receiver> + <slot>setEnabled(bool)</slot> + </connection> +</connections> +<tabstops> + <tabstop>kcfg_MaxConnectionsNumber</tabstop> + <tabstop>kcfg_TimeOut</tabstop> + <tabstop>kcfg_MaxCountComboUrl</tabstop> + <tabstop>kcfg_RecursiveCheck</tabstop> + <tabstop>kcfg_Depth</tabstop> + <tabstop>kcfg_CheckParentFolders</tabstop> + <tabstop>kcfg_CheckExternalLinks</tabstop> + <tabstop>kcfg_RememberCheckSettings</tabstop> +</tabstops> +<layoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>knuminput.h</includehint> + <includehint>knuminput.h</includehint> + <includehint>knuminput.h</includehint> + <includehint>knuminput.h</includehint> +</includehints> +</UI> diff --git a/klinkstatus/src/ui/settings/dummy.cpp b/klinkstatus/src/ui/settings/dummy.cpp new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/klinkstatus/src/ui/settings/dummy.cpp diff --git a/klinkstatus/src/ui/tablelinkstatus.cpp b/klinkstatus/src/ui/tablelinkstatus.cpp new file mode 100644 index 00000000..695365a9 --- /dev/null +++ b/klinkstatus/src/ui/tablelinkstatus.cpp @@ -0,0 +1,750 @@ +/*************************************************************************** + * Copyright (C) 2004 by Paulo Moura Guedes * + * moura@kdewebdev.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 <qmemarray.h> +#include <qtooltip.h> +#include <qpixmap.h> +#include <qclipboard.h> +#include <qpainter.h> +#include <qprocess.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(QWidget * parent, const char * name, + int column_index_status, + int column_index_label, + int column_index_URL) + : QTable(parent, name), + ResultView(column_index_status, column_index_label, column_index_URL) + //context_table_menu_(this, "context_table_menu") +{ + setShowGrid(false); + setSorting(false); + setSelectionMode(QTable::NoSelection); + setFocusStyle(QTable::FollowStyle); + setReadOnly(true); + + verticalHeader()->hide(); + setLeftMargin(0); + + cell_tip_ = new CellToolTip(this); + + sub_menu_ = new QPopupMenu(this, "sub_menu_referrers"); + + connect(this, SIGNAL( contextMenuRequested ( int, int, const QPoint& )), + this, SLOT( slotPopupContextMenu( int, int, const QPoint&)) ); +} + +TableLinkstatus::~TableLinkstatus() +{ + delete cell_tip_; +} + +void TableLinkstatus::setColumns(QStringList const& columns) +{ + ResultView::setColumns(columns); + + removeColunas(); + setNumCols(columns.size()); + + QHeader* 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(LinkStatus const* linkstatus) +{ + insereLinha(generateRowOfTableItems(linkstatus)); +} + +vector<TableItem*> TableLinkstatus::generateRowOfTableItems(LinkStatus const* linkstatus) +{ + vector<TableItem*> items; + int column = 1; + + TableItem* item1 = new TableItemStatus(this, QTableItem::Never, + linkstatus, column++); + TableItem* item2 = new TableItemNome(this, QTableItem::Never, + linkstatus, column++); + TableItem* item3 = new TableItemURL(this, QTableItem::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]->sizeHint().width() > columnWidth(col_url_ - 1)) + { + setColumnStretchable(col_url_ - 1, false); + setColumnWidth(col_url_ - 1, items[col_url_ - 1]->sizeHint().width()); + } + + ensureCellVisible(row, 0); +} + +void TableLinkstatus::clear() +{ + QMemArray<int> linhas(numRows()); + for(uint i = 0; i != linhas.size(); ++i) + linhas[i] = i + 1; + + removeRows(linhas); + + Q_ASSERT(numRows() == 0); +} + +void TableLinkstatus::removeColunas() +{ + QMemArray<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::Status const& status) +{ + for(int i = 0; i != numRows(); ++i) + { + int row = i; + TableItem* _item = myItem(row, col_status_); + + if(!ResultView::displayableWithStatus(_item->linkStatus(), 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; + QTableItem* _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())) + QTable::ensureCellVisible(row, col); +} + +bool TableLinkstatus::textFitsInCell(int row, int col) const +{ + QTableItem* itm(myItem(row, col)); + Q_ASSERT(itm); + + QSize size_hint(itm->sizeHint()); + 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*> (QTable::item(row, col)); + Q_ASSERT(_item); + return _item; +} + +void TableLinkstatus::slotPopupContextMenu(int r, int w, const QPoint& pos) +{ + TableItem* table_item = myItem(r, w); + if(table_item) + { + QValueVector<KURL> referrers = table_item->linkStatus()->referrers(); + loadContextTableMenu(referrers, table_item->linkStatus()->isRoot()); + context_table_menu_.popup(pos); + } +} + +void TableLinkstatus::loadContextTableMenu(QValueVector<KURL> const& referrers, bool is_root) +{ + context_table_menu_.clear(); + sub_menu_->clear(); + + if(!is_root) + { + sub_menu_->insertItem(i18n("All"), this, SLOT(slotEditReferrersWithQuanta())); + sub_menu_->insertSeparator(); + + for(uint i = 0; i != referrers.size(); ++i) + { + sub_menu_->insertItem(referrers[i].prettyURL()); + } + connect(sub_menu_, SIGNAL(activated(int)), this, 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, SLOT(slotViewUrlInBrowser())); + + context_table_menu_.insertItem(SmallIconSet("fileopen"), i18n("Open Referrer URL"), + this, SLOT(slotViewParentUrlInBrowser())); + + context_table_menu_.insertSeparator(); + + context_table_menu_.insertItem(SmallIconSet("editcopy"), i18n("Copy URL"), + this, SLOT(slotCopyUrlToClipboard())); + + context_table_menu_.insertItem(SmallIconSet("editcopy"), i18n("Copy Referrer URL"), + this, SLOT(slotCopyParentUrlToClipboard())); + + context_table_menu_.insertItem(SmallIconSet("editcopy"), i18n("Copy Cell Text"), + this, SLOT(slotCopyCellTextToClipboard())); +} + +void TableLinkstatus::slotCopyUrlToClipboard() const +{ + TableItem* _item = myItem(currentRow(), currentColumn()); + QString content(_item->linkStatus()->absoluteUrl().prettyURL()); + QClipboard* cb = kapp->clipboard(); + cb->setText(content); +} + +void TableLinkstatus::slotCopyParentUrlToClipboard() const +{ + TableItem* _item = myItem(currentRow(), currentColumn()); + QString content(_item->linkStatus()->parent()->absoluteUrl().prettyURL()); + QClipboard* cb = kapp->clipboard(); + cb->setText(content); +} + +void TableLinkstatus::slotCopyCellTextToClipboard() const +{ + QString cell_text(text(currentRow(), currentColumn())); + QClipboard* cb = kapp->clipboard(); + cb->setText(cell_text); +} + +void TableLinkstatus::slotEditReferrersWithQuanta() +{ + TableItem* _item = myItem(currentRow(), currentColumn()); + QValueVector<KURL> referrers = _item->linkStatus()->referrers(); + + if(Global::isQuantaAvailableViaDCOP()) + { + for(uint i = 0; i != referrers.size(); ++i) + slotEditReferrerWithQuanta(referrers[i]); + } + else + { + QStringList 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()); + QValueVector<KURL> referrers = _item->linkStatus()->referrers(); + Q_ASSERT(index >= 0 && (uint)index < referrers.size()); + + slotEditReferrerWithQuanta(referrers[index]); +} + +void TableLinkstatus::slotEditReferrerWithQuanta(KURL const& url) +{ + QString filePath = url.url(); + + if(Global::isQuantaAvailableViaDCOP()) + { + DCOPRef quanta(Global::quantaDCOPAppId(),"WindowManagerIf"); + bool success = quanta.send("openFile", filePath, 0, 0); + + if(!success) + { + QString message = i18n("<qt>File <b>%1</b> cannot be opened. Might be a DCOP problem.</qt>").arg(filePath); + KMessageBox::error(parentWidget(), message); + } + } + else + { + QStringList args(url.url()); + Global::openQuanta(args); + } +} + +void TableLinkstatus::slotViewUrlInBrowser() +{ + TableItem* _item = myItem(currentRow(), currentColumn()); + KURL url = _item->linkStatus()->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->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.")); + } +} + +/* + +********************* TableItem *************************** + +*/ + +TableItem::TableItem(QTable* table, EditType et, + LinkStatus const* linkstatus, + int column_index, int alignment) + : QTableItem(table, et, ""), ResultViewItem(linkstatus, column_index), + /*ls_((LinkStatus*)linkstatus), + column_index_(column_index),*/ alignment_(alignment) +{ + //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::setAlignment(int aFlags) +{ + alignment_ = aFlags; +} + +int TableItem::alignment() const +{ + return alignment_; +} +/* +LinkStatus const* const TableItem::linkStatus() const +{ + Q_ASSERT(ls_); + return ls_; +} + +QColor const& TableItem::textStatusColor() const +{ + if(linkStatus()->errorOccurred()) + { + //kdDebug(23100) << "ERROR: " << linkStatus()->error() << ": " << linkStatus()->absoluteUrl().prettyURL() << endl; + if(linkStatus()->error() == i18n( "Javascript not supported" )) + return Qt::lightGray; + else + return Qt::red; + } + + else if(linkStatus()->absoluteUrl().hasRef()) + return Qt::blue; + + else if(linkStatus()->absoluteUrl().protocol() != "http" && + linkStatus()->absoluteUrl().protocol() != "https") + return Qt::darkGreen; + + else + { + QString status_code(QString::number(linkStatus()->httpHeader().statusCode())); + + if(status_code[0] == '0') + { + kdWarning(23100) << "status code == 0: " << endl; + kdWarning(23100) << linkStatus()->toString() << endl; + kdWarning(23100) << linkStatus()->httpHeader().toString() << endl; + } + //Q_ASSERT(status_code[0] != '0'); + + if(status_code[0] == '5') + return Qt::darkMagenta; + + else if(status_code[0] == '4') + return Qt::red; + + else if(status_code[0] == '3') + return Qt::blue; + + else if(status_code[0] == '2') + return Qt::darkGreen; + + else + return Qt::red; + } +} +*/ + +/* + +********************* TableItemURL *************************** + +*/ + +TableItemURL::TableItemURL(QTable* table, EditType et, + LinkStatus const* linkstatus, int column_index) + : TableItem(table, et, linkstatus, column_index) +{ + setText(); +} + +void TableItemURL::setText() +{ + if(linkStatus()->node() && linkStatus()->malformed()) + { + if(linkStatus()->node()->url().isEmpty()) + QTableItem::setText( linkStatus()->node()->content().simplifyWhiteSpace() ); + else + QTableItem::setText( linkStatus()->node()->url() ); + } + else + { + KURL url = linkStatus()->absoluteUrl(); + QTableItem::setText(::convertToLocal(linkStatus())); + } +} + +void TableItemURL::setPixmap() +{} + +QString TableItemURL::toolTip() const +{ + return text(); // Pode parecer repeticao mas nao eh... Ver construtor +} + +void TableItemURL::paint( QPainter *p, const QColorGroup &cg, + const QRect &cr, bool selected ) +{ + // Get a color to draw the text + QColorGroup m_cg(cg); + QColor color(textStatusColor()); + m_cg.setColor(QColorGroup::Text, color); + + QTableItem::paint(p, m_cg, cr, selected); +} + +QColor const& TableItemURL::textStatusColor() const +{ + // TODO clean this code + + QString status_code(QString::number(linkStatus()->httpHeader().statusCode())); + + if(linkStatus()->errorOccurred()) + { + if(linkStatus()->error().contains(i18n( "Timeout" ))) + return darkMagenta; + else if(linkStatus()->error().contains(i18n( "not supported" ))) + return lightGray; + else + return red; + } + else if(linkStatus()->absoluteUrl().protocol() != "http" && + linkStatus()->absoluteUrl().protocol() != "https") + return black; + + else if(status_code[0] == '5') + return darkMagenta; + + else if(status_code[0] == '4') + return red; + + else + return black; +} + +/* + +********************* TableItemStatus *************************** + +*/ + +TableItemStatus::TableItemStatus(QTable* table, EditType et, + LinkStatus const* linkstatus, int column_index) + : TableItem(table, et, linkstatus, column_index) +{ + setAlignment(Qt::AlignHCenter /*| Qt :: AlignVCenter*/); + setText(); + setPixmap(); +} + +void TableItemStatus::setText() +{ + if(linkStatus()->errorOccurred() || + linkStatus()->status() == "OK" || + linkStatus()->status() == "304") + { + QTableItem::setText(""); + } + else + { + /* + if(linkStatus()->httpHeader().statusCode() == 0) + { + kdDebug(23100) << "TableItemStatus::setText : statusCode() == 0" << endl; + kdDebug(23100) << linkStatus()->toString() << endl; + kdDebug(23100) << linkStatus()->docHtml() << endl; + } + */ + //Q_ASSERT(linkStatus()->httpHeader().statusCode() != 0); //<------------------------------------------------------------ + //QTableItem::setText( QString::number(linkStatus()->httpHeader().statusCode()) ); + QTableItem::setText( linkStatus()->status() ); + } +} + +void TableItemStatus::setPixmap() +{ + if(linkStatus()->errorOccurred()) + { + + if(linkStatus()->error().contains(i18n( "Timeout" ))) + { + QTableItem::setPixmap(SmallIcon("kalarm")); + } + else if(linkStatus()->error() == i18n( "Malformed" )) + { + QTableItem::setPixmap(SmallIcon("bug")); + } + else + { + QTableItem::setPixmap(SmallIcon("no")); + } + } + else if(linkStatus()->status() == "304") + QTableItem::setPixmap(UserIcon("304")); + + else if(linkStatus()->status() == "OK") + QTableItem::setPixmap(SmallIcon("ok")); +} + +QString TableItemStatus::toolTip() const +{ + if(linkStatus()->errorOccurred() || + linkStatus()->absoluteUrl().hasRef() || + (linkStatus()->absoluteUrl().protocol() != "http" && + linkStatus()->absoluteUrl().protocol() != "https")) + { + return i18n("%1").arg(linkStatus()->status()); + } + else + return i18n("%1").arg(linkStatus()->httpHeader().reasonPhrase()); +} + +void TableItemStatus::paint( QPainter *p, const QColorGroup &cg, + const QRect &cr, bool selected ) +{ + p->fillRect( 0, 0, cr.width(), cr.height(), + selected ? cg.brush( QColorGroup::Highlight ) + : cg.brush( QColorGroup::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 + QColorGroup m_cg(cg); + QColor color(textStatusColor()); + m_cg.setColor(QColorGroup::Text, color); + + //QTableItem::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() ? (alignment() | WordBreak) : alignment(), text() ); +} + +/* + +********************* TableItemNome *************************** + +*/ + +TableItemNome::TableItemNome(QTable* table, EditType et, + LinkStatus const* linkstatus, int column_index) + : TableItem(table, et, linkstatus, column_index) +{ + setText(); +} + +void TableItemNome::setText() +{ + QString label(linkStatus()->label()); + if(!label.isNull()) + QTableItem::setText(label.simplifyWhiteSpace()); +} + +void TableItemNome::setPixmap() +{} + +QString TableItemNome::toolTip() const +{ + return text(); // Pode parecer repeticao mas nao eh... Ver construtor +} + +#include "tablelinkstatus.moc" diff --git a/klinkstatus/src/ui/tablelinkstatus.h b/klinkstatus/src/ui/tablelinkstatus.h new file mode 100644 index 00000000..0b3f2cf2 --- /dev/null +++ b/klinkstatus/src/ui/tablelinkstatus.h @@ -0,0 +1,202 @@ +/*************************************************************************** + * Copyright (C) 2004 by Paulo Moura Guedes * + * moura@kdewebdev.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. * + ***************************************************************************/ + +#ifndef TABLE_LINKSTATUS_H +#define TABLE_LINKSTATUS_H + +#include <qtable.h> +#include <qstring.h> +#include <qcolor.h> +#include <qpopupmenu.h> +#include <qvaluevector.h> +class QStringList; + +class KURL; + +#include <vector> + +#include "../engine/linkstatus.h" +#include "celltooltip.h" +#include "resultview.h" + +using namespace std; + + +int const STATUS_COLUMN_WIDTH = 50; + +class TableItem; + +class TableLinkstatus: public QTable, public ResultView +{ + Q_OBJECT +public: + + TableLinkstatus(QWidget * parent = 0, const char * name = 0, + int column_index_status = 1, + int column_index_label = 2, + int column_index_URL = 3); + ~TableLinkstatus(); + + virtual void setColumns(QStringList const& columns); + + /* Insere uma nova entrada no fim da tabela */ + virtual void insertResult(LinkStatus const* linkstatus); + + + virtual void clear(); + void removeColunas(); + virtual void show(ResultView::Status const& status); + virtual void showAll(); + + + /* Specialization of QTable::ensureCellVisible */ + virtual void ensureCellVisible(int row, int col); + + virtual bool textFitsInCell(int row, int col) const; + virtual bool isEmpty() const; + + TableItem* myItem(int row, int col) const; + +private slots: + + virtual void slotPopupContextMenu(int row, int col, const QPoint& pos); + virtual void slotCopyUrlToClipboard() const; + virtual void slotCopyParentUrlToClipboard() const; + virtual void slotCopyCellTextToClipboard() const; + virtual void slotEditReferrersWithQuanta(); + virtual void slotEditReferrerWithQuanta(int id); + virtual void slotEditReferrerWithQuanta(KURL const& url); + virtual void slotViewUrlInBrowser(); + virtual void slotViewParentUrlInBrowser(); + virtual void loadContextTableMenu(QValueVector<KURL> const& referrers, bool is_root = false); + +private: + + vector<TableItem*> generateRowOfTableItems(LinkStatus const* linkstatus); + void insereLinha(vector<TableItem*> items); + +private: +/* + int col_status_; + int col_label_; + int col_url_; + CellToolTip* cell_tip_; + QPopupMenu context_table_menu_; + QPopupMenu* sub_menu_; +*/ +}; + + +class TableItem: public QTableItem, public ResultViewItem +{ +public: + + TableItem(QTable* table, EditType et, + LinkStatus const* linkstatus, + int column_index, int alignment = Qt::AlignLeft); + virtual ~TableItem(); + + virtual void setColumnIndex(int i); + virtual int columnIndex() const; + + void setAlignment(int aFlags); + virtual int alignment() const; + + virtual QString toolTip() const = 0; + //LinkStatus const* const linkStatus() const; + +protected: + + //QColor const& textStatusColor() const; + virtual void paint( QPainter *p, const QColorGroup &cg, + const QRect &cr, bool selected ); + virtual void setText() = 0; + virtual void setPixmap() = 0; + +private: + + //LinkStatus* ls_; + //int column_index_; + int alignment_; +}; + + +class TableItemURL: public TableItem +{ +public: + + TableItemURL(QTable* table, EditType et, + LinkStatus const* linkstatus, int column_index = 3); + //virtual ~TableItemURL(){}; + + virtual QString toolTip() const; + +protected: + + virtual void setText(); + virtual void setPixmap(); + virtual void paint( QPainter *p, const QColorGroup &cg, const QRect &cr, bool selected ); + QColor const& textStatusColor() const; +}; + + +class TableItemStatus: public TableItem +{ +public: + + TableItemStatus(QTable* table, EditType et, + LinkStatus const* linkstatus, int column_index = 1); + //virtual ~TableItemStatus(){}; + + virtual QString toolTip() const; + +protected: + + virtual void setText(); + virtual void setPixmap(); + virtual void paint( QPainter *p, const QColorGroup &cg, const QRect &cr, bool selected ); +}; + + +class TableItemNome: public TableItem +{ +public: + + TableItemNome(QTable* table, EditType et, + LinkStatus const* linkstatus, int column_index = 2); + //virtual ~TableItemNome(){}; + + virtual QString toolTip() const; + +protected: + + virtual void setText(); + virtual void setPixmap(); + //virtual void paint( QPainter *p, const QColorGroup &cg, const QRect &cr, bool selected ); +}; + + +inline void TableItem::paint( QPainter *p, const QColorGroup &cg, + const QRect &cr, bool selected ) +{ + QTableItem::paint(p, cg, cr, selected); +} + +#endif diff --git a/klinkstatus/src/ui/tabwidgetsession.cpp b/klinkstatus/src/ui/tabwidgetsession.cpp new file mode 100644 index 00000000..9d9033a7 --- /dev/null +++ b/klinkstatus/src/ui/tabwidgetsession.cpp @@ -0,0 +1,274 @@ +/*************************************************************************** + * Copyright (C) 2004 by Paulo Moura Guedes * + * moura@kdewebdev.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 "tabwidgetsession.h" +#include "sessionwidget.h" +#include "klsconfig.h" +#include "treeview.h" +#include "../engine/searchmanager.h" +#include "../actionmanager.h" + +#include <qtoolbutton.h> +#include <qcursor.h> +#include <qtooltip.h> +#include <qpushbutton.h> +#include <qpixmap.h> +#include <qiconset.h> +#include <qstringlist.h> + +#include <kapplication.h> +#include <kstandarddirs.h> +#include <klocale.h> +#include <kstringhandler.h> +#include <kcharsets.h> +#include <kmimetype.h> +#include <kaction.h> +#include <kiconloader.h> + + +TabWidgetSession::TabWidgetSession(QWidget* parent, const char* name, WFlags f) + : KTabWidget(parent, name, f) // tabs_ is initialized with size 17 +{ + setFocusPolicy(QTabWidget::NoFocus); + setMargin(0); + setTabReorderingEnabled(true); + setHoverCloseButton(true); + setHoverCloseButtonDelayed(true); + + tabs_.setAutoDelete(false); + + QToolButton* tabs_new = new QToolButton(this); + tabs_new->setAccel(QKeySequence("Ctrl+N")); + connect(tabs_new, SIGNAL(clicked()), this, SLOT(slotNewSession())); + tabs_new->setIconSet(SmallIconSet("tab_new_raised")); + tabs_new->adjustSize(); + QToolTip::add(tabs_new, i18n("Open new tab")); + setCornerWidget(tabs_new, TopLeft); + + tabs_close_ = new QToolButton(this); + tabs_close_->setAccel(QKeySequence("Ctrl+W")); + connect(tabs_close_, SIGNAL(clicked()), this, SLOT(closeSession())); + tabs_close_->setIconSet(SmallIconSet("tab_remove")); + tabs_close_->adjustSize(); + QToolTip::add(tabs_close_, i18n("Close the current tab")); + setCornerWidget(tabs_close_, TopRight); + + connect(this, SIGNAL(currentChanged(QWidget*)), this, SLOT(slotCurrentChanged(QWidget*))); +} + +TabWidgetSession::~TabWidgetSession() +{} + +SessionWidget* TabWidgetSession::currentSession() const +{ + return tabs_[currentPageIndex()]; +} + +bool TabWidgetSession::emptySessionsExist() const +{ + if(count() == 0) + return true; + + for(int i = 0; i != count(); ++i) + { + Q_ASSERT(tabs_[i]); + if(tabs_[i]->isEmpty() && !tabs_[i]->getSearchManager()->searching()) + return true; + } + return false; +} + +SessionWidget* TabWidgetSession::getEmptySession() const +{ + Q_ASSERT(emptySessionsExist()); + Q_ASSERT(count() != 0); + + for(uint i = 0; i != tabs_.count(); ++i) + { + if(tabs_[i]->isEmpty()) + return tabs_[i]; + } + return 0; +} + +// Remember to use count() and not size() +QIntDict<SessionWidget> const& TabWidgetSession::sessions() const +{ + return tabs_; +} + +SessionWidget* TabWidgetSession::newSession() +{ + // TODO: settings: number of connections, timeout + SessionWidget* session_widget = newSessionWidget(); + connect(session_widget, SIGNAL(signalUpdateTabLabel(const LinkStatus *, SessionWidget*)), + this, SLOT(updateTabLabel(const LinkStatus *, SessionWidget*))); + + insertTab(session_widget, i18n("Session") + i18n(QString::number(count() + 1).ascii())); + + tabs_.insert(count() - 1, session_widget); + Q_ASSERT(tabs_[count() - 1]); + setCurrentPage(count() - 1); + + return session_widget; +} + +SessionWidget* TabWidgetSession::newSession(KURL const& url) +{ + SessionWidget* sessionwidget = newSession(); + currentSession()->setUrl(url); + + return sessionwidget; +} + +void TabWidgetSession::closeSession() +{ + if(count() > 1) + removePage(currentPage()); + + tabs_close_->setEnabled(count() > 1); + ActionManager::getInstance()->action("close_tab")->setEnabled(count() > 1); +} + +SessionWidget* TabWidgetSession::newSessionWidget() +{ + SessionWidget* session_widget = new SessionWidget(KLSConfig::maxConnectionsNumber(), + KLSConfig::timeOut(), this, QString("session_widget-" + count())); + + QStringList columns; + + columns.push_back(TreeView::URL_LABEL); + columns.push_back(TreeView::STATUS_LABEL); + if(KLSConfig::showMarkupStatus()) + columns.push_back(TreeView::MARKUP_LABEL); + columns.push_back(TreeView::LINK_LABEL_LABEL); + + session_widget->setColumns(columns); + + session_widget->tree_view->restoreLayout(KLSConfig::self()->config(), "klinkstatus"); + + return session_widget; +} + +void TabWidgetSession::updateTabLabel(LinkStatus const* linkstatus, SessionWidget* page) +{ + QString label; + KURL url = linkstatus->absoluteUrl(); + + if(linkstatus->hasHtmlDocTitle()) + { + label = linkstatus->htmlDocTitle(); + label = KStringHandler::csqueeze(label, 30); + } + else + { + if(url.fileName(false).isEmpty()) + label = url.prettyURL(); + else + label = url.fileName(false); + + label = KStringHandler::lsqueeze(label, 30); + } + + changeTab(page, KCharsets::resolveEntities(label)); + setTabIconSet(page, QIconSet(KMimeType::pixmapForURL(url))); +} + +void TabWidgetSession::slotLoadSettings() +{ + for(uint i = 0; i != tabs_.count(); ++i) + { + if(tabs_[i]->isEmpty()) + { + SessionWidget* session_widget = tabs_[i]; + if(session_widget->isEmpty()) + session_widget->slotLoadSettings(true); + else + session_widget->slotLoadSettings(false); + } + } +} + +void TabWidgetSession::setUrl(KURL const& url) +{ + currentSession()->setUrl(url); +} + +void TabWidgetSession::slotCurrentChanged(QWidget* /*page*/) +{ + tabs_close_->setEnabled(count() > 1); + + SessionWidget* session_widget = currentSession(); + ActionManager::getInstance()->slotUpdateSessionWidgetActions(session_widget); +} + +void TabWidgetSession::slotHideSearchPanel() +{ + currentSession()->slotHideSearchPanel(); +} + +void TabWidgetSession::slotFollowLastLinkChecked() +{ + currentSession()->slotFollowLastLinkChecked(); +} + +void TabWidgetSession::slotResetSearchOptions() +{ + currentSession()->slotResetSearchOptions(); +} + +void TabWidgetSession::slotNewSession(KURL const& url) +{ + if(count() == 0 || !emptySessionsExist()) + { + SessionWidget* sessionwidget = newSession(url); + ActionManager::getInstance()->initSessionWidget(sessionwidget); + } + else + { + SessionWidget* sessionwidget = getEmptySession(); + sessionwidget->setUrl(url); + showPage(sessionwidget); + } + + ActionManager::getInstance()->action("close_tab")->setEnabled(count() > 1); +} + +void TabWidgetSession::slotStartSearch() +{ + currentSession()->slotStartSearch(); +} + +void TabWidgetSession::slotPauseSearch() +{ + currentSession()->slotPauseSearch(); +} + +void TabWidgetSession::slotStopSearch() +{ + currentSession()->slotStopSearch(); +} + +void TabWidgetSession::slotExportAsHTML() +{ + currentSession()->slotExportAsHTML(); +} + + +#include "tabwidgetsession.moc" diff --git a/klinkstatus/src/ui/tabwidgetsession.h b/klinkstatus/src/ui/tabwidgetsession.h new file mode 100644 index 00000000..616c8173 --- /dev/null +++ b/klinkstatus/src/ui/tabwidgetsession.h @@ -0,0 +1,85 @@ +/*************************************************************************** + * Copyright (C) 2004 by Paulo Moura Guedes * + * moura@kdewebdev.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. * + ***************************************************************************/ +#ifndef TABWIDGETSESSION_H +#define TABWIDGETSESSION_H + +#include <ktabwidget.h> +#include <kurl.h> + +#include <qintdict.h> +class QToolButton; + +class SessionWidget; +class LinkStatus; + + +/** +This class handles the creation and destruction of sessions, i.e, severals instances of searching tabs. + +@author Paulo Moura Guedes +*/ +class TabWidgetSession : public KTabWidget +{ + Q_OBJECT + +public: + TabWidgetSession(QWidget * parent = 0, const char * name = 0, WFlags f = 0); + ~TabWidgetSession(); + + /** Set the URL in the current session widget */ + void setUrl(KURL const& url); + + SessionWidget* currentSession() const; + bool emptySessionsExist() const; + /** Returns the first empty session it finds */ + SessionWidget* getEmptySession() const; + QIntDict<SessionWidget> const& sessions() const; + + +public slots: + void slotNewSession(KURL const& url = KURL()); + SessionWidget* newSession(); + SessionWidget* newSession(KURL const& url); + void closeSession(); + void updateTabLabel(LinkStatus const* linkstatus, SessionWidget*); + void slotLoadSettings(); + + void slotHideSearchPanel(); + void slotResetSearchOptions(); + void slotFollowLastLinkChecked(); + + void slotStartSearch(); + void slotPauseSearch(); + void slotStopSearch(); + + void slotExportAsHTML(); + +private slots: + void slotCurrentChanged(QWidget* page); + +private: + SessionWidget* newSessionWidget(); + +private: + QIntDict<SessionWidget> tabs_; + QToolButton* tabs_close_; +}; + +#endif diff --git a/klinkstatus/src/ui/treeview.cpp b/klinkstatus/src/ui/treeview.cpp new file mode 100644 index 00000000..7ad92d8e --- /dev/null +++ b/klinkstatus/src/ui/treeview.cpp @@ -0,0 +1,609 @@ +/*************************************************************************** + * Copyright (C) 2004 by Paulo Moura Guedes * + * moura@kdewebdev.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 <qvaluevector.h> +#include <qheader.h> +#include <qclipboard.h> + +#include "treeview.h" +#include "../global.h" +#include "../engine/linkstatus.h" +#include "../engine/linkfilter.h" +#include "../cfg/klsconfig.h" + + +TreeView::TreeView(QWidget *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(QListView::LastColumn); + + sub_menu_ = new QPopupMenu(this, "sub_menu_referrers"); + + connect(this, SIGNAL( rightButtonClicked ( QListViewItem *, const QPoint &, int )), + this, SLOT( slotPopupContextMenu( QListViewItem *, const QPoint &, int )) ); +} + + +TreeView::~TreeView() +{ + saveLayout(KLSConfig::self()->config(), "klinkstatus"); +} + +void TreeView::setColumns(QStringList const& columns) +{ + ResultView::setColumns(columns); + removeColunas(); + +// resetColumns is called automatically + for(uint i = 0; i != columns.size(); ++i) + { + addColumn(i18n(columns[i])); + setColumnWidthMode(i, QListView::Manual); + } + + setColumnAlignment(col_status_ - 1, Qt::AlignCenter); + if(KLSConfig::showMarkupStatus()) + setColumnAlignment(col_markup_ - 1, Qt::AlignCenter); +} + +void TreeView::resetColumns() +{ + setColumnWidth(col_url_ - 1, (int)(0.45 * width())); + + setResizeMode(QListView::LastColumn); // fit to the window + // resize again + setColumnWidthMode(col_label_ - 1, QListView::Manual); + setResizeMode(QListView::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) +{ + QListViewItemIterator it(static_cast<KListView*> (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) +{ + QListViewItemIterator 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() +{ + QListViewItemIterator it(this); + while(it.current()) + { + it.current()->setVisible(true); + //it.current()->setEnabled(true); + ++it; + } +} + +void TreeView::ensureRowVisible(const QListViewItem * i, bool tree_display) +{ + QScrollBar* 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(QResizeEvent *e) +{ + KListView::resizeEvent(e); + resetColumns(); + clipper()->repaint(); +} + +void TreeView::slotPopupContextMenu(QListViewItem* item, const QPoint& pos, int col) +{ + current_column_ = col; + + TreeViewItem* tree_item = myItem(item); + if(tree_item) + { + QValueVector<KURL> referrers = tree_item->linkStatus()->referrers(); + loadContextTableMenu(referrers, tree_item->linkStatus()->isRoot()); + context_table_menu_.popup(pos); + } +} + +void TreeView::slotCopyUrlToClipboard() const +{ + TreeViewItem* _item = myItem(currentItem()); + QString content(_item->linkStatus()->absoluteUrl().prettyURL()); + QClipboard* cb = kapp->clipboard(); + cb->setText(content); +} + +void TreeView::slotCopyParentUrlToClipboard() const +{ + TreeViewItem* _item = myItem(currentItem()); + QString content(_item->linkStatus()->parent()->absoluteUrl().prettyURL()); + QClipboard* cb = kapp->clipboard(); + cb->setText(content); +} + +void TreeView::slotCopyCellTextToClipboard() const +{ + TreeViewItem* _item = myItem(currentItem()); + QString cell_text(_item->text(current_column_)); + QClipboard* cb = kapp->clipboard(); + cb->setText(cell_text); +} + +void TreeView::slotEditReferrersWithQuanta() +{ + TreeViewItem* _item = myItem(currentItem()); + QValueVector<KURL> referrers = _item->linkStatus()->referrers(); + + if(Global::isQuantaAvailableViaDCOP()) + { + for(uint i = 0; i != referrers.size(); ++i) + slotEditReferrerWithQuanta(referrers[i]); + } + else + { + QStringList 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()); + QValueVector<KURL> referrers = _item->linkStatus()->referrers(); + Q_ASSERT(index >= 0 && (uint)index < referrers.size()); + + slotEditReferrerWithQuanta(referrers[index]); +} + +void TreeView::slotEditReferrerWithQuanta(KURL const& url) +{ + QString filePath = url.url(); + + if(Global::isQuantaAvailableViaDCOP()) + { + DCOPRef quanta(Global::quantaDCOPAppId(),"WindowManagerIf"); + bool success = quanta.send("openFile", filePath, 0, 0); + + if(!success) + { + QString message = i18n("<qt>File <b>%1</b> cannot be opened. Might be a DCOP problem.</qt>").arg(filePath); + KMessageBox::error(parentWidget(), message); + } + } + else + { + QStringList 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(QValueVector<KURL> const& referrers, bool is_root) +{ + context_table_menu_.clear(); + sub_menu_->clear(); + + if(!is_root) + { + sub_menu_->insertItem(i18n("All"), this, SLOT(slotEditReferrersWithQuanta())); + sub_menu_->insertSeparator(); + + for(uint i = 0; i != referrers.size(); ++i) + { + sub_menu_->insertItem(referrers[i].prettyURL()); + } + connect(sub_menu_, SIGNAL(activated(int)), this, 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, SLOT(slotViewUrlInBrowser())); + + context_table_menu_.insertItem(/*SmallIconSet("fileopen"), */i18n("Open Referrer URL"), + this, SLOT(slotViewParentUrlInBrowser())); + + context_table_menu_.insertSeparator(); + + context_table_menu_.insertItem(SmallIconSet("editcopy"), i18n("Copy URL"), + this, SLOT(slotCopyUrlToClipboard())); + + context_table_menu_.insertItem(/*SmallIconSet("editcopy"), */i18n("Copy Referrer URL"), + this, SLOT(slotCopyParentUrlToClipboard())); + + context_table_menu_.insertItem(/*SmallIconSet("editcopy"), */i18n("Copy Cell Text"), + this, SLOT(slotCopyCellTextToClipboard())); +} + +TreeViewItem* TreeView::myItem(QListViewItem* item) const +{ + TreeViewItem* _item = dynamic_cast<TreeViewItem*> (item); + Q_ASSERT(_item); + return _item; +} + + +/* ******************************* TreeViewItem ******************************* */ + +TreeViewItem::TreeViewItem(TreeView* parent, QListViewItem* after, + LinkStatus const* linkstatus) + : KListViewItem(parent, after), + last_child_(0), root_(parent) +{ + init(linkstatus); +} + +TreeViewItem::TreeViewItem(TreeView* root, QListViewItem* listview_item, QListViewItem* 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(QListViewItem* last_child) +{ + Q_ASSERT(last_child); + last_child_ = last_child; +} + +QListViewItem* TreeViewItem::lastChild() const +{ + return last_child_; +} + +QString 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(QPainter * p, const QColorGroup & cg, int column, int width, int align) +{ + TreeColumnViewItem item = column_items_[column]; + + // Get a color to draw the text + QColorGroup m_cg(cg); + QColor color(item.textStatusColor()); + m_cg.setColor(QColorGroup::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_; +} + +QColor const& TreeColumnViewItem::textStatusColor() const +{ + if(columnIndex() == root_->urlColumnIndex() || columnIndex() == root_->statusColumnIndex()) + { + if(linkStatus()->status() == LinkStatus::BROKEN) + return Qt::red; + else if(linkStatus()->status() == LinkStatus::HTTP_CLIENT_ERROR) + return Qt::red; + else if(linkStatus()->status() == LinkStatus::HTTP_REDIRECTION) + return Qt::black; + else if(linkStatus()->status() == LinkStatus::HTTP_SERVER_ERROR) + return Qt::darkMagenta; + else if(linkStatus()->status() == LinkStatus::MALFORMED) + return Qt::red; + else if(linkStatus()->status() == LinkStatus::NOT_SUPPORTED) + return Qt::lightGray; + else if(linkStatus()->status() == LinkStatus::SUCCESSFULL) + return Qt::black; + else if(linkStatus()->status() == LinkStatus::TIMEOUT) + return Qt::darkMagenta; + else if(linkStatus()->status() == LinkStatus::UNDETERMINED) + return Qt::blue; + + return Qt::red; + } + else + return Qt::black; +} + + +QString 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 QString(); + } + else if(column == root_->labelColumnIndex()) + { + QString label(linkStatus()->label()); + if(!label.isNull()) + return label.simplifyWhiteSpace(); + } + + return QString(); +} + +QPixmap 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 QPixmap(); +} + + +#include "treeview.moc" diff --git a/klinkstatus/src/ui/treeview.h b/klinkstatus/src/ui/treeview.h new file mode 100644 index 00000000..eef34ff8 --- /dev/null +++ b/klinkstatus/src/ui/treeview.h @@ -0,0 +1,142 @@ +// +// C++ Interface: treeview +// +// Description: +// +// +// Author: Paulo Moura Guedes <moura@kdewebdev.org>, (C) 2004 +// +// Copyright: See COPYING file that comes with this distribution +// +// +#ifndef TREEVIEW_H +#define TREEVIEW_H + +#include <klistview.h> + +#include "resultview.h" +class TreeViewItem; +class TreeColumnViewItem; +class LinkMatcher; + +/** +@author Paulo Moura Guedes +TreeView and TreeViewItem and currently a little messes up in its API +because of ResultView. ResultView class was to be the base interface to +a QTable and a QListView, but the APIs are a little diferent... then I realize +that a QTable view isn't needed at all so some day I will clean this up. +*/ +class TreeView : public KListView, public ResultView +{ + Q_OBJECT +public: + + TreeView(QWidget *parent = 0, const char *name = 0); + ~TreeView(); + + virtual void setColumns(QStringList const& columns); + virtual void clear(); + void removeColunas(); + virtual void show(ResultView::Status const& status); + void show(LinkMatcher link_matcher); + virtual void showAll(); + + void setTreeDisplay(bool tree_display); + + /** + If tree_display is false the view scrolls to follow the last link inserted, + except if the user scrolls the view up (like Konsole). + If tree_view, it follows always the last link inserted. + */ + void ensureRowVisible(const QListViewItem * i, bool tree_display); + virtual bool isEmpty() const; + + TreeViewItem* myItem(QListViewItem* item) const; + +protected: + virtual void resizeEvent(QResizeEvent *e); + +private slots: + + void slotPopupContextMenu(QListViewItem *, const QPoint &, int); + virtual void slotCopyUrlToClipboard() const; + virtual void slotCopyParentUrlToClipboard() const; + virtual void slotCopyCellTextToClipboard() const; + virtual void slotEditReferrersWithQuanta(); + virtual void slotEditReferrerWithQuanta(int id); + virtual void slotEditReferrerWithQuanta(KURL const& url); + virtual void slotViewUrlInBrowser(); + virtual void slotViewParentUrlInBrowser(); + virtual void loadContextTableMenu(QValueVector<KURL> const& referrers, bool is_root = false); + +private: + void resetColumns(); + double columnsWidth() const; + +private: + int current_column_; // apparently it's impossible to know what is the current column + bool tree_display_; +}; + +inline void TreeView::setTreeDisplay(bool tree_display) { + tree_display_ = tree_display; + setRootIsDecorated(tree_display_); +} + + +/* ******************************* TreeViewItem ******************************* */ + +class TreeViewItem: public KListViewItem +{ +public: + + TreeViewItem(TreeView* parent, QListViewItem* after, + LinkStatus const* linkstatus); + TreeViewItem(TreeView* root, QListViewItem* parent_item, QListViewItem* after, + LinkStatus const* linkstatus); + virtual ~TreeViewItem(); + + void setLastChild(QListViewItem* last_child); + QListViewItem* lastChild() const; + + QString key(int column, bool) const; + LinkStatus const* linkStatus() const; + +protected: + virtual void paintCell(QPainter * p, const QColorGroup & cg, int column, int width, int align); + +private: + void init(LinkStatus const* linkstatus); + +private: + QValueVector<TreeColumnViewItem> column_items_; + QListViewItem* last_child_; + TreeView* root_; +}; + + +/* ******************************* TreeColumnViewItem ******************************* */ + +class TreeColumnViewItem +{ +public: + TreeColumnViewItem() + {} + ; + TreeColumnViewItem(TreeView* root, LinkStatus const* linkstatus, int column_index); + ~TreeColumnViewItem(); + + //void setColumnIndex(int i); + int columnIndex() const; + LinkStatus const* linkStatus() const; + QColor const& textStatusColor() const; + QString text(int column) const; + QPixmap pixmap(int column) const; + +private: + TreeView* root_; + LinkStatus const* ls_; + int column_index_; +}; + +#endif |