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 QTimer::singleShot(0, this, SLOT(delayedInit()));
00371 }
00372
00373 void View::delayedInit()
00374 {
00375
00376
00377
00378
00379
00380 if ( !m_part->mergePart(m_articleViewer) )
00381 QTimer::singleShot(500, this, SLOT(delayedInit()));
00382 }
00383
00384 void View::slotSettingsChanged()
00385 {
00386
00387 m_listTabWidget->setViewMode(Settings::showTaggingGUI() ? ListTabWidget::verticalTabs : ListTabWidget::single);
00388
00389 }
00390
00391 void View::slotOnShutdown()
00392 {
00393 m_shuttingDown = true;
00394
00395 m_articleList->slotShowNode(0);
00396 m_articleViewer->slotShowNode(0);
00397
00398 Kernel::self()->fetchQueue()->slotAbort();
00399
00400 m_feedListView->setNodeList(0);
00401 ProgressManager::self()->setFeedList(0);
00402
00403 delete m_feedList;
00404 delete m_tagNodeList;
00405
00406
00407
00408 m_tabs->setCurrentPage(m_tabs->count()-1);
00409 while (m_tabs->count() > 1)
00410 m_tabs->slotRemoveCurrentFrame();
00411
00412 delete m_mainTab;
00413 delete m_mainFrame;
00414 delete m_editNodePropertiesVisitor;
00415 delete m_deleteNodeVisitor;
00416 }
00417
00418 void View::saveSettings()
00419 {
00420 Settings::setSplitter1Sizes( m_horizontalSplitter->sizes() );
00421 Settings::setSplitter2Sizes( m_articleSplitter->sizes() );
00422 Settings::setViewMode( m_viewMode );
00423 Settings::writeConfig();
00424 }
00425
00426 void View::slotOpenNewTab(const KURL& url, bool background)
00427 {
00428 PageViewer* page = new PageViewer(this, "page");
00429
00430 connect( m_part, SIGNAL(signalSettingsChanged()), page, SLOT(slotPaletteOrFontChanged()));
00431
00432 connect( page, SIGNAL(setTabIcon(const QPixmap&)),
00433 this, SLOT(setTabIcon(const QPixmap&)));
00434 connect( page, SIGNAL(urlClicked(const KURL &, Viewer*, bool, bool)),
00435 this, SLOT(slotUrlClickedInViewer(const KURL &, Viewer*, bool, bool)) );
00436
00437 Frame* frame = new Frame(this, page, page->widget(), i18n("Untitled"));
00438 frame->setAutoDeletePart(true);
00439
00440 connect(page, SIGNAL(setWindowCaption (const QString &)), frame, SLOT(setTitle (const QString &)));
00441 connectFrame(frame);
00442 m_tabs->addFrame(frame);
00443
00444 if(!background)
00445 m_tabs->showPage(page->widget());
00446 else
00447 setFocus();
00448
00449 page->openURL(url);
00450 }
00451
00452
00453 void View::setTabIcon(const QPixmap& icon)
00454 {
00455 const PageViewer *s = dynamic_cast<const PageViewer*>(sender());
00456 if (s) {
00457 m_tabs->setTabIconSet(const_cast<PageViewer*>(s)->widget(), icon);
00458 }
00459 }
00460
00461 void View::connectFrame(Frame *f)
00462 {
00463 connect(f, SIGNAL(statusText(const QString &)), this, SLOT(slotStatusText(const QString&)));
00464 connect(f, SIGNAL(captionChanged (const QString &)), this, SLOT(slotCaptionChanged (const QString &)));
00465 connect(f, SIGNAL(loadingProgress(int)), this, SLOT(slotLoadingProgress(int)) );
00466 connect(f, SIGNAL(started()), this, SLOT(slotStarted()));
00467 connect(f, SIGNAL(completed()), this, SLOT(slotCompleted()));
00468 connect(f, SIGNAL(canceled(const QString &)), this, SLOT(slotCanceled(const QString&)));
00469 }
00470
00471 void View::slotStatusText(const QString &c)
00472 {
00473 if (sender() == m_currentFrame)
00474 emit setStatusBarText(c);
00475 }
00476
00477 void View::slotCaptionChanged(const QString &c)
00478 {
00479 if (sender() == m_currentFrame)
00480 emit setWindowCaption(c);
00481 }
00482
00483 void View::slotStarted()
00484 {
00485 if (sender() == m_currentFrame)
00486 emit signalStarted(0);
00487 }
00488
00489 void View::slotCanceled(const QString &s)
00490 {
00491 if (sender() == m_currentFrame)
00492 emit signalCanceled(s);
00493 }
00494
00495 void View::slotCompleted()
00496 {
00497 if (sender() == m_currentFrame)
00498 emit signalCompleted();
00499 }
00500
00501 void View::slotLoadingProgress(int percent)
00502 {
00503 if (sender() == m_currentFrame)
00504 emit setProgress(percent);
00505 }
00506
00507 bool View::importFeeds(const QDomDocument& doc)
00508 {
00509 FeedList* feedList = new FeedList();
00510 bool parsed = feedList->readFromXML(doc);
00511
00512
00513 if (!parsed)
00514 {
00515 delete feedList;
00516 return false;
00517 }
00518 QString title = feedList->title();
00519
00520 if (title.isEmpty())
00521 title = i18n("Imported Folder");
00522
00523 bool ok;
00524 title = KInputDialog::getText(i18n("Add Imported Folder"), i18n("Imported folder name:"), title, &ok);
00525
00526 if (!ok)
00527 {
00528 delete feedList;
00529 return false;
00530 }
00531
00532 Folder* fg = new Folder(title);
00533 m_feedList->rootNode()->appendChild(fg);
00534 m_feedList->append(feedList, fg);
00535
00536 return true;
00537 }
00538
00539 bool View::loadFeeds(const QDomDocument& doc, Folder* parent)
00540 {
00541 FeedList* feedList = new FeedList();
00542 bool parsed = feedList->readFromXML(doc);
00543
00544
00545 if (!parsed)
00546 {
00547 delete feedList;
00548 return false;
00549 }
00550 m_feedListView->setUpdatesEnabled(false);
00551 m_tagNodeListView->setUpdatesEnabled(false);
00552 if (!parent)
00553 {
00554 TagSet* tagSet = Kernel::self()->tagSet();
00555
00556 Kernel::self()->setFeedList(feedList);
00557 ProgressManager::self()->setFeedList(feedList);
00558 disconnectFromFeedList(m_feedList);
00559 delete m_feedList;
00560 delete m_tagNodeList;
00561 m_feedList = feedList;
00562 connectToFeedList(m_feedList);
00563
00564 m_tagNodeList = new TagNodeList(m_feedList, tagSet);
00565 m_feedListView->setNodeList(m_feedList);
00566 m_tagNodeListView->setNodeList(m_tagNodeList);
00567
00568 QStringList tagIDs = m_feedList->rootNode()->tags();
00569 QStringList::ConstIterator end = tagIDs.end();
00570 for (QStringList::ConstIterator it = tagIDs.begin(); it != end; ++it)
00571 {
00572 kdDebug() << *it << endl;
00573
00574
00575
00576 if (!tagSet->containsID(*it))
00577 {
00578 Tag tag(*it, *it);
00579 tagSet->insert(tag);
00580 }
00581 }
00582 }
00583 else
00584 m_feedList->append(feedList, parent);
00585
00586 m_feedListView->setUpdatesEnabled(true);
00587 m_feedListView->triggerUpdate();
00588 m_tagNodeListView->setUpdatesEnabled(true);
00589 m_tagNodeListView->triggerUpdate();
00590 return true;
00591 }
00592
00593 void View::slotDeleteExpiredArticles()
00594 {
00595 TreeNode* rootNode = m_feedList->rootNode();
00596 if (rootNode)
00597 rootNode->slotDeleteExpiredArticles();
00598 }
00599
00600 QDomDocument View::feedListToOPML()
00601 {
00602 return m_feedList->toXML();
00603 }
00604
00605 void View::addFeedToGroup(const QString& url, const QString& groupName)
00606 {
00607
00608
00609 TreeNode* node = m_feedListView->findNodeByTitle(groupName);
00610
00611 Folder* group = 0;
00612 if (!node || !node->isGroup())
00613 {
00614 Folder* g = new Folder( groupName );
00615 m_feedList->rootNode()->appendChild(g);
00616 group = g;
00617 }
00618 else
00619 group = static_cast<Folder*>(node);
00620
00621
00622 if (group)
00623 addFeed(url, 0, group, true);
00624 }
00625
00626 void View::slotNormalView()
00627 {
00628 if (m_viewMode == NormalView)
00629 return;
00630
00631 if (m_viewMode == CombinedView)
00632 {
00633 m_articleList->slotShowNode(m_listTabWidget->activeView()->selectedNode());
00634 m_articleList->show();
00635
00636 Article article = m_articleList->currentArticle();
00637
00638 if (!article.isNull())
00639 m_articleViewer->slotShowArticle(article);
00640 else
00641 m_articleViewer->slotShowSummary(m_listTabWidget->activeView()->selectedNode());
00642 }
00643
00644 m_articleSplitter->setOrientation(QSplitter::Vertical);
00645 m_viewMode = NormalView;
00646
00647 Settings::setViewMode( m_viewMode );
00648 }
00649
00650 void View::slotWidescreenView()
00651 {
00652 if (m_viewMode == WidescreenView)
00653 return;
00654
00655 if (m_viewMode == CombinedView)
00656 {
00657 m_articleList->slotShowNode(m_listTabWidget->activeView()->selectedNode());
00658 m_articleList->show();
00659
00660 Article article = m_articleList->currentArticle();
00661
00662 if (!article.isNull())
00663 m_articleViewer->slotShowArticle(article);
00664 else
00665 m_articleViewer->slotShowSummary(m_listTabWidget->activeView()->selectedNode());
00666 }
00667
00668 m_articleSplitter->setOrientation(QSplitter::Horizontal);
00669 m_viewMode = WidescreenView;
00670
00671 Settings::setViewMode( m_viewMode );
00672 }
00673
00674 void View::slotCombinedView()
00675 {
00676 if (m_viewMode == CombinedView)
00677 return;
00678
00679 m_articleList->slotClear();
00680 m_articleList->hide();
00681 m_viewMode = CombinedView;
00682
00683 slotNodeSelected(m_listTabWidget->activeView()->selectedNode());
00684 Settings::setViewMode( m_viewMode );
00685 }
00686
00687 void View::slotFrameChanged(Frame *f)
00688 {
00689 if (m_shuttingDown)
00690 return;
00691
00692 m_currentFrame=f;
00693
00694 emit setWindowCaption(f->caption());
00695 emit setProgress(f->progress());
00696 emit setStatusBarText(f->statusText());
00697
00698 m_part->mergePart(m_articleViewer);
00699
00700 if (f->part() == m_part)
00701 m_part->mergePart(m_articleViewer);
00702 else
00703 m_part->mergePart(f->part());
00704
00705 f->widget()->setFocus();
00706
00707 switch (f->state())
00708 {
00709 case Frame::Started:
00710 emit signalStarted(0);
00711 break;
00712 case Frame::Canceled:
00713 emit signalCanceled(QString::null);
00714 break;
00715 case Frame::Idle:
00716 case Frame::Completed:
00717 default:
00718 emit signalCompleted();
00719 }
00720 }
00721
00722 void View::slotFeedTreeContextMenu(KListView*, TreeNode* , const QPoint& )
00723 {
00724 m_tabs->showPage(m_mainTab);
00725 }
00726
00727 void View::slotMoveCurrentNodeUp()
00728 {
00729 TreeNode* current = m_listTabWidget->activeView()->selectedNode();
00730 if (!current)
00731 return;
00732 TreeNode* prev = current->prevSibling();
00733 Folder* parent = current->parent();
00734
00735 if (!prev || !parent)
00736 return;
00737
00738 parent->removeChild(prev);
00739 parent->insertChild(prev, current);
00740 m_listTabWidget->activeView()->ensureNodeVisible(current);
00741 }
00742
00743 void View::slotMoveCurrentNodeDown()
00744 {
00745 TreeNode* current = m_listTabWidget->activeView()->selectedNode();
00746 if (!current)
00747 return;
00748 TreeNode* next = current->nextSibling();
00749 Folder* parent = current->parent();
00750
00751 if (!next || !parent)
00752 return;
00753
00754 parent->removeChild(current);
00755 parent->insertChild(current, next);
00756 m_listTabWidget->activeView()->ensureNodeVisible(current);
00757 }
00758
00759 void View::slotMoveCurrentNodeLeft()
00760 {
00761 TreeNode* current = m_listTabWidget->activeView()->selectedNode();
00762 if (!current || !current->parent() || !current->parent()->parent())
00763 return;
00764
00765 Folder* parent = current->parent();
00766 Folder* grandparent = current->parent()->parent();
00767
00768 parent->removeChild(current);
00769 grandparent->insertChild(current, parent);
00770 m_listTabWidget->activeView()->ensureNodeVisible(current);
00771 }
00772
00773 void View::slotMoveCurrentNodeRight()
00774 {
00775 TreeNode* current = m_listTabWidget->activeView()->selectedNode();
00776 if (!current || !current->parent())
00777 return;
00778 TreeNode* prev = current->prevSibling();
00779
00780 if ( prev && prev->isGroup() )
00781 {
00782 Folder* fg = static_cast<Folder*>(prev);
00783 current->parent()->removeChild(current);
00784 fg->appendChild(current);
00785 m_listTabWidget->activeView()->ensureNodeVisible(current);
00786 }
00787 }
00788
00789 void View::slotNodeSelected(TreeNode* node)
00790 {
00791 m_markReadTimer->stop();
00792
00793 if (node)
00794 {
00795 kdDebug() << "node selected: " << node->title() << endl;
00796 kdDebug() << "unread: " << node->unread() << endl;
00797 kdDebug() << "total: " << node->totalCount() << endl;
00798 }
00799
00800 if (m_displayingAboutPage)
00801 {
00802 m_mainFrame->setTitle(i18n("Articles"));
00803 if (m_viewMode != CombinedView)
00804 m_articleList->show();
00805 if (Settings::showQuickFilter())
00806 m_searchBar->show();
00807 m_displayingAboutPage = false;
00808 }
00809
00810 m_tabs->showPage(m_mainTab);
00811
00812 if (Settings::resetQuickFilterOnNodeChange())
00813 m_searchBar->slotClearSearch();
00814
00815 if (m_viewMode == CombinedView)
00816 m_articleViewer->slotShowNode(node);
00817 else
00818 {
00819 m_articleList->slotShowNode(node);
00820 m_articleViewer->slotShowSummary(node);
00821 }
00822
00823 if (node)
00824 m_mainFrame->setCaption(node->title());
00825
00826 m_actionManager->slotNodeSelected(node);
00827
00828 updateTagActions();
00829 }
00830
00831 void View::slotOpenURL(const KURL& url, Viewer* currentViewer, BrowserRun::OpeningMode mode)
00832 {
00833 if (mode == BrowserRun::EXTERNAL)
00834 Viewer::displayInExternalBrowser(url);
00835 else
00836 {
00837 KParts::URLArgs args = currentViewer ? currentViewer->browserExtension()->urlArgs() : KParts::URLArgs();
00838
00839 BrowserRun* r = new BrowserRun(this, currentViewer, url, args, mode);
00840 connect(r, SIGNAL(signalOpenInViewer(const KURL&, Akregator::Viewer*, Akregator::BrowserRun::OpeningMode)),
00841 this, SLOT(slotOpenURLReply(const KURL&, Akregator::Viewer*, Akregator::BrowserRun::OpeningMode)));
00842 }
00843 }
00844
00845
00846 void View::slotUrlClickedInViewer(const KURL& url, Viewer* viewer, bool newTab, bool background)
00847 {
00848
00849 if (!newTab)
00850 {
00851 slotOpenURL(url, viewer, BrowserRun::CURRENT_TAB);
00852 }
00853 else
00854 {
00855 slotOpenURL(url, 0L, background ? BrowserRun::NEW_TAB_BACKGROUND : BrowserRun::NEW_TAB_FOREGROUND);
00856 }
00857 }
00858
00859
00860 void View::slotOpenURLReply(const KURL& url, Viewer* currentViewer, BrowserRun::OpeningMode mode)
00861 {
00862 switch (mode)
00863 {
00864 case BrowserRun::CURRENT_TAB:
00865 currentViewer->openURL(url);
00866 break;
00867 case BrowserRun::NEW_TAB_FOREGROUND:
00868 case BrowserRun::NEW_TAB_BACKGROUND:
00869 slotOpenNewTab(url, mode == BrowserRun::NEW_TAB_BACKGROUND);
00870 break;
00871 case BrowserRun::EXTERNAL:
00872 Viewer::displayInExternalBrowser(url);
00873 break;
00874 }
00875 }
00876
00877 void View::slotFeedAdd()
00878 {
00879 Folder* group = 0;
00880 if (!m_feedListView->selectedNode())
00881 group = m_feedList->rootNode();
00882 else
00883 {
00884
00885 if ( m_feedListView->selectedNode()->isGroup())
00886 group = static_cast<Folder*>(m_feedListView->selectedNode());
00887 else
00888 group= m_feedListView->selectedNode()->parent();
00889
00890 }
00891
00892 TreeNode* lastChild = group->children().last();
00893
00894 addFeed(QString::null, lastChild, group, false);
00895 }
00896
00897 void View::addFeed(const QString& url, TreeNode *after, Folder* parent, bool autoExec)
00898 {
00899
00900 AddFeedDialog *afd = new AddFeedDialog( 0, "add_feed" );
00901
00902 afd->setURL(KURL::decode_string(url));
00903
00904 if (autoExec)
00905 afd->slotOk();
00906 else
00907 {
00908 if (afd->exec() != QDialog::Accepted)
00909 {
00910 delete afd;
00911 return;
00912 }
00913 }
00914
00915 Feed* feed = afd->feed;
00916 delete afd;
00917
00918 FeedPropertiesDialog *dlg = new FeedPropertiesDialog( 0, "edit_feed" );
00919 dlg->setFeed(feed);
00920
00921 dlg->selectFeedName();
00922
00923 if (!autoExec)
00924 if (dlg->exec() != QDialog::Accepted)
00925 {
00926 delete feed;
00927 delete dlg;
00928 return;
00929 }
00930
00931 if (!parent)
00932 parent = m_feedList->rootNode();
00933
00934 parent->insertChild(feed, after);
00935
00936 m_feedListView->ensureNodeVisible(feed);
00937
00938
00939 delete dlg;
00940 }
00941
00942 void View::slotFeedAddGroup()
00943 {
00944 TreeNode* node = m_feedListView->selectedNode();
00945 TreeNode* after = 0;
00946
00947 if (!node)
00948 node = m_feedListView->rootNode();
00949
00950
00951
00952 if (!node->isGroup())
00953 {
00954 after = node;
00955 node = node->parent();
00956 }
00957
00958 Folder* currentGroup = static_cast<Folder*> (node);
00959
00960 bool Ok;
00961
00962 QString text = KInputDialog::getText(i18n("Add Folder"), i18n("Folder name:"), "", &Ok);
00963
00964 if (Ok)
00965 {
00966 Folder* newGroup = new Folder(text);
00967 if (!after)
00968 currentGroup->appendChild(newGroup);
00969 else
00970 currentGroup->insertChild(newGroup, after);
00971
00972 m_feedListView->ensureNodeVisible(newGroup);
00973 }
00974 }
00975
00976 void View::slotFeedRemove()
00977 {
00978 TreeNode* selectedNode = m_listTabWidget->activeView()->selectedNode();
00979
00980
00981 if (!selectedNode || selectedNode == m_feedList->rootNode())
00982 return;
00983
00984 m_deleteNodeVisitor->visit(selectedNode);
00985 }
00986
00987 void View::slotFeedModify()
00988 {
00989 TreeNode* node = m_listTabWidget->activeView()->selectedNode();
00990 if (node)
00991 m_editNodePropertiesVisitor->visit(node);
00992
00993 }
00994
00995 void View::slotNextUnreadArticle()
00996 {
00997 if (m_viewMode == CombinedView)
00998 m_listTabWidget->activeView()->slotNextUnreadFeed();
00999
01000 TreeNode* sel = m_listTabWidget->activeView()->selectedNode();
01001 if (sel && sel->unread() > 0)
01002 m_articleList->slotNextUnreadArticle();
01003 else
01004 m_listTabWidget->activeView()->slotNextUnreadFeed();
01005 }
01006
01007 void View::slotPrevUnreadArticle()
01008 {
01009 if (m_viewMode == CombinedView)
01010 m_listTabWidget->activeView()->slotPrevUnreadFeed();
01011
01012 TreeNode* sel = m_listTabWidget->activeView()->selectedNode();
01013 if (sel && sel->unread() > 0)
01014 m_articleList->slotPreviousUnreadArticle();
01015 else
01016 m_listTabWidget->activeView()->slotPrevUnreadFeed();
01017 }
01018
01019 void View::slotMarkAllFeedsRead()
01020 {
01021 m_feedList->rootNode()->slotMarkAllArticlesAsRead();
01022 }
01023
01024 void View::slotMarkAllRead()
01025 {
01026 if(!m_listTabWidget->activeView()->selectedNode()) return;
01027 m_listTabWidget->activeView()->selectedNode()->slotMarkAllArticlesAsRead();
01028 }
01029
01030 void View::slotOpenHomepage()
01031 {
01032 Feed* feed = dynamic_cast<Feed *>(m_listTabWidget->activeView()->selectedNode());
01033
01034 if (!feed)
01035 return;
01036
01037 KURL url = KURL(feed->htmlUrl())
01038 ;
01039 switch (Settings::lMBBehaviour())
01040 {
01041 case Settings::EnumLMBBehaviour::OpenInExternalBrowser:
01042 slotOpenURL(url, 0, BrowserRun::EXTERNAL);
01043 break;
01044 case Settings::EnumLMBBehaviour::OpenInBackground:
01045 slotOpenURL(url, 0, BrowserRun::NEW_TAB_BACKGROUND);
01046 break;
01047 default:
01048 slotOpenURL(url, 0, BrowserRun::NEW_TAB_FOREGROUND);
01049 }
01050 }
01051
01052 void View::slotSetTotalUnread()
01053 {
01054 emit signalUnreadCountChanged( m_feedList->rootNode()->unread() );
01055 }
01056
01057 void View::slotDoIntervalFetches()
01058 {
01059 m_feedList->rootNode()->slotAddToFetchQueue(Kernel::self()->fetchQueue(), true);
01060 }
01061
01062 void View::slotFetchCurrentFeed()
01063 {
01064 if ( !m_listTabWidget->activeView()->selectedNode() )
01065 return;
01066 m_listTabWidget->activeView()->selectedNode()->slotAddToFetchQueue(Kernel::self()->fetchQueue());
01067 }
01068
01069 void View::slotFetchAllFeeds()
01070 {
01071 m_feedList->rootNode()->slotAddToFetchQueue(Kernel::self()->fetchQueue());
01072 }
01073
01074 void View::slotFetchingStarted()
01075 {
01076 m_mainFrame->setState(Frame::Started);
01077 m_actionManager->action("feed_stop")->setEnabled(true);
01078 m_mainFrame->setStatusText(i18n("Fetching Feeds..."));
01079 }
01080
01081 void View::slotFetchingStopped()
01082 {
01083 m_mainFrame->setState(Frame::Completed);
01084 m_actionManager->action("feed_stop")->setEnabled(false);
01085 m_mainFrame->setStatusText(QString::null);
01086 }
01087
01088 void View::slotFeedFetched(Feed *feed)
01089 {
01090
01091 if (feed->articles().count() > 0)
01092 {
01093 QValueList<Article> articles = feed->articles();
01094 QValueList<Article>::ConstIterator it;
01095 QValueList<Article>::ConstIterator end = articles.end();
01096 for (it = articles.begin(); it != end; ++it)
01097 {
01098 if ((*it).status()==Article::New && ((*it).feed()->useNotification() || Settings::useNotifications()))
01099 {
01100 NotificationManager::self()->slotNotifyArticle(*it);
01101 }
01102 }
01103 }
01104 }
01105
01106 void View::slotMouseButtonPressed(int button, const Article& article, const QPoint &, int)
01107 {
01108 if (button == Qt::MidButton)
01109 {
01110 KURL link = article.link();
01111 switch (Settings::mMBBehaviour())
01112 {
01113 case Settings::EnumMMBBehaviour::OpenInExternalBrowser:
01114 slotOpenURL(link, 0L, BrowserRun::EXTERNAL);
01115 break;
01116 case Settings::EnumMMBBehaviour::OpenInBackground:
01117 slotOpenURL(link, 0L, BrowserRun::NEW_TAB_BACKGROUND);
01118 break;
01119 default:
01120 slotOpenURL(link, 0L, BrowserRun::NEW_TAB_FOREGROUND);
01121 }
01122 }
01123 }
01124
01125 void View::slotAssignTag(const Tag& tag, bool assign)
01126 {
01127 kdDebug() << (assign ? "assigned" : "removed") << " tag \"" << tag.id() << "\"" << endl;
01128 QValueList<Article> selectedArticles = m_articleList->selectedArticles();
01129 for (QValueList<Article>::Iterator it = selectedArticles.begin(); it != selectedArticles.end(); ++it)
01130 {
01131 if (assign)
01132 (*it).addTag(tag.id());
01133 else
01134 (*it).removeTag(tag.id());
01135 }
01136 updateTagActions();
01137 }
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147
01148
01149 void View::slotNewTag()
01150 {
01151 Tag tag(KApplication::randomString(8), "New Tag");
01152 Kernel::self()->tagSet()->insert(tag);
01153 TagNode* node = m_tagNodeList->findByTagID(tag.id());
01154 if (node)
01155 m_tagNodeListView->startNodeRenaming(node);
01156 }
01157
01158 void View::slotTagCreated(const Tag& tag)
01159 {
01160 if (m_tagNodeList && !m_tagNodeList->containsTagId(tag.id()))
01161 {
01162 TagNode* tagNode = new TagNode(tag, m_feedList->rootNode());
01163 m_tagNodeList->rootNode()->appendChild(tagNode);
01164 }
01165 }
01166
01167 void View::slotTagRemoved(const Tag& )
01168 {
01169 }
01170
01171 void View::slotArticleSelected(const Article& article)
01172 {
01173 if (m_viewMode == CombinedView)
01174 return;
01175
01176 m_markReadTimer->stop();
01177
01178 Feed *feed = article.feed();
01179 if (!feed)
01180 return;
01181
01182 Article a(article);
01183 if (a.status() != Article::Read)
01184 {
01185 int delay;
01186
01187 if ( Settings::useMarkReadDelay() )
01188 {
01189 delay = Settings::markReadDelay();
01190
01191 if (delay > 0)
01192 m_markReadTimer->start( delay*1000, true );
01193 else
01194 a.setStatus(Article::Read);
01195 }
01196 }
01197
01198 KToggleAction* maai = dynamic_cast<KToggleAction*>(m_actionManager->action("article_set_status_important"));
01199 maai->setChecked(a.keep());
01200
01201 kdDebug() << "selected: " << a.guid() << endl;
01202
01203 updateTagActions();
01204
01205 m_articleViewer->slotShowArticle(a);
01206 }
01207
01208 void View::slotOpenArticleExternal(const Article& article, const QPoint&, int)
01209 {
01210 if (!article.isNull())
01211 Viewer::displayInExternalBrowser(article.link());
01212 }
01213
01214
01215 void View::slotOpenCurrentArticle()
01216 {
01217 Article article = m_articleList->currentArticle();
01218
01219 if (article.isNull())
01220 return;
01221
01222 KURL link;
01223 if (article.link().isValid())
01224 link = article.link();
01225 else if (article.guidIsPermaLink())
01226 link = KURL(article.guid());
01227
01228 if (link.isValid())
01229 {
01230 slotOpenURL(link, 0L, BrowserRun::NEW_TAB_FOREGROUND);
01231 }
01232 }
01233
01234 void View::slotOpenCurrentArticleExternal()
01235 {
01236 slotOpenArticleExternal(m_articleList->currentArticle(), QPoint(), 0);
01237 }
01238
01239 void View::slotOpenCurrentArticleBackgroundTab()
01240 {
01241 Article article = m_articleList->currentArticle();
01242
01243 if (article.isNull())
01244 return;
01245
01246 KURL link;
01247
01248 if (article.link().isValid())
01249 link = article.link();
01250 else if (article.guidIsPermaLink())
01251 link = KURL(article.guid());
01252
01253 if (link.isValid())
01254 {
01255 slotOpenURL(link, 0L, BrowserRun::NEW_TAB_BACKGROUND);
01256 }
01257 }
01258
01259 void View::slotCopyLinkAddress()
01260 {
01261 Article article = m_articleList->currentArticle();
01262
01263 if(article.isNull())
01264 return;
01265
01266 QString link;
01267 if (article.link().isValid() || (article.guidIsPermaLink() && KURL(article.guid()).isValid()))
01268 {
01269
01270 if (article.link().isValid())
01271 link = article.link().url();
01272 else
01273 link = article.guid();
01274 QClipboard *cb = QApplication::clipboard();
01275 cb->setText(link, QClipboard::Clipboard);
01276 cb->setText(link, QClipboard::Selection);
01277 }
01278 }
01279
01280 void View::slotFeedURLDropped(KURL::List &urls, TreeNode* after, Folder* parent)
01281 {
01282 KURL::List::iterator it;
01283 for ( it = urls.begin(); it != urls.end(); ++it )
01284 {
01285 addFeed((*it).prettyURL(), after, parent, false);
01286 }
01287 }
01288
01289 void View::slotToggleShowQuickFilter()
01290 {
01291 if ( Settings::showQuickFilter() )
01292 {
01293 Settings::setShowQuickFilter(false);
01294 m_searchBar->slotClearSearch();
01295 m_searchBar->hide();
01296 }
01297 else
01298 {
01299 Settings::setShowQuickFilter(true);
01300 if (!m_displayingAboutPage)
01301 m_searchBar->show();
01302 }
01303
01304 }
01305
01306 void View::slotArticleDelete()
01307 {
01308
01309 if ( m_viewMode == CombinedView )
01310 return;
01311
01312 QValueList<Article> articles = m_articleList->selectedArticles();
01313
01314 QString msg;
01315 switch (articles.count())
01316 {
01317 case 0:
01318 return;
01319 case 1:
01320 msg = i18n("<qt>Are you sure you want to delete article <b>%1</b>?</qt>").arg(QStyleSheet::escape(articles.first().title()));
01321 break;
01322 default:
01323 msg = i18n("<qt>Are you sure you want to delete the selected article?</qt>",
01324 "<qt>Are you sure you want to delete the %n selected articles?</qt>",
01325 articles.count());
01326 }
01327
01328 if (KMessageBox::warningContinueCancel(0, msg, i18n("Delete Article"), KStdGuiItem::del()) == KMessageBox::Continue)
01329 {
01330 if (m_listTabWidget->activeView()->selectedNode())
01331 m_listTabWidget->activeView()->selectedNode()->setNotificationMode(false);
01332
01333 QValueList<Feed*> feeds;
01334 for (QValueList<Article>::Iterator it = articles.begin(); it != articles.end(); ++it)
01335 {
01336 Feed* feed = (*it).feed();
01337 if (!feeds.contains(feed))
01338 feeds.append(feed);
01339 feed->setNotificationMode(false);
01340 (*it).setDeleted();
01341 }
01342
01343 for (QValueList<Feed*>::Iterator it = feeds.begin(); it != feeds.end(); ++it)
01344 {
01345 (*it)->setNotificationMode(true);
01346 }
01347
01348 if (m_listTabWidget->activeView()->selectedNode())
01349 m_listTabWidget->activeView()->selectedNode()->setNotificationMode(true);
01350 }
01351 }
01352
01353
01354 void View::slotArticleToggleKeepFlag(bool )
01355 {
01356 QValueList<Article> articles = m_articleList->selectedArticles();
01357
01358 if (articles.isEmpty())
01359 return;
01360
01361 bool allFlagsSet = true;
01362 for (QValueList<Article>::Iterator it = articles.begin(); allFlagsSet && it != articles.end(); ++it)
01363 if (!(*it).keep())
01364 allFlagsSet = false;
01365
01366 for (QValueList<Article>::Iterator it = articles.begin(); it != articles.end(); ++it)
01367 (*it).setKeep(!allFlagsSet);
01368 }
01369
01370 void View::slotSetSelectedArticleRead()
01371 {
01372 QValueList<Article> articles = m_articleList->selectedArticles();
01373
01374 if (articles.isEmpty())
01375 return;
01376
01377 for (QValueList<Article>::Iterator it = articles.begin(); it != articles.end(); ++it)
01378 (*it).setStatus(Article::Read);
01379 }
01380
01381 void View::slotTextToSpeechRequest()
01382 {
01383 if (m_currentFrame == m_mainFrame)
01384 {
01385 if (m_viewMode != CombinedView)
01386 {
01387
01388 SpeechClient::self()->slotSpeak(m_articleList->selectedArticles());
01389
01390 }
01391 else
01392 {
01393 if (m_listTabWidget->activeView()->selectedNode())
01394 {
01395
01396 }
01397 }
01398 }
01399 else
01400 {
01401 QString selectedText = static_cast<PageViewer *>(m_currentFrame->part())->selectedText();
01402
01403 if (!selectedText.isEmpty())
01404 SpeechClient::self()->slotSpeak(selectedText, "en");
01405 }
01406 }
01407
01408 void View::slotSetSelectedArticleUnread()
01409 {
01410 QValueList<Article> articles = m_articleList->selectedArticles();
01411
01412 if (articles.isEmpty())
01413 return;
01414
01415 for (QValueList<Article>::Iterator it = articles.begin(); it != articles.end(); ++it)
01416 (*it).setStatus(Article::Unread);
01417 }
01418
01419 void View::slotSetSelectedArticleNew()
01420 {
01421 QValueList<Article> articles = m_articleList->selectedArticles();
01422
01423 if (articles.isEmpty())
01424 return;
01425
01426 for (QValueList<Article>::Iterator it = articles.begin(); it != articles.end(); ++it)
01427 (*it).setStatus(Article::New);
01428 }
01429
01430 void View::slotSetCurrentArticleReadDelayed()
01431 {
01432 Article article = m_articleList->currentArticle();
01433
01434 if (article.isNull())
01435 return;
01436
01437 article.setStatus(Article::Read);
01438 }
01439
01440 void View::slotMouseOverInfo(const KFileItem *kifi)
01441 {
01442 if (kifi)
01443 {
01444 KFileItem *k=(KFileItem*)kifi;
01445 m_mainFrame->setStatusText(k->url().prettyURL());
01446 }
01447 else
01448 {
01449 m_mainFrame->setStatusText(QString::null);
01450 }
01451 }
01452
01453 void View::readProperties(KConfig* config)
01454 {
01455
01456 if (!Settings::resetQuickFilterOnNodeChange())
01457 {
01458 m_searchBar->slotSetText(config->readEntry("searchLine"));
01459 int statusfilter = config->readNumEntry("searchCombo", -1);
01460 if (statusfilter != -1)
01461 m_searchBar->slotSetStatus(statusfilter);
01462 }
01463
01464 int selectedID = config->readNumEntry("selectedNodeID", -1);
01465 if (selectedID != -1)
01466 {
01467 TreeNode* selNode = m_feedList->findByID(selectedID);
01468 if (selNode)
01469 m_listTabWidget->activeView()->setSelectedNode(selNode);
01470 }
01471
01472 QStringList urls = config->readListEntry("FeedBrowserURLs");
01473 QStringList::ConstIterator it = urls.begin();
01474 for (; it != urls.end(); ++it)
01475 {
01476 KURL url = KURL::fromPathOrURL(*it);
01477 if (url.isValid())
01478 slotOpenNewTab(url, true);
01479 }
01480 }
01481
01482 void View::saveProperties(KConfig* config)
01483 {
01484
01485 config->writeEntry("searchLine", m_searchBar->text());
01486 config->writeEntry("searchCombo", m_searchBar->status());
01487
01488 TreeNode* sel = m_listTabWidget->activeView()->selectedNode();
01489
01490 if (sel)
01491 {
01492 config->writeEntry("selectedNodeID", sel->id() );
01493 }
01494
01495
01496 QStringList urls;
01497 QPtrList<Frame> frames = m_tabs->frames();
01498 QPtrList<Frame>::ConstIterator it = frames.begin();
01499 for (; it != frames.end(); ++it)
01500 {
01501 Frame *frame = *it;
01502 KParts::ReadOnlyPart *part = frame->part();
01503 PageViewer *pageViewer = dynamic_cast<PageViewer*>(part);
01504 if (pageViewer)
01505 {
01506 KURL url = pageViewer->url();
01507 if (url.isValid())
01508 urls.append(url.prettyURL());
01509 }
01510 }
01511
01512 config->writeEntry("FeedBrowserURLs", urls);
01513 }
01514
01515 void View::connectToFeedList(FeedList* feedList)
01516 {
01517 connect(feedList->rootNode(), SIGNAL(signalChanged(TreeNode*)), this, SLOT(slotSetTotalUnread()));
01518 slotSetTotalUnread();
01519 }
01520
01521 void View::disconnectFromFeedList(FeedList* feedList)
01522 {
01523 disconnect(feedList->rootNode(), SIGNAL(signalChanged(TreeNode*)), this, SLOT(slotSetTotalUnread()));
01524 }
01525
01526 void View::updateTagActions()
01527 {
01528 QStringList tags;
01529
01530 QValueList<Article> selectedArticles = m_articleList->selectedArticles();
01531
01532 for (QValueList<Article>::ConstIterator it = selectedArticles.begin(); it != selectedArticles.end(); ++it)
01533 {
01534 QStringList atags = (*it).tags();
01535 for (QStringList::ConstIterator it2 = atags.begin(); it2 != atags.end(); ++it2)
01536 {
01537 if (!tags.contains(*it2))
01538 tags += *it2;
01539 }
01540 }
01541 m_actionManager->slotUpdateTagActions(!selectedArticles.isEmpty(), tags);
01542 }
01543
01544 }
01545
01546 #include "akregator_view.moc"