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 if (node)
00823 m_mainFrame->setCaption(node->title());
00824
00825 m_actionManager->slotNodeSelected(node);
00826
00827 updateTagActions();
00828 }
00829
00830 void View::slotOpenURL(const KURL& url, Viewer* currentViewer, BrowserRun::OpeningMode mode)
00831 {
00832 if (mode == BrowserRun::EXTERNAL)
00833 Viewer::displayInExternalBrowser(url);
00834 else
00835 {
00836 KParts::URLArgs args = currentViewer ? currentViewer->browserExtension()->urlArgs() : KParts::URLArgs();
00837
00838 BrowserRun* r = new BrowserRun(this, currentViewer, url, args, mode);
00839 connect(r, SIGNAL(signalOpenInViewer(const KURL&, Akregator::Viewer*, Akregator::BrowserRun::OpeningMode)),
00840 this, SLOT(slotOpenURLReply(const KURL&, Akregator::Viewer*, Akregator::BrowserRun::OpeningMode)));
00841 }
00842 }
00843
00844
00845 void View::slotUrlClickedInViewer(const KURL& url, Viewer* viewer, bool newTab, bool background)
00846 {
00847
00848 if (!newTab)
00849 {
00850 slotOpenURL(url, viewer, BrowserRun::CURRENT_TAB);
00851 }
00852 else
00853 {
00854 slotOpenURL(url, 0L, background ? BrowserRun::NEW_TAB_BACKGROUND : BrowserRun::NEW_TAB_FOREGROUND);
00855 }
00856 }
00857
00858
00859 void View::slotOpenURLReply(const KURL& url, Viewer* currentViewer, BrowserRun::OpeningMode mode)
00860 {
00861 switch (mode)
00862 {
00863 case BrowserRun::CURRENT_TAB:
00864 currentViewer->openURL(url);
00865 break;
00866 case BrowserRun::NEW_TAB_FOREGROUND:
00867 case BrowserRun::NEW_TAB_BACKGROUND:
00868 slotOpenNewTab(url, mode == BrowserRun::NEW_TAB_BACKGROUND);
00869 break;
00870 case BrowserRun::EXTERNAL:
00871 Viewer::displayInExternalBrowser(url);
00872 break;
00873 }
00874 }
00875
00876 void View::slotFeedAdd()
00877 {
00878 Folder* group = 0;
00879 if (!m_feedListView->selectedNode())
00880 group = m_feedList->rootNode();
00881 else
00882 {
00883
00884 if ( m_feedListView->selectedNode()->isGroup())
00885 group = static_cast<Folder*>(m_feedListView->selectedNode());
00886 else
00887 group= m_feedListView->selectedNode()->parent();
00888
00889 }
00890
00891 TreeNode* lastChild = group->children().last();
00892
00893 addFeed(QString::null, lastChild, group, false);
00894 }
00895
00896 void View::addFeed(const QString& url, TreeNode *after, Folder* parent, bool autoExec)
00897 {
00898
00899 AddFeedDialog *afd = new AddFeedDialog( 0, "add_feed" );
00900
00901 afd->setURL(KURL::decode_string(url));
00902
00903 if (autoExec)
00904 afd->slotOk();
00905 else
00906 {
00907 if (afd->exec() != QDialog::Accepted)
00908 {
00909 delete afd;
00910 return;
00911 }
00912 }
00913
00914 Feed* feed = afd->feed;
00915 delete afd;
00916
00917 FeedPropertiesDialog *dlg = new FeedPropertiesDialog( 0, "edit_feed" );
00918 dlg->setFeed(feed);
00919
00920 dlg->selectFeedName();
00921
00922 if (!autoExec)
00923 if (dlg->exec() != QDialog::Accepted)
00924 {
00925 delete feed;
00926 delete dlg;
00927 return;
00928 }
00929
00930 if (!parent)
00931 parent = m_feedList->rootNode();
00932
00933 parent->insertChild(feed, after);
00934
00935 m_feedListView->ensureNodeVisible(feed);
00936
00937
00938 delete dlg;
00939 }
00940
00941 void View::slotFeedAddGroup()
00942 {
00943 TreeNode* node = m_feedListView->selectedNode();
00944 TreeNode* after = 0;
00945
00946 if (!node)
00947 node = m_feedListView->rootNode();
00948
00949
00950
00951 if (!node->isGroup())
00952 {
00953 after = node;
00954 node = node->parent();
00955 }
00956
00957 Folder* currentGroup = static_cast<Folder*> (node);
00958
00959 bool Ok;
00960
00961 QString text = KInputDialog::getText(i18n("Add Folder"), i18n("Folder name:"), "", &Ok);
00962
00963 if (Ok)
00964 {
00965 Folder* newGroup = new Folder(text);
00966 if (!after)
00967 currentGroup->appendChild(newGroup);
00968 else
00969 currentGroup->insertChild(newGroup, after);
00970
00971 m_feedListView->ensureNodeVisible(newGroup);
00972 }
00973 }
00974
00975 void View::slotFeedRemove()
00976 {
00977 TreeNode* selectedNode = m_listTabWidget->activeView()->selectedNode();
00978
00979
00980 if (!selectedNode || selectedNode == m_feedList->rootNode())
00981 return;
00982
00983 m_deleteNodeVisitor->visit(selectedNode);
00984 }
00985
00986 void View::slotFeedModify()
00987 {
00988 TreeNode* node = m_listTabWidget->activeView()->selectedNode();
00989 if (node)
00990 m_editNodePropertiesVisitor->visit(node);
00991
00992 }
00993
00994 void View::slotNextUnreadArticle()
00995 {
00996 if (m_viewMode == CombinedView)
00997 m_listTabWidget->activeView()->slotNextUnreadFeed();
00998
00999 TreeNode* sel = m_listTabWidget->activeView()->selectedNode();
01000 if (sel && sel->unread() > 0)
01001 m_articleList->slotNextUnreadArticle();
01002 else
01003 m_listTabWidget->activeView()->slotNextUnreadFeed();
01004 }
01005
01006 void View::slotPrevUnreadArticle()
01007 {
01008 if (m_viewMode == CombinedView)
01009 m_listTabWidget->activeView()->slotPrevUnreadFeed();
01010
01011 TreeNode* sel = m_listTabWidget->activeView()->selectedNode();
01012 if (sel && sel->unread() > 0)
01013 m_articleList->slotPreviousUnreadArticle();
01014 else
01015 m_listTabWidget->activeView()->slotPrevUnreadFeed();
01016 }
01017
01018 void View::slotMarkAllFeedsRead()
01019 {
01020 m_feedList->rootNode()->slotMarkAllArticlesAsRead();
01021 }
01022
01023 void View::slotMarkAllRead()
01024 {
01025 if(!m_listTabWidget->activeView()->selectedNode()) return;
01026 m_listTabWidget->activeView()->selectedNode()->slotMarkAllArticlesAsRead();
01027 }
01028
01029 void View::slotOpenHomepage()
01030 {
01031 Feed* feed = dynamic_cast<Feed *>(m_listTabWidget->activeView()->selectedNode());
01032
01033 if (!feed)
01034 return;
01035
01036 KURL url = KURL(feed->htmlUrl())
01037 ;
01038 switch (Settings::lMBBehaviour())
01039 {
01040 case Settings::EnumLMBBehaviour::OpenInExternalBrowser:
01041 slotOpenURL(url, 0, BrowserRun::EXTERNAL);
01042 break;
01043 case Settings::EnumLMBBehaviour::OpenInBackground:
01044 slotOpenURL(url, 0, BrowserRun::NEW_TAB_BACKGROUND);
01045 break;
01046 default:
01047 slotOpenURL(url, 0, BrowserRun::NEW_TAB_FOREGROUND);
01048 }
01049 }
01050
01051 void View::slotSetTotalUnread()
01052 {
01053 emit signalUnreadCountChanged( m_feedList->rootNode()->unread() );
01054 }
01055
01056 void View::slotDoIntervalFetches()
01057 {
01058 m_feedList->rootNode()->slotAddToFetchQueue(Kernel::self()->fetchQueue(), true);
01059 }
01060
01061 void View::slotFetchCurrentFeed()
01062 {
01063 if ( !m_listTabWidget->activeView()->selectedNode() )
01064 return;
01065 m_listTabWidget->activeView()->selectedNode()->slotAddToFetchQueue(Kernel::self()->fetchQueue());
01066 }
01067
01068 void View::slotFetchAllFeeds()
01069 {
01070 m_feedList->rootNode()->slotAddToFetchQueue(Kernel::self()->fetchQueue());
01071 }
01072
01073 void View::slotFetchingStarted()
01074 {
01075 m_mainFrame->setState(Frame::Started);
01076 m_actionManager->action("feed_stop")->setEnabled(true);
01077 m_mainFrame->setStatusText(i18n("Fetching Feeds..."));
01078 }
01079
01080 void View::slotFetchingStopped()
01081 {
01082 m_mainFrame->setState(Frame::Completed);
01083 m_actionManager->action("feed_stop")->setEnabled(false);
01084 m_mainFrame->setStatusText(QString::null);
01085 }
01086
01087 void View::slotFeedFetched(Feed *feed)
01088 {
01089
01090 if (feed->articles().count() > 0)
01091 {
01092 QValueList<Article> articles = feed->articles();
01093 QValueList<Article>::ConstIterator it;
01094 QValueList<Article>::ConstIterator end = articles.end();
01095 for (it = articles.begin(); it != end; ++it)
01096 {
01097 if ((*it).status()==Article::New && ((*it).feed()->useNotification() || Settings::useNotifications()))
01098 {
01099 NotificationManager::self()->slotNotifyArticle(*it);
01100 }
01101 }
01102 }
01103 }
01104
01105 void View::slotMouseButtonPressed(int button, const Article& article, const QPoint &, int)
01106 {
01107 if (button == Qt::MidButton)
01108 {
01109 KURL link = article.link();
01110 switch (Settings::mMBBehaviour())
01111 {
01112 case Settings::EnumMMBBehaviour::OpenInExternalBrowser:
01113 slotOpenURL(link, 0L, BrowserRun::EXTERNAL);
01114 break;
01115 case Settings::EnumMMBBehaviour::OpenInBackground:
01116 slotOpenURL(link, 0L, BrowserRun::NEW_TAB_BACKGROUND);
01117 break;
01118 default:
01119 slotOpenURL(link, 0L, BrowserRun::NEW_TAB_FOREGROUND);
01120 }
01121 }
01122 }
01123
01124 void View::slotAssignTag(const Tag& tag, bool assign)
01125 {
01126 kdDebug() << (assign ? "assigned" : "removed") << " tag \"" << tag.id() << "\"" << endl;
01127 QValueList<Article> selectedArticles = m_articleList->selectedArticles();
01128 for (QValueList<Article>::Iterator it = selectedArticles.begin(); it != selectedArticles.end(); ++it)
01129 {
01130 if (assign)
01131 (*it).addTag(tag.id());
01132 else
01133 (*it).removeTag(tag.id());
01134 }
01135 updateTagActions();
01136 }
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147
01148 void View::slotNewTag()
01149 {
01150 Tag tag(KApplication::randomString(8), "New Tag");
01151 Kernel::self()->tagSet()->insert(tag);
01152 TagNode* node = m_tagNodeList->findByTagID(tag.id());
01153 if (node)
01154 m_tagNodeListView->startNodeRenaming(node);
01155 }
01156
01157 void View::slotTagCreated(const Tag& tag)
01158 {
01159 if (m_tagNodeList && !m_tagNodeList->containsTagId(tag.id()))
01160 {
01161 TagNode* tagNode = new TagNode(tag, m_feedList->rootNode());
01162 m_tagNodeList->rootNode()->appendChild(tagNode);
01163 }
01164 }
01165
01166 void View::slotTagRemoved(const Tag& )
01167 {
01168 }
01169
01170 void View::slotArticleSelected(const Article& article)
01171 {
01172 if (m_viewMode == CombinedView)
01173 return;
01174
01175 m_markReadTimer->stop();
01176
01177 Feed *feed = article.feed();
01178 if (!feed)
01179 return;
01180
01181 Article a(article);
01182 if (a.status() != Article::Read)
01183 {
01184 int delay;
01185
01186 if ( Settings::useMarkReadDelay() )
01187 {
01188 delay = Settings::markReadDelay();
01189
01190 if (delay > 0)
01191 m_markReadTimer->start( delay*1000, true );
01192 else
01193 a.setStatus(Article::Read);
01194 }
01195 }
01196
01197 KToggleAction* maai = dynamic_cast<KToggleAction*>(m_actionManager->action("article_set_status_important"));
01198 maai->setChecked(a.keep());
01199
01200 kdDebug() << "selected: " << a.guid() << endl;
01201
01202 updateTagActions();
01203
01204 m_articleViewer->slotShowArticle(a);
01205 }
01206
01207 void View::slotOpenArticleExternal(const Article& article, const QPoint&, int)
01208 {
01209 if (!article.isNull())
01210 Viewer::displayInExternalBrowser(article.link());
01211 }
01212
01213
01214 void View::slotOpenCurrentArticle()
01215 {
01216 Article article = m_articleList->currentArticle();
01217
01218 if (article.isNull())
01219 return;
01220
01221 KURL link;
01222 if (article.link().isValid())
01223 link = article.link();
01224 else if (article.guidIsPermaLink())
01225 link = KURL(article.guid());
01226
01227 if (link.isValid())
01228 {
01229 slotOpenURL(link, 0L, BrowserRun::NEW_TAB_FOREGROUND);
01230 }
01231 }
01232
01233 void View::slotOpenCurrentArticleExternal()
01234 {
01235 slotOpenArticleExternal(m_articleList->currentArticle(), QPoint(), 0);
01236 }
01237
01238 void View::slotOpenCurrentArticleBackgroundTab()
01239 {
01240 Article article = m_articleList->currentArticle();
01241
01242 if (article.isNull())
01243 return;
01244
01245 KURL link;
01246
01247 if (article.link().isValid())
01248 link = article.link();
01249 else if (article.guidIsPermaLink())
01250 link = KURL(article.guid());
01251
01252 if (link.isValid())
01253 {
01254 slotOpenURL(link, 0L, BrowserRun::NEW_TAB_BACKGROUND);
01255 }
01256 }
01257
01258 void View::slotCopyLinkAddress()
01259 {
01260 Article article = m_articleList->currentArticle();
01261
01262 if(article.isNull())
01263 return;
01264
01265 QString link;
01266 if (article.link().isValid() || (article.guidIsPermaLink() && KURL(article.guid()).isValid()))
01267 {
01268
01269 if (article.link().isValid())
01270 link = article.link().url();
01271 else
01272 link = article.guid();
01273 QClipboard *cb = QApplication::clipboard();
01274 cb->setText(link, QClipboard::Clipboard);
01275 cb->setText(link, QClipboard::Selection);
01276 }
01277 }
01278
01279 void View::slotFeedURLDropped(KURL::List &urls, TreeNode* after, Folder* parent)
01280 {
01281 KURL::List::iterator it;
01282 for ( it = urls.begin(); it != urls.end(); ++it )
01283 {
01284 addFeed((*it).prettyURL(), after, parent, false);
01285 }
01286 }
01287
01288 void View::slotToggleShowQuickFilter()
01289 {
01290 if ( Settings::showQuickFilter() )
01291 {
01292 Settings::setShowQuickFilter(false);
01293 m_searchBar->slotClearSearch();
01294 m_searchBar->hide();
01295 }
01296 else
01297 {
01298 Settings::setShowQuickFilter(true);
01299 if (!m_displayingAboutPage)
01300 m_searchBar->show();
01301 }
01302
01303 }
01304
01305 void View::slotArticleDelete()
01306 {
01307
01308 if ( m_viewMode == CombinedView )
01309 return;
01310
01311 QValueList<Article> articles = m_articleList->selectedArticles();
01312
01313 QString msg;
01314 switch (articles.count())
01315 {
01316 case 0:
01317 return;
01318 case 1:
01319 msg = i18n("<qt>Are you sure you want to delete article <b>%1</b>?</qt>").arg(QStyleSheet::escape(articles.first().title()));
01320 break;
01321 default:
01322 msg = i18n("<qt>Are you sure you want to delete the selected article?</qt>",
01323 "<qt>Are you sure you want to delete the %n selected articles?</qt>",
01324 articles.count());
01325 }
01326
01327 if (KMessageBox::warningContinueCancel(0, msg, i18n("Delete Article"), KStdGuiItem::del()) == KMessageBox::Continue)
01328 {
01329 if (m_listTabWidget->activeView()->selectedNode())
01330 m_listTabWidget->activeView()->selectedNode()->setNotificationMode(false);
01331
01332 QValueList<Feed*> feeds;
01333 for (QValueList<Article>::Iterator it = articles.begin(); it != articles.end(); ++it)
01334 {
01335 Feed* feed = (*it).feed();
01336 if (!feeds.contains(feed))
01337 feeds.append(feed);
01338 feed->setNotificationMode(false);
01339 (*it).setDeleted();
01340 }
01341
01342 for (QValueList<Feed*>::Iterator it = feeds.begin(); it != feeds.end(); ++it)
01343 {
01344 (*it)->setNotificationMode(true);
01345 }
01346
01347 if (m_listTabWidget->activeView()->selectedNode())
01348 m_listTabWidget->activeView()->selectedNode()->setNotificationMode(true);
01349 }
01350 }
01351
01352
01353 void View::slotArticleToggleKeepFlag(bool )
01354 {
01355 QValueList<Article> articles = m_articleList->selectedArticles();
01356
01357 if (articles.isEmpty())
01358 return;
01359
01360 bool allFlagsSet = true;
01361 for (QValueList<Article>::Iterator it = articles.begin(); allFlagsSet && it != articles.end(); ++it)
01362 if (!(*it).keep())
01363 allFlagsSet = false;
01364
01365 for (QValueList<Article>::Iterator it = articles.begin(); it != articles.end(); ++it)
01366 (*it).setKeep(!allFlagsSet);
01367 }
01368
01369 void View::slotSetSelectedArticleRead()
01370 {
01371 QValueList<Article> articles = m_articleList->selectedArticles();
01372
01373 if (articles.isEmpty())
01374 return;
01375
01376 for (QValueList<Article>::Iterator it = articles.begin(); it != articles.end(); ++it)
01377 (*it).setStatus(Article::Read);
01378 }
01379
01380 void View::slotTextToSpeechRequest()
01381 {
01382 if (m_currentFrame == m_mainFrame)
01383 {
01384 if (m_viewMode != CombinedView)
01385 {
01386
01387 SpeechClient::self()->slotSpeak(m_articleList->selectedArticles());
01388
01389 }
01390 else
01391 {
01392 if (m_listTabWidget->activeView()->selectedNode())
01393 {
01394
01395 }
01396 }
01397 }
01398 else
01399 {
01400 QString selectedText = static_cast<PageViewer *>(m_currentFrame->part())->selectedText();
01401
01402 if (!selectedText.isEmpty())
01403 SpeechClient::self()->slotSpeak(selectedText, "en");
01404 }
01405 }
01406
01407 void View::slotSetSelectedArticleUnread()
01408 {
01409 QValueList<Article> articles = m_articleList->selectedArticles();
01410
01411 if (articles.isEmpty())
01412 return;
01413
01414 for (QValueList<Article>::Iterator it = articles.begin(); it != articles.end(); ++it)
01415 (*it).setStatus(Article::Unread);
01416 }
01417
01418 void View::slotSetSelectedArticleNew()
01419 {
01420 QValueList<Article> articles = m_articleList->selectedArticles();
01421
01422 if (articles.isEmpty())
01423 return;
01424
01425 for (QValueList<Article>::Iterator it = articles.begin(); it != articles.end(); ++it)
01426 (*it).setStatus(Article::New);
01427 }
01428
01429 void View::slotSetCurrentArticleReadDelayed()
01430 {
01431 Article article = m_articleList->currentArticle();
01432
01433 if (article.isNull())
01434 return;
01435
01436 article.setStatus(Article::Read);
01437 }
01438
01439 void View::slotMouseOverInfo(const KFileItem *kifi)
01440 {
01441 if (kifi)
01442 {
01443 KFileItem *k=(KFileItem*)kifi;
01444 m_mainFrame->setStatusText(k->url().prettyURL());
01445 }
01446 else
01447 {
01448 m_mainFrame->setStatusText(QString::null);
01449 }
01450 }
01451
01452 void View::readProperties(KConfig* config)
01453 {
01454
01455 if (!Settings::resetQuickFilterOnNodeChange())
01456 {
01457 m_searchBar->slotSetText(config->readEntry("searchLine"));
01458 int statusfilter = config->readNumEntry("searchCombo", -1);
01459 if (statusfilter != -1)
01460 m_searchBar->slotSetStatus(statusfilter);
01461 }
01462
01463 int selectedID = config->readNumEntry("selectedNodeID", -1);
01464 if (selectedID != -1)
01465 {
01466 TreeNode* selNode = m_feedList->findByID(selectedID);
01467 if (selNode)
01468 m_listTabWidget->activeView()->setSelectedNode(selNode);
01469 }
01470 }
01471
01472 void View::saveProperties(KConfig* config)
01473 {
01474
01475 config->writeEntry("searchLine", m_searchBar->text());
01476 config->writeEntry("searchCombo", m_searchBar->status());
01477
01478 TreeNode* sel = m_listTabWidget->activeView()->selectedNode();
01479
01480 if (sel)
01481 {
01482 config->writeEntry("selectedNodeID", sel->id() );
01483 }
01484 }
01485
01486 void View::connectToFeedList(FeedList* feedList)
01487 {
01488 connect(feedList->rootNode(), SIGNAL(signalChanged(TreeNode*)), this, SLOT(slotSetTotalUnread()));
01489 slotSetTotalUnread();
01490 }
01491
01492 void View::disconnectFromFeedList(FeedList* feedList)
01493 {
01494 disconnect(feedList->rootNode(), SIGNAL(signalChanged(TreeNode*)), this, SLOT(slotSetTotalUnread()));
01495 }
01496
01497 void View::updateTagActions()
01498 {
01499 QStringList tags;
01500
01501 QValueList<Article> selectedArticles = m_articleList->selectedArticles();
01502
01503 for (QValueList<Article>::ConstIterator it = selectedArticles.begin(); it != selectedArticles.end(); ++it)
01504 {
01505 QStringList atags = (*it).tags();
01506 for (QStringList::ConstIterator it2 = atags.begin(); it2 != atags.end(); ++it2)
01507 {
01508 if (!tags.contains(*it2))
01509 tags += *it2;
01510 }
01511 }
01512 m_actionManager->slotUpdateTagActions(!selectedArticles.isEmpty(), tags);
01513 }
01514
01515 }
01516
01517 #include "akregator_view.moc"