00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "actionmanagerimpl.h"
00028 #include "akregator_part.h"
00029 #include "akregator_run.h"
00030 #include "akregator_view.h"
00031 #include "listtabwidget.h"
00032 #include "addfeeddialog.h"
00033 #include "propertiesdialog.h"
00034 #include "frame.h"
00035 #include "fetchqueue.h"
00036 #include "feedlistview.h"
00037 #include "articlelistview.h"
00038 #include "articleviewer.h"
00039 #include "viewer.h"
00040 #include "feed.h"
00041 #include "tagfolder.h"
00042 #include "folder.h"
00043 #include "feedlist.h"
00044 #include "akregatorconfig.h"
00045 #include "kernel.h"
00046 #include "pageviewer.h"
00047 #include "searchbar.h"
00048 #include "speechclient.h"
00049 #include "storage.h"
00050 #include "tabwidget.h"
00051 #include "tag.h"
00052 #include "tagset.h"
00053 #include "tagnode.h"
00054 #include "tagnodelist.h"
00055 #include "tagpropertiesdialog.h"
00056 #include "treenode.h"
00057 #include "progressmanager.h"
00058 #include "treenodevisitor.h"
00059 #include "notificationmanager.h"
00060
00061 #include <kaction.h>
00062 #include <kapplication.h>
00063 #include <kcharsets.h>
00064 #include <kcombobox.h>
00065 #include <kconfig.h>
00066 #include <kdebug.h>
00067 #include <kdialog.h>
00068 #include <kfiledialog.h>
00069 #include <kfileitem.h>
00070 #include <khtml_part.h>
00071 #include <khtmlview.h>
00072 #include <kiconloader.h>
00073 #include <kinputdialog.h>
00074 #include <klineedit.h>
00075 #include <klistview.h>
00076 #include <klocale.h>
00077 #include <kmessagebox.h>
00078 #include <kpassdlg.h>
00079 #include <kprocess.h>
00080 #include <krun.h>
00081 #include <kshell.h>
00082 #include <kstandarddirs.h>
00083 #include <kurl.h>
00084 #include <kxmlguifactory.h>
00085 #include <kparts/partmanager.h>
00086
00087 #include <qbuttongroup.h>
00088 #include <qcheckbox.h>
00089 #include <qdatetime.h>
00090 #include <qfile.h>
00091 #include <qhbox.h>
00092 #include <qlabel.h>
00093 #include <qlayout.h>
00094 #include <qmultilineedit.h>
00095 #include <qpopupmenu.h>
00096 #include <qptrlist.h>
00097 #include <qstylesheet.h>
00098 #include <qtextstream.h>
00099 #include <qtimer.h>
00100 #include <qtoolbutton.h>
00101 #include <qtooltip.h>
00102 #include <qvaluevector.h>
00103 #include <qwhatsthis.h>
00104 #include <qclipboard.h>
00105
00106 namespace Akregator {
00107
00108 class View::EditNodePropertiesVisitor : public TreeNodeVisitor
00109 {
00110 public:
00111 EditNodePropertiesVisitor(View* view) : m_view(view) {}
00112
00113 virtual bool visitTagNode(TagNode* node)
00114 {
00115 TagPropertiesDialog* dlg = new TagPropertiesDialog(m_view);
00116 dlg->setTag(node->tag());
00117 dlg->exec();
00118 delete dlg;
00119 return true;
00120 }
00121
00122 virtual bool visitFolder(Folder* node)
00123 {
00124 m_view->m_listTabWidget->activeView()->startNodeRenaming(node);
00125 return true;
00126 }
00127
00128 virtual bool visitFeed(Feed* node)
00129 {
00130 FeedPropertiesDialog *dlg = new FeedPropertiesDialog( m_view, "edit_feed" );
00131 dlg->setFeed(node);
00132 dlg->exec();
00133 delete dlg;
00134 return true;
00135 }
00136 private:
00137
00138 View* m_view;
00139 };
00140
00141 class View::DeleteNodeVisitor : public TreeNodeVisitor
00142 {
00143 public:
00144 DeleteNodeVisitor(View* view) : m_view(view) {}
00145
00146 virtual bool visitTagNode(TagNode* node)
00147 {
00148 QString msg = i18n("<qt>Are you sure you want to delete tag <b>%1</b>? The tag will be removed from all articles.</qt>").arg(node->title());
00149 if (KMessageBox::warningContinueCancel(0, msg, i18n("Delete Tag"), KStdGuiItem::del()) == KMessageBox::Continue)
00150 {
00151 Tag tag = node->tag();
00152 QValueList<Article> articles = m_view->m_feedList->rootNode()->articles(tag.id());
00153 node->setNotificationMode(false);
00154 for (QValueList<Article>::Iterator it = articles.begin(); it != articles.end(); ++it)
00155 (*it).removeTag(tag.id());
00156 node->setNotificationMode(true);
00157 Kernel::self()->tagSet()->remove(tag);
00158 m_view->m_listTabWidget->activeView()->setFocus();
00159 }
00160 return true;
00161 }
00162
00163 virtual bool visitFolder(Folder* node)
00164 {
00165 QString msg;
00166 if (node->title().isEmpty())
00167 msg = i18n("<qt>Are you sure you want to delete this folder and its feeds and subfolders?</qt>");
00168 else
00169 msg = i18n("<qt>Are you sure you want to delete folder <b>%1</b> and its feeds and subfolders?</qt>").arg(node->title());
00170
00171 if (KMessageBox::warningContinueCancel(0, msg, i18n("Delete Folder"), KStdGuiItem::del()) == KMessageBox::Continue)
00172 {
00173 delete node;
00174 m_view->m_listTabWidget->activeView()->setFocus();
00175 }
00176 return true;
00177 }
00178
00179 virtual bool visitFeed(Feed* node)
00180 {
00181 QString msg;
00182 if (node->title().isEmpty())
00183 msg = i18n("<qt>Are you sure you want to delete this feed?</qt>");
00184 else
00185 msg = i18n("<qt>Are you sure you want to delete feed <b>%1</b>?</qt>").arg(node->title());
00186
00187 if (KMessageBox::warningContinueCancel(0, msg, i18n("Delete Feed"), KStdGuiItem::del()) == KMessageBox::Continue)
00188 {
00189 delete node;
00190 m_view->m_listTabWidget->activeView()->setFocus();
00191 }
00192 return true;
00193 }
00194 private:
00195
00196 View* m_view;
00197 };
00198
00199
00200 View::~View()
00201 {
00202
00203
00204
00205 if (!m_shuttingDown)
00206 {
00207 kdDebug() << "View::~View(): slotOnShutdown() wasn't called. Calling it now." << endl;
00208 slotOnShutdown();
00209 }
00210 kdDebug() << "View::~View(): leaving" << endl;
00211 }
00212
00213 View::View( Part *part, QWidget *parent, ActionManagerImpl* actionManager, const char *name)
00214 : QWidget(parent, name), m_viewMode(NormalView), m_actionManager(actionManager)
00215 {
00216 m_editNodePropertiesVisitor = new EditNodePropertiesVisitor(this);
00217 m_deleteNodeVisitor = new DeleteNodeVisitor(this);
00218 m_keepFlagIcon = QPixmap(locate("data", "akregator/pics/akregator_flag.png"));
00219 m_part = part;
00220 m_feedList = new FeedList();
00221 m_tagNodeList = new TagNodeList(m_feedList, Kernel::self()->tagSet());
00222 m_shuttingDown = false;
00223 m_displayingAboutPage = false;
00224 m_currentFrame = 0L;
00225 setFocusPolicy(QWidget::StrongFocus);
00226
00227 QVBoxLayout *lt = new QVBoxLayout( this );
00228
00229 m_horizontalSplitter = new QSplitter(QSplitter::Horizontal, this);
00230
00231 m_horizontalSplitter->setOpaqueResize(true);
00232 lt->addWidget(m_horizontalSplitter);
00233
00234 connect (Kernel::self()->fetchQueue(), SIGNAL(fetched(Feed*)), this, SLOT(slotFeedFetched(Feed*)));
00235 connect (Kernel::self()->fetchQueue(), SIGNAL(signalStarted()), this, SLOT(slotFetchingStarted()));
00236 connect (Kernel::self()->fetchQueue(), SIGNAL(signalStopped()), this, SLOT(slotFetchingStopped()));
00237
00238 connect(Kernel::self()->tagSet(), SIGNAL(signalTagAdded(const Tag&)), this, SLOT(slotTagCreated(const Tag&)));
00239 connect(Kernel::self()->tagSet(), SIGNAL(signalTagRemoved(const Tag&)), this, SLOT(slotTagRemoved(const Tag&)));
00240
00241 m_listTabWidget = new ListTabWidget(m_horizontalSplitter);
00242 m_actionManager->initListTabWidget(m_listTabWidget);
00243
00244 connect(m_listTabWidget, SIGNAL(signalNodeSelected(TreeNode*)), this, SLOT(slotNodeSelected(TreeNode*)));
00245
00246 if (!Settings::showTaggingGUI())
00247 m_listTabWidget->setViewMode(ListTabWidget::single);
00248
00249 m_feedListView = new NodeListView( this, "feedtree" );
00250 m_listTabWidget->addView(m_feedListView, i18n("Feeds"), KGlobal::iconLoader()->loadIcon("folder", KIcon::Small));
00251
00252 connect(m_feedListView, SIGNAL(signalContextMenu(KListView*, TreeNode*, const QPoint&)), this, SLOT(slotFeedTreeContextMenu(KListView*, TreeNode*, const QPoint&)));
00253
00254 connect(m_feedListView, SIGNAL(signalDropped (KURL::List &, TreeNode*,
00255 Folder*)), this, SLOT(slotFeedURLDropped (KURL::List &,
00256 TreeNode*, Folder*)));
00257
00258 m_tagNodeListView = new NodeListView(this);
00259 m_listTabWidget->addView(m_tagNodeListView, i18n("Tags"), KGlobal::iconLoader()->loadIcon("rss_tag", KIcon::Small));
00260
00261 connect(m_tagNodeListView, SIGNAL(signalContextMenu(KListView*, TreeNode*, const QPoint&)), this, SLOT(slotFeedTreeContextMenu(KListView*, TreeNode*, const QPoint&)));
00262
00263
00264 ProgressManager::self()->setFeedList(m_feedList);
00265
00266 m_tabs = new TabWidget(m_horizontalSplitter);
00267 m_actionManager->initTabWidget(m_tabs);
00268
00269 connect( m_part, SIGNAL(signalSettingsChanged()), m_tabs, SLOT(slotSettingsChanged()));
00270
00271 connect( m_tabs, SIGNAL( currentFrameChanged(Frame *) ), this,
00272 SLOT( slotFrameChanged(Frame *) ) );
00273
00274 QWhatsThis::add(m_tabs, i18n("You can view multiple articles in several open tabs."));
00275
00276 m_mainTab = new QWidget(this, "Article Tab");
00277 QVBoxLayout *mainTabLayout = new QVBoxLayout( m_mainTab, 0, 2, "mainTabLayout");
00278
00279 QWhatsThis::add(m_mainTab, i18n("Articles list."));
00280
00281 m_searchBar = new SearchBar(m_mainTab);
00282
00283 if ( !Settings::showQuickFilter() )
00284 m_searchBar->hide();
00285
00286 mainTabLayout->addWidget(m_searchBar);
00287
00288 m_articleSplitter = new QSplitter(QSplitter::Vertical, m_mainTab, "panner2");
00289
00290 m_articleList = new ArticleListView( m_articleSplitter, "articles" );
00291 m_actionManager->initArticleListView(m_articleList);
00292
00293 connect( m_articleList, SIGNAL(signalMouseButtonPressed(int, const Article&, const QPoint &, int)), this, SLOT(slotMouseButtonPressed(int, const Article&, const QPoint &, int)));
00294
00295
00296 connect( m_articleList, SIGNAL(signalArticleChosen(const Article&)),
00297 this, SLOT( slotArticleSelected(const Article&)) );
00298 connect( m_articleList, SIGNAL(signalDoubleClicked(const Article&, const QPoint&, int)),
00299 this, SLOT( slotOpenArticleExternal(const Article&, const QPoint&, int)) );
00300
00301 m_articleViewer = new ArticleViewer(m_articleSplitter, "article_viewer");
00302 m_articleViewer->setSafeMode();
00303
00304 m_actionManager->initArticleViewer(m_articleViewer);
00305
00306 connect(m_searchBar, SIGNAL(signalSearch(const Akregator::Filters::ArticleMatcher&, const Akregator::Filters::ArticleMatcher&)), m_articleList, SLOT(slotSetFilter(const Akregator::Filters::ArticleMatcher&, const Akregator::Filters::ArticleMatcher&)));
00307
00308 connect(m_searchBar, SIGNAL(signalSearch(const Akregator::Filters::ArticleMatcher&, const Akregator::Filters::ArticleMatcher&)), m_articleViewer, SLOT(slotSetFilter(const Akregator::Filters::ArticleMatcher&, const Akregator::Filters::ArticleMatcher&)));
00309
00310 connect( m_articleViewer, SIGNAL(urlClicked(const KURL&, Viewer*, bool, bool)),
00311 this, SLOT(slotUrlClickedInViewer(const KURL&, Viewer*, bool, bool)) );
00312
00313 connect( m_articleViewer->browserExtension(), SIGNAL(mouseOverInfo(const KFileItem *)),
00314 this, SLOT(slotMouseOverInfo(const KFileItem *)) );
00315
00316 connect( m_part, SIGNAL(signalSettingsChanged()), m_articleViewer, SLOT(slotPaletteOrFontChanged()));
00317 QWhatsThis::add(m_articleViewer->widget(), i18n("Browsing area."));
00318 mainTabLayout->addWidget( m_articleSplitter );
00319
00320 m_mainFrame=new Frame(this, m_part, m_mainTab, i18n("Articles"), false);
00321 connectFrame(m_mainFrame);
00322 m_tabs->addFrame(m_mainFrame);
00323
00324 m_horizontalSplitter->setSizes( Settings::splitter1Sizes() );
00325 m_articleSplitter->setSizes( Settings::splitter2Sizes() );
00326
00327 KConfig *conf = Settings::self()->config();
00328 conf->setGroup("General");
00329 if(!conf->readBoolEntry("Disable Introduction", false))
00330 {
00331 m_articleList->hide();
00332 m_searchBar->hide();
00333 m_articleViewer->displayAboutPage();
00334 m_mainFrame->setTitle(i18n("About"));
00335 m_displayingAboutPage = true;
00336 }
00337
00338 m_fetchTimer = new QTimer(this);
00339 connect( m_fetchTimer, SIGNAL(timeout()), this, SLOT(slotDoIntervalFetches()) );
00340 m_fetchTimer->start(1000*60);
00341
00342
00343 m_expiryTimer = new QTimer(this);
00344 connect(m_expiryTimer, SIGNAL(timeout()), this,
00345 SLOT(slotDeleteExpiredArticles()) );
00346 m_expiryTimer->start(3600*1000);
00347
00348 m_markReadTimer = new QTimer(this);
00349 connect(m_markReadTimer, SIGNAL(timeout()), this, SLOT(slotSetCurrentArticleReadDelayed()) );
00350
00351 switch (Settings::viewMode())
00352 {
00353 case CombinedView:
00354 slotCombinedView();
00355 break;
00356 case WidescreenView:
00357 slotWidescreenView();
00358 break;
00359 default:
00360 slotNormalView();
00361 }
00362
00363 if (!Settings::resetQuickFilterOnNodeChange())
00364 {
00365 m_searchBar->slotSetStatus(Settings::statusFilter());
00366 m_searchBar->slotSetText(Settings::textFilter());
00367 }
00368
00369 QTimer::singleShot(1000, this, SLOT(slotDeleteExpiredArticles()) );
00370 m_part->mergePart(m_articleViewer);
00371 }
00372
00373 void View::slotSettingsChanged()
00374 {
00375
00376 m_listTabWidget->setViewMode(Settings::showTaggingGUI() ? ListTabWidget::verticalTabs : ListTabWidget::single);
00377
00378 }
00379
00380 void View::slotOnShutdown()
00381 {
00382 m_shuttingDown = true;
00383
00384 m_articleList->slotShowNode(0);
00385 m_articleViewer->slotShowNode(0);
00386
00387 Kernel::self()->fetchQueue()->slotAbort();
00388
00389 m_feedListView->setNodeList(0);
00390 ProgressManager::self()->setFeedList(0);
00391
00392 delete m_feedList;
00393 delete m_tagNodeList;
00394
00395
00396
00397 m_tabs->setCurrentPage(m_tabs->count()-1);
00398 while (m_tabs->count() > 1)
00399 m_tabs->slotRemoveCurrentFrame();
00400
00401 delete m_mainTab;
00402 delete m_mainFrame;
00403 delete m_editNodePropertiesVisitor;
00404 delete m_deleteNodeVisitor;
00405 }
00406
00407 void View::saveSettings()
00408 {
00409 Settings::setSplitter1Sizes( m_horizontalSplitter->sizes() );
00410 Settings::setSplitter2Sizes( m_articleSplitter->sizes() );
00411 Settings::setViewMode( m_viewMode );
00412 Settings::writeConfig();
00413 }
00414
00415 void View::slotOpenNewTab(const KURL& url, bool background)
00416 {
00417 PageViewer* page = new PageViewer(this, "page");
00418
00419 connect( m_part, SIGNAL(signalSettingsChanged()), page, SLOT(slotPaletteOrFontChanged()));
00420
00421 connect( page, SIGNAL(setTabIcon(const QPixmap&)),
00422 this, SLOT(setTabIcon(const QPixmap&)));
00423 connect( page, SIGNAL(urlClicked(const KURL &, Viewer*, bool, bool)),
00424 this, SLOT(slotUrlClickedInViewer(const KURL &, Viewer*, bool, bool)) );
00425
00426 Frame* frame = new Frame(this, page, page->widget(), i18n("Untitled"));
00427 frame->setAutoDeletePart(true);
00428
00429 connect(page, SIGNAL(setWindowCaption (const QString &)), frame, SLOT(setTitle (const QString &)));
00430 connectFrame(frame);
00431 m_tabs->addFrame(frame);
00432
00433 if(!background)
00434 m_tabs->showPage(page->widget());
00435 else
00436 setFocus();
00437
00438 page->openURL(url);
00439 }
00440
00441
00442 void View::setTabIcon(const QPixmap& icon)
00443 {
00444 const PageViewer *s = dynamic_cast<const PageViewer*>(sender());
00445 if (s) {
00446 m_tabs->setTabIconSet(const_cast<PageViewer*>(s)->widget(), icon);
00447 }
00448 }
00449
00450 void View::connectFrame(Frame *f)
00451 {
00452 connect(f, SIGNAL(statusText(const QString &)), this, SLOT(slotStatusText(const QString&)));
00453 connect(f, SIGNAL(captionChanged (const QString &)), this, SLOT(slotCaptionChanged (const QString &)));
00454 connect(f, SIGNAL(loadingProgress(int)), this, SLOT(slotLoadingProgress(int)) );
00455 connect(f, SIGNAL(started()), this, SLOT(slotStarted()));
00456 connect(f, SIGNAL(completed()), this, SLOT(slotCompleted()));
00457 connect(f, SIGNAL(canceled(const QString &)), this, SLOT(slotCanceled(const QString&)));
00458 }
00459
00460 void View::slotStatusText(const QString &c)
00461 {
00462 if (sender() == m_currentFrame)
00463 emit setStatusBarText(c);
00464 }
00465
00466 void View::slotCaptionChanged(const QString &c)
00467 {
00468 if (sender() == m_currentFrame)
00469 emit setWindowCaption(c);
00470 }
00471
00472 void View::slotStarted()
00473 {
00474 if (sender() == m_currentFrame)
00475 emit signalStarted(0);
00476 }
00477
00478 void View::slotCanceled(const QString &s)
00479 {
00480 if (sender() == m_currentFrame)
00481 emit signalCanceled(s);
00482 }
00483
00484 void View::slotCompleted()
00485 {
00486 if (sender() == m_currentFrame)
00487 emit signalCompleted();
00488 }
00489
00490 void View::slotLoadingProgress(int percent)
00491 {
00492 if (sender() == m_currentFrame)
00493 emit setProgress(percent);
00494 }
00495
00496 bool View::importFeeds(const QDomDocument& doc)
00497 {
00498 FeedList* feedList = new FeedList();
00499 bool parsed = feedList->readFromXML(doc);
00500
00501
00502 if (!parsed)
00503 {
00504 delete feedList;
00505 return false;
00506 }
00507 QString title = feedList->title();
00508
00509 if (title.isEmpty())
00510 title = i18n("Imported Folder");
00511
00512 bool ok;
00513 title = KInputDialog::getText(i18n("Add Imported Folder"), i18n("Imported folder name:"), title, &ok);
00514
00515 if (!ok)
00516 {
00517 delete feedList;
00518 return false;
00519 }
00520
00521 Folder* fg = new Folder(title);
00522 m_feedList->rootNode()->appendChild(fg);
00523 m_feedList->append(feedList, fg);
00524
00525 return true;
00526 }
00527
00528 bool View::loadFeeds(const QDomDocument& doc, Folder* parent)
00529 {
00530 FeedList* feedList = new FeedList();
00531 bool parsed = feedList->readFromXML(doc);
00532
00533
00534 if (!parsed)
00535 {
00536 delete feedList;
00537 return false;
00538 }
00539 m_feedListView->setUpdatesEnabled(false);
00540 m_tagNodeListView->setUpdatesEnabled(false);
00541 if (!parent)
00542 {
00543 TagSet* tagSet = Kernel::self()->tagSet();
00544
00545 Kernel::self()->setFeedList(feedList);
00546 ProgressManager::self()->setFeedList(feedList);
00547 disconnectFromFeedList(m_feedList);
00548 delete m_feedList;
00549 delete m_tagNodeList;
00550 m_feedList = feedList;
00551 connectToFeedList(m_feedList);
00552
00553 m_tagNodeList = new TagNodeList(m_feedList, tagSet);
00554 m_feedListView->setNodeList(m_feedList);
00555 m_tagNodeListView->setNodeList(m_tagNodeList);
00556
00557 QStringList tagIDs = m_feedList->rootNode()->tags();
00558 QStringList::ConstIterator end = tagIDs.end();
00559 for (QStringList::ConstIterator it = tagIDs.begin(); it != end; ++it)
00560 {
00561 kdDebug() << *it << endl;
00562
00563
00564
00565 if (!tagSet->containsID(*it))
00566 {
00567 Tag tag(*it, *it);
00568 tagSet->insert(tag);
00569 }
00570 }
00571 }
00572 else
00573 m_feedList->append(feedList, parent);
00574
00575 m_feedListView->setUpdatesEnabled(true);
00576 m_feedListView->triggerUpdate();
00577 m_tagNodeListView->setUpdatesEnabled(true);
00578 m_tagNodeListView->triggerUpdate();
00579 return true;
00580 }
00581
00582 void View::slotDeleteExpiredArticles()
00583 {
00584 TreeNode* rootNode = m_feedList->rootNode();
00585 if (rootNode)
00586 rootNode->slotDeleteExpiredArticles();
00587 }
00588
00589 QDomDocument View::feedListToOPML()
00590 {
00591 return m_feedList->toXML();
00592 }
00593
00594 void View::addFeedToGroup(const QString& url, const QString& groupName)
00595 {
00596
00597
00598 TreeNode* node = m_feedListView->findNodeByTitle(groupName);
00599
00600 Folder* group = 0;
00601 if (!node || !node->isGroup())
00602 {
00603 Folder* g = new Folder( groupName );
00604 m_feedList->rootNode()->appendChild(g);
00605 group = g;
00606 }
00607 else
00608 group = static_cast<Folder*>(node);
00609
00610
00611 if (group)
00612 addFeed(url, 0, group, true);
00613 }
00614
00615 void View::slotNormalView()
00616 {
00617 if (m_viewMode == NormalView)
00618 return;
00619
00620 if (m_viewMode == CombinedView)
00621 {
00622 m_articleList->slotShowNode(m_listTabWidget->activeView()->selectedNode());
00623 m_articleList->show();
00624
00625 Article article = m_articleList->currentArticle();
00626
00627 if (!article.isNull())
00628 m_articleViewer->slotShowArticle(article);
00629 else
00630 m_articleViewer->slotShowSummary(m_listTabWidget->activeView()->selectedNode());
00631 }
00632
00633 m_articleSplitter->setOrientation(QSplitter::Vertical);
00634 m_viewMode = NormalView;
00635
00636 Settings::setViewMode( m_viewMode );
00637 }
00638
00639 void View::slotWidescreenView()
00640 {
00641 if (m_viewMode == WidescreenView)
00642 return;
00643
00644 if (m_viewMode == CombinedView)
00645 {
00646 m_articleList->slotShowNode(m_listTabWidget->activeView()->selectedNode());
00647 m_articleList->show();
00648
00649 Article article = m_articleList->currentArticle();
00650
00651 if (!article.isNull())
00652 m_articleViewer->slotShowArticle(article);
00653 else
00654 m_articleViewer->slotShowSummary(m_listTabWidget->activeView()->selectedNode());
00655 }
00656
00657 m_articleSplitter->setOrientation(QSplitter::Horizontal);
00658 m_viewMode = WidescreenView;
00659
00660 Settings::setViewMode( m_viewMode );
00661 }
00662
00663 void View::slotCombinedView()
00664 {
00665 if (m_viewMode == CombinedView)
00666 return;
00667
00668 m_articleList->slotClear();
00669 m_articleList->hide();
00670 m_viewMode = CombinedView;
00671
00672 slotNodeSelected(m_listTabWidget->activeView()->selectedNode());
00673 Settings::setViewMode( m_viewMode );
00674 }
00675
00676 void View::slotFrameChanged(Frame *f)
00677 {
00678 if (m_shuttingDown)
00679 return;
00680
00681 m_currentFrame=f;
00682
00683 emit setWindowCaption(f->caption());
00684 emit setProgress(f->progress());
00685 emit setStatusBarText(f->statusText());
00686
00687 if (f->part() == m_part)
00688 m_part->mergePart(m_articleViewer);
00689 else
00690 m_part->mergePart(f->part());
00691
00692 f->widget()->setFocus();
00693
00694 switch (f->state())
00695 {
00696 case Frame::Started:
00697 emit signalStarted(0);
00698 break;
00699 case Frame::Canceled:
00700 emit signalCanceled(QString::null);
00701 break;
00702 case Frame::Idle:
00703 case Frame::Completed:
00704 default:
00705 emit signalCompleted();
00706 }
00707 }
00708
00709 void View::slotFeedTreeContextMenu(KListView*, TreeNode* , const QPoint& )
00710 {
00711 m_tabs->showPage(m_mainTab);
00712 }
00713
00714 void View::slotMoveCurrentNodeUp()
00715 {
00716 TreeNode* current = m_listTabWidget->activeView()->selectedNode();
00717 if (!current)
00718 return;
00719 TreeNode* prev = current->prevSibling();
00720 Folder* parent = current->parent();
00721
00722 if (!prev || !parent)
00723 return;
00724
00725 parent->removeChild(prev);
00726 parent->insertChild(prev, current);
00727 m_listTabWidget->activeView()->ensureNodeVisible(current);
00728 }
00729
00730 void View::slotMoveCurrentNodeDown()
00731 {
00732 TreeNode* current = m_listTabWidget->activeView()->selectedNode();
00733 if (!current)
00734 return;
00735 TreeNode* next = current->nextSibling();
00736 Folder* parent = current->parent();
00737
00738 if (!next || !parent)
00739 return;
00740
00741 parent->removeChild(current);
00742 parent->insertChild(current, next);
00743 m_listTabWidget->activeView()->ensureNodeVisible(current);
00744 }
00745
00746 void View::slotMoveCurrentNodeLeft()
00747 {
00748 TreeNode* current = m_listTabWidget->activeView()->selectedNode();
00749 if (!current || !current->parent() || !current->parent()->parent())
00750 return;
00751
00752 Folder* parent = current->parent();
00753 Folder* grandparent = current->parent()->parent();
00754
00755 parent->removeChild(current);
00756 grandparent->insertChild(current, parent);
00757 m_listTabWidget->activeView()->ensureNodeVisible(current);
00758 }
00759
00760 void View::slotMoveCurrentNodeRight()
00761 {
00762 TreeNode* current = m_listTabWidget->activeView()->selectedNode();
00763 if (!current || !current->parent())
00764 return;
00765 TreeNode* prev = current->prevSibling();
00766
00767 if ( prev && prev->isGroup() )
00768 {
00769 Folder* fg = static_cast<Folder*>(prev);
00770 current->parent()->removeChild(current);
00771 fg->appendChild(current);
00772 m_listTabWidget->activeView()->ensureNodeVisible(current);
00773 }
00774 }
00775
00776 void View::slotNodeSelected(TreeNode* node)
00777 {
00778 m_markReadTimer->stop();
00779
00780 if (node)
00781 {
00782 kdDebug() << "node selected: " << node->title() << endl;
00783 kdDebug() << "unread: " << node->unread() << endl;
00784 kdDebug() << "total: " << node->totalCount() << endl;
00785 }
00786
00787 if (m_displayingAboutPage)
00788 {
00789 m_mainFrame->setTitle(i18n("Articles"));
00790 if (m_viewMode != CombinedView)
00791 m_articleList->show();
00792 if (Settings::showQuickFilter())
00793 m_searchBar->show();
00794 m_displayingAboutPage = false;
00795 }
00796
00797 m_tabs->showPage(m_mainTab);
00798
00799 if (Settings::resetQuickFilterOnNodeChange())
00800 m_searchBar->slotClearSearch();
00801
00802 if (m_viewMode == CombinedView)
00803 m_articleViewer->slotShowNode(node);
00804 else
00805 {
00806 m_articleList->slotShowNode(node);
00807 m_articleViewer->slotShowSummary(node);
00808 }
00809
00810 if (node)
00811 m_mainFrame->setCaption(node->title());
00812
00813 m_actionManager->slotNodeSelected(node);
00814
00815 updateTagActions();
00816 }
00817
00818 void View::slotOpenURL(const KURL& url, Viewer* currentViewer, BrowserRun::OpeningMode mode)
00819 {
00820 if (mode == BrowserRun::EXTERNAL)
00821 Viewer::displayInExternalBrowser(url);
00822 else
00823 {
00824 KParts::URLArgs args = currentViewer ? currentViewer->browserExtension()->urlArgs() : KParts::URLArgs();
00825
00826 BrowserRun* r = new BrowserRun(this, currentViewer, url, args, mode);
00827 connect(r, SIGNAL(signalOpenInViewer(const KURL&, Akregator::Viewer*, Akregator::BrowserRun::OpeningMode)),
00828 this, SLOT(slotOpenURLReply(const KURL&, Akregator::Viewer*, Akregator::BrowserRun::OpeningMode)));
00829 }
00830 }
00831
00832
00833 void View::slotUrlClickedInViewer(const KURL& url, Viewer* viewer, bool newTab, bool background)
00834 {
00835
00836 if (!newTab)
00837 {
00838 slotOpenURL(url, viewer, BrowserRun::CURRENT_TAB);
00839 }
00840 else
00841 {
00842 slotOpenURL(url, 0L, background ? BrowserRun::NEW_TAB_BACKGROUND : BrowserRun::NEW_TAB_FOREGROUND);
00843 }
00844 }
00845
00846
00847 void View::slotOpenURLReply(const KURL& url, Viewer* currentViewer, BrowserRun::OpeningMode mode)
00848 {
00849 switch (mode)
00850 {
00851 case BrowserRun::CURRENT_TAB:
00852 currentViewer->openURL(url);
00853 break;
00854 case BrowserRun::NEW_TAB_FOREGROUND:
00855 case BrowserRun::NEW_TAB_BACKGROUND:
00856 slotOpenNewTab(url, mode == BrowserRun::NEW_TAB_BACKGROUND);
00857 break;
00858 case BrowserRun::EXTERNAL:
00859 Viewer::displayInExternalBrowser(url);
00860 break;
00861 }
00862 }
00863
00864 void View::slotFeedAdd()
00865 {
00866 Folder* group = 0;
00867 if (!m_feedListView->selectedNode())
00868 group = m_feedList->rootNode();
00869 else
00870 {
00871
00872 if ( m_feedListView->selectedNode()->isGroup())
00873 group = static_cast<Folder*>(m_feedListView->selectedNode());
00874 else
00875 group= m_feedListView->selectedNode()->parent();
00876
00877 }
00878
00879 TreeNode* lastChild = group->children().last();
00880
00881 addFeed(QString::null, lastChild, group, false);
00882 }
00883
00884 void View::addFeed(const QString& url, TreeNode *after, Folder* parent, bool autoExec)
00885 {
00886
00887 AddFeedDialog *afd = new AddFeedDialog( 0, "add_feed" );
00888
00889 afd->setURL(KURL::decode_string(url));
00890
00891 if (autoExec)
00892 afd->slotOk();
00893 else
00894 {
00895 if (afd->exec() != QDialog::Accepted)
00896 {
00897 delete afd;
00898 return;
00899 }
00900 }
00901
00902 Feed* feed = afd->feed;
00903 delete afd;
00904
00905 FeedPropertiesDialog *dlg = new FeedPropertiesDialog( 0, "edit_feed" );
00906 dlg->setFeed(feed);
00907
00908 dlg->selectFeedName();
00909
00910 if (!autoExec)
00911 if (dlg->exec() != QDialog::Accepted)
00912 {
00913 delete feed;
00914 delete dlg;
00915 return;
00916 }
00917
00918 if (!parent)
00919 parent = m_feedList->rootNode();
00920
00921 parent->insertChild(feed, after);
00922
00923 m_feedListView->ensureNodeVisible(feed);
00924
00925
00926 delete dlg;
00927 }
00928
00929 void View::slotFeedAddGroup()
00930 {
00931 TreeNode* node = m_feedListView->selectedNode();
00932 TreeNode* after = 0;
00933
00934 if (!node)
00935 node = m_feedListView->rootNode();
00936
00937
00938
00939 if (!node->isGroup())
00940 {
00941 after = node;
00942 node = node->parent();
00943 }
00944
00945 Folder* currentGroup = static_cast<Folder*> (node);
00946
00947 bool Ok;
00948
00949 QString text = KInputDialog::getText(i18n("Add Folder"), i18n("Folder name:"), "", &Ok);
00950
00951 if (Ok)
00952 {
00953 Folder* newGroup = new Folder(text);
00954 if (!after)
00955 currentGroup->appendChild(newGroup);
00956 else
00957 currentGroup->insertChild(newGroup, after);
00958
00959 m_feedListView->ensureNodeVisible(newGroup);
00960 }
00961 }
00962
00963 void View::slotFeedRemove()
00964 {
00965 TreeNode* selectedNode = m_listTabWidget->activeView()->selectedNode();
00966
00967
00968 if (!selectedNode || selectedNode == m_feedList->rootNode())
00969 return;
00970
00971 m_deleteNodeVisitor->visit(selectedNode);
00972 }
00973
00974 void View::slotFeedModify()
00975 {
00976 TreeNode* node = m_listTabWidget->activeView()->selectedNode();
00977 if (node)
00978 m_editNodePropertiesVisitor->visit(node);
00979
00980 }
00981
00982 void View::slotNextUnreadArticle()
00983 {
00984 if (m_viewMode == CombinedView)
00985 m_listTabWidget->activeView()->slotNextUnreadFeed();
00986
00987 TreeNode* sel = m_listTabWidget->activeView()->selectedNode();
00988 if (sel && sel->unread() > 0)
00989 m_articleList->slotNextUnreadArticle();
00990 else
00991 m_listTabWidget->activeView()->slotNextUnreadFeed();
00992 }
00993
00994 void View::slotPrevUnreadArticle()
00995 {
00996 if (m_viewMode == CombinedView)
00997 m_listTabWidget->activeView()->slotPrevUnreadFeed();
00998
00999 TreeNode* sel = m_listTabWidget->activeView()->selectedNode();
01000 if (sel && sel->unread() > 0)
01001 m_articleList->slotPreviousUnreadArticle();
01002 else
01003 m_listTabWidget->activeView()->slotPrevUnreadFeed();
01004 }
01005
01006 void View::slotMarkAllFeedsRead()
01007 {
01008 m_feedList->rootNode()->slotMarkAllArticlesAsRead();
01009 }
01010
01011 void View::slotMarkAllRead()
01012 {
01013 if(!m_listTabWidget->activeView()->selectedNode()) return;
01014 m_listTabWidget->activeView()->selectedNode()->slotMarkAllArticlesAsRead();
01015 }
01016
01017 void View::slotOpenHomepage()
01018 {
01019 Feed* feed = dynamic_cast<Feed *>(m_listTabWidget->activeView()->selectedNode());
01020
01021 if (!feed)
01022 return;
01023
01024 KURL url = KURL(feed->htmlUrl())
01025 ;
01026 switch (Settings::lMBBehaviour())
01027 {
01028 case Settings::EnumLMBBehaviour::OpenInExternalBrowser:
01029 slotOpenURL(url, 0, BrowserRun::EXTERNAL);
01030 break;
01031 case Settings::EnumLMBBehaviour::OpenInBackground:
01032 slotOpenURL(url, 0, BrowserRun::NEW_TAB_BACKGROUND);
01033 break;
01034 default:
01035 slotOpenURL(url, 0, BrowserRun::NEW_TAB_FOREGROUND);
01036 }
01037 }
01038
01039 void View::slotSetTotalUnread()
01040 {
01041 emit signalUnreadCountChanged( m_feedList->rootNode()->unread() );
01042 }
01043
01044 void View::slotDoIntervalFetches()
01045 {
01046 m_feedList->rootNode()->slotAddToFetchQueue(Kernel::self()->fetchQueue(), true);
01047 }
01048
01049 void View::slotFetchCurrentFeed()
01050 {
01051 if ( !m_listTabWidget->activeView()->selectedNode() )
01052 return;
01053 m_listTabWidget->activeView()->selectedNode()->slotAddToFetchQueue(Kernel::self()->fetchQueue());
01054 }
01055
01056 void View::slotFetchAllFeeds()
01057 {
01058 m_feedList->rootNode()->slotAddToFetchQueue(Kernel::self()->fetchQueue());
01059 }
01060
01061 void View::slotFetchingStarted()
01062 {
01063 m_mainFrame->setState(Frame::Started);
01064 m_actionManager->action("feed_stop")->setEnabled(true);
01065 m_mainFrame->setStatusText(i18n("Fetching Feeds..."));
01066 }
01067
01068 void View::slotFetchingStopped()
01069 {
01070 m_mainFrame->setState(Frame::Completed);
01071 m_actionManager->action("feed_stop")->setEnabled(false);
01072 m_mainFrame->setStatusText(QString::null);
01073 }
01074
01075 void View::slotFeedFetched(Feed *feed)
01076 {
01077
01078 if (feed->articles().count() > 0)
01079 {
01080 QValueList<Article> articles = feed->articles();
01081 QValueList<Article>::ConstIterator it;
01082 QValueList<Article>::ConstIterator end = articles.end();
01083 for (it = articles.begin(); it != end; ++it)
01084 {
01085 if ((*it).status()==Article::New && ((*it).feed()->useNotification() || Settings::useNotifications()))
01086 {
01087 NotificationManager::self()->slotNotifyArticle(*it);
01088 }
01089 }
01090 }
01091 }
01092
01093 void View::slotMouseButtonPressed(int button, const Article& article, const QPoint &, int)
01094 {
01095 if (button == Qt::MidButton)
01096 {
01097 KURL link = article.link();
01098 switch (Settings::mMBBehaviour())
01099 {
01100 case Settings::EnumMMBBehaviour::OpenInExternalBrowser:
01101 slotOpenURL(link, 0L, BrowserRun::EXTERNAL);
01102 break;
01103 case Settings::EnumMMBBehaviour::OpenInBackground:
01104 slotOpenURL(link, 0L, BrowserRun::NEW_TAB_BACKGROUND);
01105 break;
01106 default:
01107 slotOpenURL(link, 0L, BrowserRun::NEW_TAB_FOREGROUND);
01108 }
01109 }
01110 }
01111
01112 void View::slotAssignTag(const Tag& tag, bool assign)
01113 {
01114 kdDebug() << (assign ? "assigned" : "removed") << " tag \"" << tag.id() << "\"" << endl;
01115 QValueList<Article> selectedArticles = m_articleList->selectedArticles();
01116 for (QValueList<Article>::Iterator it = selectedArticles.begin(); it != selectedArticles.end(); ++it)
01117 {
01118 if (assign)
01119 (*it).addTag(tag.id());
01120 else
01121 (*it).removeTag(tag.id());
01122 }
01123 updateTagActions();
01124 }
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136 void View::slotNewTag()
01137 {
01138 Tag tag(KApplication::randomString(8), "New Tag");
01139 Kernel::self()->tagSet()->insert(tag);
01140 TagNode* node = m_tagNodeList->findByTagID(tag.id());
01141 if (node)
01142 m_tagNodeListView->startNodeRenaming(node);
01143 }
01144
01145 void View::slotTagCreated(const Tag& tag)
01146 {
01147 if (m_tagNodeList && !m_tagNodeList->containsTagId(tag.id()))
01148 {
01149 TagNode* tagNode = new TagNode(tag, m_feedList->rootNode());
01150 m_tagNodeList->rootNode()->appendChild(tagNode);
01151 }
01152 }
01153
01154 void View::slotTagRemoved(const Tag& )
01155 {
01156 }
01157
01158 void View::slotArticleSelected(const Article& article)
01159 {
01160 if (m_viewMode == CombinedView)
01161 return;
01162
01163 m_markReadTimer->stop();
01164
01165 Feed *feed = article.feed();
01166 if (!feed)
01167 return;
01168
01169 Article a(article);
01170 if (a.status() != Article::Read)
01171 {
01172 int delay;
01173
01174 if ( Settings::useMarkReadDelay() )
01175 {
01176 delay = Settings::markReadDelay();
01177
01178 if (delay > 0)
01179 m_markReadTimer->start( delay*1000, true );
01180 else
01181 a.setStatus(Article::Read);
01182 }
01183 }
01184
01185 KToggleAction* maai = dynamic_cast<KToggleAction*>(m_actionManager->action("article_set_status_important"));
01186 maai->setChecked(a.keep());
01187
01188 kdDebug() << "selected: " << a.guid() << endl;
01189
01190 updateTagActions();
01191
01192 m_articleViewer->slotShowArticle(a);
01193 }
01194
01195 void View::slotOpenArticleExternal(const Article& article, const QPoint&, int)
01196 {
01197 if (!article.isNull())
01198 Viewer::displayInExternalBrowser(article.link());
01199 }
01200
01201
01202 void View::slotOpenCurrentArticle()
01203 {
01204 Article article = m_articleList->currentArticle();
01205
01206 if (article.isNull())
01207 return;
01208
01209 KURL link;
01210 if (article.link().isValid())
01211 link = article.link();
01212 else if (article.guidIsPermaLink())
01213 link = KURL(article.guid());
01214
01215 if (link.isValid())
01216 {
01217 slotOpenURL(link, 0L, BrowserRun::NEW_TAB_FOREGROUND);
01218 }
01219 }
01220
01221 void View::slotOpenCurrentArticleExternal()
01222 {
01223 slotOpenArticleExternal(m_articleList->currentArticle(), QPoint(), 0);
01224 }
01225
01226 void View::slotOpenCurrentArticleBackgroundTab()
01227 {
01228 Article article = m_articleList->currentArticle();
01229
01230 if (article.isNull())
01231 return;
01232
01233 KURL link;
01234
01235 if (article.link().isValid())
01236 link = article.link();
01237 else if (article.guidIsPermaLink())
01238 link = KURL(article.guid());
01239
01240 if (link.isValid())
01241 {
01242 slotOpenURL(link, 0L, BrowserRun::NEW_TAB_BACKGROUND);
01243 }
01244 }
01245
01246 void View::slotCopyLinkAddress()
01247 {
01248 Article article = m_articleList->currentArticle();
01249
01250 if(article.isNull())
01251 return;
01252
01253 QString link;
01254 if (article.link().isValid() || (article.guidIsPermaLink() && KURL(article.guid()).isValid()))
01255 {
01256
01257 if (article.link().isValid())
01258 link = article.link().url();
01259 else
01260 link = article.guid();
01261 QClipboard *cb = QApplication::clipboard();
01262 cb->setText(link, QClipboard::Clipboard);
01263 cb->setText(link, QClipboard::Selection);
01264 }
01265 }
01266
01267 void View::slotFeedURLDropped(KURL::List &urls, TreeNode* after, Folder* parent)
01268 {
01269 KURL::List::iterator it;
01270 for ( it = urls.begin(); it != urls.end(); ++it )
01271 {
01272 addFeed((*it).prettyURL(), after, parent, false);
01273 }
01274 }
01275
01276 void View::slotToggleShowQuickFilter()
01277 {
01278 if ( Settings::showQuickFilter() )
01279 {
01280 Settings::setShowQuickFilter(false);
01281 m_searchBar->slotClearSearch();
01282 m_searchBar->hide();
01283 }
01284 else
01285 {
01286 Settings::setShowQuickFilter(true);
01287 if (!m_displayingAboutPage)
01288 m_searchBar->show();
01289 }
01290
01291 }
01292
01293 void View::slotArticleDelete()
01294 {
01295
01296 if ( m_viewMode == CombinedView )
01297 return;
01298
01299 QValueList<Article> articles = m_articleList->selectedArticles();
01300
01301 QString msg;
01302 switch (articles.count())
01303 {
01304 case 0:
01305 return;
01306 case 1:
01307 msg = i18n("<qt>Are you sure you want to delete article <b>%1</b>?</qt>").arg(QStyleSheet::escape(articles.first().title()));
01308 break;
01309 default:
01310 msg = i18n("<qt>Are you sure you want to delete the selected article?</qt>",
01311 "<qt>Are you sure you want to delete the %n selected articles?</qt>",
01312 articles.count());
01313 }
01314
01315 if (KMessageBox::warningContinueCancel(0, msg, i18n("Delete Article"), KStdGuiItem::del()) == KMessageBox::Continue)
01316 {
01317 if (m_listTabWidget->activeView()->selectedNode())
01318 m_listTabWidget->activeView()->selectedNode()->setNotificationMode(false);
01319
01320 QValueList<Feed*> feeds;
01321 for (QValueList<Article>::Iterator it = articles.begin(); it != articles.end(); ++it)
01322 {
01323 Feed* feed = (*it).feed();
01324 if (!feeds.contains(feed))
01325 feeds.append(feed);
01326 feed->setNotificationMode(false);
01327 (*it).setDeleted();
01328 }
01329
01330 for (QValueList<Feed*>::Iterator it = feeds.begin(); it != feeds.end(); ++it)
01331 {
01332 (*it)->setNotificationMode(true);
01333 }
01334
01335 if (m_listTabWidget->activeView()->selectedNode())
01336 m_listTabWidget->activeView()->selectedNode()->setNotificationMode(true);
01337 }
01338 }
01339
01340
01341 void View::slotArticleToggleKeepFlag(bool )
01342 {
01343 QValueList<Article> articles = m_articleList->selectedArticles();
01344
01345 if (articles.isEmpty())
01346 return;
01347
01348 bool allFlagsSet = true;
01349 for (QValueList<Article>::Iterator it = articles.begin(); allFlagsSet && it != articles.end(); ++it)
01350 if (!(*it).keep())
01351 allFlagsSet = false;
01352
01353 for (QValueList<Article>::Iterator it = articles.begin(); it != articles.end(); ++it)
01354 (*it).setKeep(!allFlagsSet);
01355 }
01356
01357 void View::slotSetSelectedArticleRead()
01358 {
01359 QValueList<Article> articles = m_articleList->selectedArticles();
01360
01361 if (articles.isEmpty())
01362 return;
01363
01364 for (QValueList<Article>::Iterator it = articles.begin(); it != articles.end(); ++it)
01365 (*it).setStatus(Article::Read);
01366 }
01367
01368 void View::slotTextToSpeechRequest()
01369 {
01370 if (m_currentFrame == m_mainFrame)
01371 {
01372 if (m_viewMode != CombinedView)
01373 {
01374
01375 SpeechClient::self()->slotSpeak(m_articleList->selectedArticles());
01376
01377 }
01378 else
01379 {
01380 if (m_listTabWidget->activeView()->selectedNode())
01381 {
01382
01383 }
01384 }
01385 }
01386 else
01387 {
01388 QString selectedText = static_cast<PageViewer *>(m_currentFrame->part())->selectedText();
01389
01390 if (!selectedText.isEmpty())
01391 SpeechClient::self()->slotSpeak(selectedText, "en");
01392 }
01393 }
01394
01395 void View::slotSetSelectedArticleUnread()
01396 {
01397 QValueList<Article> articles = m_articleList->selectedArticles();
01398
01399 if (articles.isEmpty())
01400 return;
01401
01402 for (QValueList<Article>::Iterator it = articles.begin(); it != articles.end(); ++it)
01403 (*it).setStatus(Article::Unread);
01404 }
01405
01406 void View::slotSetSelectedArticleNew()
01407 {
01408 QValueList<Article> articles = m_articleList->selectedArticles();
01409
01410 if (articles.isEmpty())
01411 return;
01412
01413 for (QValueList<Article>::Iterator it = articles.begin(); it != articles.end(); ++it)
01414 (*it).setStatus(Article::New);
01415 }
01416
01417 void View::slotSetCurrentArticleReadDelayed()
01418 {
01419 Article article = m_articleList->currentArticle();
01420
01421 if (article.isNull())
01422 return;
01423
01424 article.setStatus(Article::Read);
01425 }
01426
01427 void View::slotMouseOverInfo(const KFileItem *kifi)
01428 {
01429 if (kifi)
01430 {
01431 KFileItem *k=(KFileItem*)kifi;
01432 m_mainFrame->setStatusText(k->url().prettyURL());
01433 }
01434 else
01435 {
01436 m_mainFrame->setStatusText(QString::null);
01437 }
01438 }
01439
01440 void View::readProperties(KConfig* config)
01441 {
01442
01443 if (!Settings::resetQuickFilterOnNodeChange())
01444 {
01445 m_searchBar->slotSetText(config->readEntry("searchLine"));
01446 int statusfilter = config->readNumEntry("searchCombo", -1);
01447 if (statusfilter != -1)
01448 m_searchBar->slotSetStatus(statusfilter);
01449 }
01450
01451 int selectedID = config->readNumEntry("selectedNodeID", -1);
01452 if (selectedID != -1)
01453 {
01454 TreeNode* selNode = m_feedList->findByID(selectedID);
01455 if (selNode)
01456 m_listTabWidget->activeView()->setSelectedNode(selNode);
01457 }
01458
01459 QStringList urls = config->readListEntry("FeedBrowserURLs");
01460 QStringList::ConstIterator it = urls.begin();
01461 for (; it != urls.end(); ++it)
01462 {
01463 KURL url = KURL::fromPathOrURL(*it);
01464 if (url.isValid())
01465 slotOpenNewTab(url, true);
01466 }
01467 }
01468
01469 void View::saveProperties(KConfig* config)
01470 {
01471
01472 config->writeEntry("searchLine", m_searchBar->text());
01473 config->writeEntry("searchCombo", m_searchBar->status());
01474
01475 TreeNode* sel = m_listTabWidget->activeView()->selectedNode();
01476
01477 if (sel)
01478 {
01479 config->writeEntry("selectedNodeID", sel->id() );
01480 }
01481
01482
01483 QStringList urls;
01484 QPtrList<Frame> frames = m_tabs->frames();
01485 QPtrList<Frame>::ConstIterator it = frames.begin();
01486 for (; it != frames.end(); ++it)
01487 {
01488 Frame *frame = *it;
01489 KParts::ReadOnlyPart *part = frame->part();
01490 PageViewer *pageViewer = dynamic_cast<PageViewer*>(part);
01491 if (pageViewer)
01492 {
01493 KURL url = pageViewer->url();
01494 if (url.isValid())
01495 urls.append(url.prettyURL());
01496 }
01497 }
01498
01499 config->writeEntry("FeedBrowserURLs", urls);
01500 }
01501
01502 void View::connectToFeedList(FeedList* feedList)
01503 {
01504 connect(feedList->rootNode(), SIGNAL(signalChanged(TreeNode*)), this, SLOT(slotSetTotalUnread()));
01505 slotSetTotalUnread();
01506 }
01507
01508 void View::disconnectFromFeedList(FeedList* feedList)
01509 {
01510 disconnect(feedList->rootNode(), SIGNAL(signalChanged(TreeNode*)), this, SLOT(slotSetTotalUnread()));
01511 }
01512
01513 void View::updateTagActions()
01514 {
01515 QStringList tags;
01516
01517 QValueList<Article> selectedArticles = m_articleList->selectedArticles();
01518
01519 for (QValueList<Article>::ConstIterator it = selectedArticles.begin(); it != selectedArticles.end(); ++it)
01520 {
01521 QStringList atags = (*it).tags();
01522 for (QStringList::ConstIterator it2 = atags.begin(); it2 != atags.end(); ++it2)
01523 {
01524 if (!tags.contains(*it2))
01525 tags += *it2;
01526 }
01527 }
01528 m_actionManager->slotUpdateTagActions(!selectedArticles.isEmpty(), tags);
01529 }
01530
01531 }
01532
01533 #include "akregator_view.moc"