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