• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdepim API Reference
  • KDE Home
  • Contact Us
 

akregator

  • sources
  • kde-4.14
  • kdepim
  • akregator
  • src
selectioncontroller.cpp
Go to the documentation of this file.
1 /*
2  This file is part of Akregator.
3 
4  Copyright (C) 2007 Frank Osterfeld <osterfeld@kde.org>
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program; if not, write to the Free Software
18  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 
20  As a special exception, permission is given to link this program
21  with any edition of Qt, and distribute the resulting executable,
22  without including the source code for Qt in the source distribution.
23 */
24 
25 #include "selectioncontroller.h"
26 
27 #include "actionmanager.h"
28 #include "article.h"
29 #include "articlejobs.h"
30 #include "articlemodel.h"
31 #include "feedlist.h"
32 #include "subscriptionlistmodel.h"
33 #include "treenode.h"
34 
35 #include <KDebug>
36 
37 #include <QAbstractItemView>
38 #include <QMenu>
39 
40 using namespace boost;
41 using namespace Akregator;
42 
43 namespace {
44  static Akregator::Article articleForIndex( const QModelIndex& index, FeedList* feedList )
45  {
46  if ( !index.isValid() )
47  return Akregator::Article();
48 
49  const QString guid = index.data( ArticleModel::GuidRole ).toString();
50  const QString feedId = index.data( ArticleModel::FeedIdRole ).toString();
51  return feedList->findArticle( feedId, guid );
52  }
53 
54  static QList<Akregator::Article> articlesForIndexes( const QModelIndexList& indexes, FeedList* feedList )
55  {
56  QList<Akregator::Article> articles;
57  Q_FOREACH ( const QModelIndex& i, indexes )
58  {
59  const Article a = articleForIndex( i, feedList );
60  if ( a.isNull() )
61  continue;
62  articles.append( articleForIndex( i, feedList ) );
63  }
64 
65  return articles;
66  }
67 
68  static Akregator::TreeNode* subscriptionForIndex( const QModelIndex& index, Akregator::FeedList* feedList )
69  {
70  if ( !index.isValid() )
71  return 0L;
72 
73  return feedList->findByID( index.data( Akregator::SubscriptionListModel::SubscriptionIdRole ).toInt() );
74  }
75 } // anon namespace
76 
77 Akregator::SelectionController::SelectionController( QObject* parent )
78  : AbstractSelectionController( parent ),
79  m_feedList(),
80  m_feedSelector(),
81  m_articleLister( 0 ),
82  m_singleDisplay( 0 ),
83  m_subscriptionModel ( new SubscriptionListModel( shared_ptr<FeedList>(), this ) ),
84  m_folderExpansionHandler( 0 ),
85  m_articleModel( 0 ),
86  m_selectedSubscription()
87 {
88 }
89 
90 Akregator::SelectionController::~SelectionController()
91 {
92  delete m_articleModel;
93 }
94 
95 
96 void Akregator::SelectionController::setFeedSelector( QAbstractItemView* feedSelector )
97 {
98  if ( m_feedSelector == feedSelector )
99  return;
100 
101  if ( m_feedSelector ) {
102  m_feedSelector->disconnect( this );
103  m_feedSelector->selectionModel()->disconnect( this );
104  }
105 
106  m_feedSelector = feedSelector;
107 
108  if ( !m_feedSelector )
109  return;
110 
111  m_feedSelector->setModel( m_subscriptionModel );
112 
113  connect( m_feedSelector, SIGNAL(customContextMenuRequested(QPoint)),
114  this, SLOT(subscriptionContextMenuRequested(QPoint)) );
115  connect( m_feedSelector->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)),
116  this, SLOT(selectedSubscriptionChanged(QModelIndex)) );
117  connect( m_feedSelector, SIGNAL(activated(QModelIndex)),
118  this, SLOT(selectedSubscriptionChanged(QModelIndex)) );
119 
120 }
121 
122 void Akregator::SelectionController::setArticleLister( Akregator::ArticleLister* lister )
123 {
124  if ( m_articleLister == lister )
125  return;
126 
127  if ( m_articleLister )
128  m_articleLister->articleSelectionModel()->disconnect( this );
129  if ( m_articleLister && m_articleLister->itemView() )
130  m_articleLister->itemView()->disconnect( this );
131 
132  m_articleLister = lister;
133 
134  if ( m_articleLister && m_articleLister->itemView() )
135  connect( m_articleLister->itemView(), SIGNAL(doubleClicked(QModelIndex)),
136  this, SLOT(articleIndexDoubleClicked(QModelIndex)) );
137 }
138 
139 void Akregator::SelectionController::setSingleArticleDisplay( Akregator::SingleArticleDisplay* display )
140 {
141  m_singleDisplay = display;
142 }
143 
144 Akregator::Article Akregator::SelectionController::currentArticle() const
145 {
146  if ( !m_articleLister || !m_articleLister->articleSelectionModel() )
147  return Article();
148  return ::articleForIndex( m_articleLister->articleSelectionModel()->currentIndex(), m_feedList.get() );
149 }
150 
151 QModelIndex SelectionController::currentArticleIndex() const
152 {
153  return m_articleLister->articleSelectionModel()->currentIndex();
154 }
155 
156 QList<Akregator::Article> Akregator::SelectionController::selectedArticles() const
157 {
158  if ( !m_articleLister || !m_articleLister->articleSelectionModel() )
159  return QList<Akregator::Article>();
160  return ::articlesForIndexes( m_articleLister->articleSelectionModel()->selectedRows(), m_feedList.get() );
161 }
162 
163 Akregator::TreeNode* Akregator::SelectionController::selectedSubscription() const
164 {
165  return ::subscriptionForIndex( m_feedSelector->selectionModel()->currentIndex(), m_feedList.get() );
166 }
167 
168 void Akregator::SelectionController::setFeedList( const shared_ptr<FeedList>& list )
169 {
170  if ( m_feedList == list )
171  return;
172 
173  m_feedList = list;
174  std::auto_ptr<SubscriptionListModel> oldModel( m_subscriptionModel );
175  m_subscriptionModel = new SubscriptionListModel( m_feedList, this );
176 
177  if ( m_folderExpansionHandler ) {
178  m_folderExpansionHandler->setFeedList( m_feedList );
179  m_folderExpansionHandler->setModel( m_subscriptionModel );
180  }
181 
182  if ( m_feedSelector ) {
183  m_feedSelector->setModel( m_subscriptionModel );
184  disconnect( m_feedSelector->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)),
185  this, SLOT(selectedSubscriptionChanged(QModelIndex)) );
186  connect( m_feedSelector->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)),
187  this, SLOT(selectedSubscriptionChanged(QModelIndex)) );
188  }
189 }
190 
191 void Akregator::SelectionController::setFolderExpansionHandler( Akregator::FolderExpansionHandler* handler )
192 {
193  if ( handler == m_folderExpansionHandler )
194  return;
195  m_folderExpansionHandler = handler;
196  if ( !m_folderExpansionHandler )
197  return;
198  handler->setFeedList( m_feedList );
199  handler->setModel( m_subscriptionModel );
200 }
201 
202 void Akregator::SelectionController::articleHeadersAvailable( KJob* job )
203 {
204  assert( job );
205  assert( job == m_listJob );
206 
207 
208  if ( job->error() ) {
209  kWarning() << job->errorText();
210  return;
211  }
212  TreeNode* const node = m_listJob->node();
213 
214  assert( node ); // if there was no error, the node must still exist
215  assert( node == m_selectedSubscription ); //...and equal the previously selected node
216 
217  ArticleModel* const newModel = new ArticleModel( m_listJob->articles() );
218 
219  connect( node, SIGNAL(destroyed()),
220  newModel, SLOT(clear()) );
221  connect( node, SIGNAL(signalArticlesAdded(Akregator::TreeNode*,QList<Akregator::Article>)),
222  newModel, SLOT(articlesAdded(Akregator::TreeNode*,QList<Akregator::Article>)) );
223  connect( node, SIGNAL(signalArticlesRemoved(Akregator::TreeNode*,QList<Akregator::Article>)),
224  newModel, SLOT(articlesRemoved(Akregator::TreeNode*,QList<Akregator::Article>)) );
225  connect( node, SIGNAL(signalArticlesUpdated(Akregator::TreeNode*,QList<Akregator::Article>)),
226  newModel, SLOT(articlesUpdated(Akregator::TreeNode*,QList<Akregator::Article>)) );
227 
228  m_articleLister->setIsAggregation( node->isAggregation() );
229  m_articleLister->setArticleModel( newModel );
230  delete m_articleModel; //order is important: do not delete the old model before the new model is set in the view
231  m_articleModel = newModel;
232 
233  disconnect( m_articleLister->articleSelectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
234  this, SLOT(articleSelectionChanged()) );
235  connect( m_articleLister->articleSelectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
236  this, SLOT(articleSelectionChanged()) );
237 
238  if ( node )
239  m_articleLister->setScrollBarPositions( node->listViewScrollBarPositions() );
240 }
241 
242 
243 void Akregator::SelectionController::selectedSubscriptionChanged( const QModelIndex& index )
244 {
245  if ( !index.isValid() )
246  return;
247 
248  if ( m_selectedSubscription && m_articleLister )
249  m_selectedSubscription->setListViewScrollBarPositions( m_articleLister->scrollBarPositions() );
250 
251  m_selectedSubscription = selectedSubscription();
252  emit currentSubscriptionChanged( m_selectedSubscription );
253 
254  // using a timer here internally to simulate async data fetching (which is still synchronous),
255  // to ensure the UI copes with async behavior later on
256 
257  if ( m_listJob ) {
258  m_listJob->disconnect( this ); //Ignore if ~KJob() emits finished()
259  delete m_listJob;
260  }
261 
262  if ( !m_selectedSubscription )
263  return;
264 
265  ArticleListJob* const job( new ArticleListJob( m_selectedSubscription ) );
266  connect( job, SIGNAL(finished(KJob*)),
267  this, SLOT(articleHeadersAvailable(KJob*)) );
268  m_listJob = job;
269  m_listJob->start();
270 
271 }
272 
273 void Akregator::SelectionController::subscriptionContextMenuRequested( const QPoint& point )
274 {
275  Q_ASSERT( m_feedSelector );
276  const TreeNode* const node = ::subscriptionForIndex( m_feedSelector->indexAt( point ), m_feedList.get() );
277  if ( !node )
278  return;
279 
280  QWidget* w = ActionManager::getInstance()->container( node->isGroup() ? "feedgroup_popup" : "feeds_popup" );
281  QMenu* popup = qobject_cast<QMenu*>( w );
282  if ( popup )
283  {
284  const QPoint globalPos = m_feedSelector->viewport()->mapToGlobal( point );
285  popup->exec( globalPos );
286  }
287 }
288 
289 void Akregator::SelectionController::articleSelectionChanged()
290 {
291  const Akregator::Article article = currentArticle();
292  if ( m_singleDisplay )
293  m_singleDisplay->showArticle( article );
294  emit currentArticleChanged( article );
295 }
296 
297 void Akregator::SelectionController::articleIndexDoubleClicked( const QModelIndex& index )
298 {
299  const Akregator::Article article = ::articleForIndex( index, m_feedList.get() );
300  emit articleDoubleClicked( article );
301 }
302 
303 void SelectionController::setFilters( const std::vector<boost::shared_ptr<const Filters::AbstractMatcher> >& matchers )
304 {
305  Q_ASSERT( m_articleLister );
306  m_articleLister->setFilters( matchers );
307 }
308 
309 void SelectionController::forceFilterUpdate()
310 {
311  Q_ASSERT( m_articleLister );
312  m_articleLister->forceFilterUpdate();
313 }
314 
treenode.h
Akregator::SelectionController::SelectionController
SelectionController(QObject *parent=0)
Definition: selectioncontroller.cpp:77
QModelIndex
QWidget
QAbstractItemView
QItemSelectionModel::currentIndex
QModelIndex currentIndex() const
feedlist.h
Akregator::SelectionController::setFilters
void setFilters(const std::vector< boost::shared_ptr< const Akregator::Filters::AbstractMatcher > > &)
Definition: selectioncontroller.cpp:303
Akregator::SingleArticleDisplay
Definition: abstractselectioncontroller.h:77
Akregator::SelectionController::forceFilterUpdate
void forceFilterUpdate()
Definition: selectioncontroller.cpp:309
Akregator::ArticleLister::forceFilterUpdate
virtual void forceFilterUpdate()=0
QAbstractItemView::setModel
virtual void setModel(QAbstractItemModel *model)
Akregator::SelectionController::~SelectionController
~SelectionController()
Definition: selectioncontroller.cpp:90
articlejobs.h
Akregator::SelectionController::selectedSubscription
Akregator::TreeNode * selectedSubscription() const
Definition: selectioncontroller.cpp:163
Akregator::TreeNode::isAggregation
virtual bool isAggregation() const =0
returns if the node represents an aggregation, i.e.
Akregator::SubscriptionListModel::SubscriptionIdRole
Definition: subscriptionlistmodel.h:48
Akregator::FeedList::findArticle
const Article findArticle(const QString &feedURL, const QString &guid) const
Definition: feedlist.cpp:337
Akregator::FolderExpansionHandler
Definition: subscriptionlistmodel.h:135
Akregator::ArticleLister::articleSelectionModel
virtual QItemSelectionModel * articleSelectionModel() const =0
Akregator::SubscriptionListModel
Definition: subscriptionlistmodel.h:42
QPoint
actionmanager.h
Akregator::AbstractSelectionController
Definition: abstractselectioncontroller.h:94
Akregator::FeedList
The model of a feed tree, represents an OPML document.
Definition: feedlist.h:78
QModelIndex::isValid
bool isValid() const
Akregator::Article::isNull
bool isNull() const
Definition: article.cpp:253
QList::append
void append(const T &value)
Akregator::SelectionController::setFolderExpansionHandler
void setFolderExpansionHandler(Akregator::FolderExpansionHandler *handler)
Definition: selectioncontroller.cpp:191
QVariant::toInt
int toInt(bool *ok) const
Akregator::ArticleListJob
Definition: articlejobs.h:110
QObject
Akregator::SelectionController::setArticleLister
void setArticleLister(Akregator::ArticleLister *lister)
Definition: selectioncontroller.cpp:122
Akregator::ActionManager::container
virtual QWidget * container(const char *name)=0
QString
QList< Akregator::Article >
article.h
Akregator::FolderExpansionHandler::setFeedList
void setFeedList(const boost::shared_ptr< FeedList > &feedList)
Definition: subscriptionlistmodel.cpp:361
Akregator::SelectionController::currentArticle
Akregator::Article currentArticle() const
Definition: selectioncontroller.cpp:144
QMenu::exec
QAction * exec()
Akregator::FolderExpansionHandler::setModel
void setModel(Akregator::SubscriptionListModel *model)
Definition: subscriptionlistmodel.cpp:356
Akregator::ArticleLister
Definition: abstractselectioncontroller.h:52
Akregator::FeedList::findByID
const TreeNode * findByID(int id) const
Definition: feedlist.cpp:386
QMenu
Akregator::SelectionController::currentArticleIndex
QModelIndex currentArticleIndex() const
Definition: selectioncontroller.cpp:151
selectioncontroller.h
Akregator::TreeNode::listViewScrollBarPositions
QPoint listViewScrollBarPositions() const
Definition: treenode.cpp:228
QItemSelection
QModelIndex::data
QVariant data(int role) const
Akregator::ActionManager::getInstance
static ActionManager * getInstance()
Definition: actionmanager.cpp:35
Akregator::TreeNode::isGroup
virtual bool isGroup() const =0
Helps the rest of the app to decide if node should be handled as group or not.
articlemodel.h
Akregator::Article
A proxy class for Syndication::ItemPtr with some additional methods to assist sorting.
Definition: article.h:63
Akregator::SelectionController::selectedArticles
QList< Akregator::Article > selectedArticles() const
Definition: selectioncontroller.cpp:156
Akregator::SelectionController::setFeedList
void setFeedList(const boost::shared_ptr< FeedList > &list)
Definition: selectioncontroller.cpp:168
Akregator::SelectionController::setSingleArticleDisplay
void setSingleArticleDisplay(Akregator::SingleArticleDisplay *display)
Definition: selectioncontroller.cpp:139
Akregator::SelectionController::setFeedSelector
void setFeedSelector(QAbstractItemView *feedSelector)
Definition: selectioncontroller.cpp:96
subscriptionlistmodel.h
Akregator::TreeNode
Abstract base class for all kind of elements in the feed tree, like feeds and feed groups (and search...
Definition: treenode.h:58
QVariant::toString
QString toString() const
KJob
Akregator::ArticleLister::setFilters
virtual void setFilters(const std::vector< boost::shared_ptr< const Filters::AbstractMatcher > > &)=0
Akregator::ArticleModel
Definition: articlemodel.h:46
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:34:00 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

akregator

Skip menu "akregator"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members

kdepim API Reference

Skip menu "kdepim API Reference"
  • akonadi_next
  • akregator
  • blogilo
  • calendarsupport
  • console
  •   kabcclient
  •   konsolekalendar
  • kaddressbook
  • kalarm
  •   lib
  • kdgantt2
  • kjots
  • kleopatra
  • kmail
  • knode
  • knotes
  • kontact
  • korgac
  • korganizer
  • ktimetracker
  • libkdepim
  • libkleo
  • libkpgp
  • mailcommon
  • messagelist
  • messageviewer
  • pimprint

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal