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