/*************************************************************************** * Copyright (C) 2004 by Paulo Moura Guedes * * moura@tdewebdev.org * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #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, TQWidget* 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, TQT_SIGNAL( textChanged ( const TQString & ) ), this, TQT_SLOT( slotEnableCheckButton( const TQString & ) ) ); connect(tree_view, TQT_SIGNAL( clicked ( TQListViewItem * ) ), this, TQT_SLOT( showBottomStatusLabel( TQListViewItem * ) ) ); connect(&bottom_status_timer_, TQT_SIGNAL(timeout()), this, TQT_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)); TQPixmap pixMap = KGlobal::iconLoader()->loadIcon("fileopen", KIcon::Small); pushbutton_url->setFixedSize(pixMap.width() + 8, pixMap.height() + 8); connect(pushbutton_url, TQT_SIGNAL(clicked()), this, TQT_SLOT(slotChooseUrlDialog())); resultsSearchBar->hide(); start_search_action_ = static_cast (action_manager_->action("start_search")); connect(resultsSearchBar, TQT_SIGNAL(signalSearch(LinkMatcher)), this, TQT_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(), TQT_TQOBJECT(this), "search_manager"); Q_ASSERT(search_manager_); connect(search_manager_, TQT_SIGNAL(signalRootChecked(const LinkStatus *, LinkChecker *)), this, TQT_SLOT(slotRootChecked(const LinkStatus *, LinkChecker *))); connect(search_manager_, TQT_SIGNAL(signalLinkChecked(const LinkStatus *, LinkChecker *)), this, TQT_SLOT(slotLinkChecked(const LinkStatus *, LinkChecker *))); connect(search_manager_, TQT_SIGNAL(signalSearchFinished()), this, TQT_SLOT(slotSearchFinished())); connect(search_manager_, TQT_SIGNAL(signalSearchPaused()), this, TQT_SLOT(slotSearchPaused())); connect(search_manager_, TQT_SIGNAL(signalAddingLevelTotalSteps(uint)), this, TQT_SLOT(slotAddingLevelTotalSteps(uint))); connect(search_manager_, TQT_SIGNAL(signalAddingLevelProgress()), this, TQT_SLOT(slotAddingLevelProgress())); connect(search_manager_, TQT_SIGNAL(signalLinksToCheckTotalSteps(uint)), this, TQT_SLOT(slotLinksToCheckTotalSteps(uint))); } void SessionWidget::setColumns(TQStringList 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 TQString & 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")) { TQString 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 ( TQKeyEvent* e ) { if( e->key() == TQt::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() == TQt::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); 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); 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(TQString const& url) { combobox_url->addToHistory(url); } void SessionWidget::showBottomStatusLabel(TQListViewItem* item) { kdDebug(23100) << "SessionWidget::showBottomStatusLabel" << endl; if(!item) return; TreeViewItem* _item = tree_view->myItem(item); if(_item) { TQString status = _item->linkStatus()->statusText(); textlabel_status->setText(status); if(textlabel_status->sizeHint().width() > textlabel_status->maximumWidth()) TQToolTip::add(textlabel_status, status); else TQToolTip::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(TQString(),"text/html", 0, i18n("Export Results as HTML")); if(url.isEmpty()) return; TQString 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 { TQTextStream *outputStream = savefile->textStream(); outputStream->setEncoding(TQTextStream::UnicodeUTF8); TQString xslt_doc = FileManager::read(locate("appdata", "styles/results_stylesheet.xsl")); XSLT xslt(xslt_doc); // kdDebug(23100) << search_manager_->toXML() << endl; TQString 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"