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

kleopatra

  • sources
  • kde-4.12
  • kdepim
  • kleopatra
  • view
keytreeview.cpp
Go to the documentation of this file.
1 /* -*- mode: c++; c-basic-offset:4 -*-
2  view/keytreeview.cpp
3 
4  This file is part of Kleopatra, the KDE keymanager
5  Copyright (c) 2009 Klarälvdalens Datakonsult AB
6 
7  Kleopatra is free software; you can redistribute it and/or modify
8  it under the terms of the GNU General Public License as published by
9  the Free Software Foundation; either version 2 of the License, or
10  (at your option) any later version.
11 
12  Kleopatra is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 
21  In addition, as a special exception, the copyright holders give
22  permission to link the code of this program with any edition of
23  the Qt library by Trolltech AS, Norway (or with modified versions
24  of Qt that use the same license as Qt), and distribute linked
25  combinations including the two. You must obey the GNU General
26  Public License in all respects for all of the code used other than
27  Qt. If you modify this file, you may extend this exception to
28  your version of the file, but you are not obligated to do so. If
29  you do not wish to do so, delete this exception statement from
30  your version.
31 */
32 
33 #include <config-kleopatra.h>
34 
35 #include "keytreeview.h"
36 
37 #include <models/keylistmodel.h>
38 #include <models/keylistsortfilterproxymodel.h>
39 #include <models/predicates.h>
40 
41 #include <utils/headerview.h>
42 
43 #include <kleo/stl_util.h>
44 #include <kleo/keyfilter.h>
45 
46 #include <KDebug>
47 
48 #include <QTreeView>
49 #include <QHeaderView>
50 #include <QItemSelectionModel>
51 #include <QItemSelection>
52 #include <QLayout>
53 
54 #include <cassert>
55 
56 using namespace Kleo;
57 using namespace boost;
58 using namespace GpgME;
59 
60 namespace {
61 
62 class TreeView : public QTreeView {
63 public:
64  explicit TreeView( QWidget * parent=0 ) : QTreeView( parent ) {}
65 
66  /* reimp */ QSize minimumSizeHint() const {
67  const QSize min = QTreeView::minimumSizeHint();
68  return QSize( min.width(), min.height() + 5 * fontMetrics().height() );
69  }
70 };
71 
72 } // anon namespace
73 
74 KeyTreeView::KeyTreeView( QWidget * parent )
75  : QWidget( parent ),
76  m_proxy( new KeyListSortFilterProxyModel( this ) ),
77  m_additionalProxy( 0 ),
78  m_view( new TreeView( this ) ),
79  m_flatModel( 0 ),
80  m_hierarchicalModel( 0 ),
81  m_stringFilter(),
82  m_keyFilter(),
83  m_isHierarchical( true )
84 {
85  init();
86 }
87 
88 
89 KeyTreeView::KeyTreeView( const KeyTreeView & other )
90  : QWidget( 0 ),
91  m_proxy( new KeyListSortFilterProxyModel( this ) ),
92  m_additionalProxy( other.m_additionalProxy ? other.m_additionalProxy->clone() : 0 ),
93  m_view( new TreeView( this ) ),
94  m_flatModel( other.m_flatModel ),
95  m_hierarchicalModel( other.m_hierarchicalModel ),
96  m_stringFilter( other.m_stringFilter ),
97  m_keyFilter( other.m_keyFilter ),
98  m_isHierarchical( other.m_isHierarchical )
99 {
100  init();
101  setColumnSizes( other.columnSizes() );
102  setSortColumn( other.sortColumn(), other.sortOrder() );
103 }
104 
105 KeyTreeView::KeyTreeView( const QString & text, const shared_ptr<KeyFilter> & kf, AbstractKeyListSortFilterProxyModel * proxy, QWidget * parent )
106  : QWidget( parent ),
107  m_proxy( new KeyListSortFilterProxyModel( this ) ),
108  m_additionalProxy( proxy ),
109  m_view( new TreeView( this ) ),
110  m_flatModel( 0 ),
111  m_hierarchicalModel( 0 ),
112  m_stringFilter( text ),
113  m_keyFilter( kf ),
114  m_isHierarchical( true )
115 {
116  init();
117 }
118 
119 void KeyTreeView::setColumnSizes( const std::vector<int> & sizes ) {
120  if ( sizes.empty() )
121  return;
122  assert( m_view );
123  assert( m_view->header() );
124  assert( qobject_cast<HeaderView*>( m_view->header() ) == static_cast<HeaderView*>( m_view->header() ) );
125  if ( HeaderView * const hv = static_cast<HeaderView*>( m_view->header() ) )
126  hv->setSectionSizes( sizes );
127 }
128 
129 void KeyTreeView::setSortColumn( int sortColumn, Qt::SortOrder sortOrder ) {
130  assert( m_view );
131  m_view->sortByColumn( sortColumn, sortOrder );
132 }
133 
134 int KeyTreeView::sortColumn() const {
135  assert( m_view );
136  assert( m_view->header() );
137  return m_view->header()->sortIndicatorSection();
138 }
139 
140 Qt::SortOrder KeyTreeView::sortOrder() const {
141  assert( m_view );
142  assert( m_view->header() );
143  return m_view->header()->sortIndicatorOrder();
144 }
145 
146 std::vector<int> KeyTreeView::columnSizes() const {
147  assert( m_view );
148  assert( m_view->header() );
149  assert( qobject_cast<HeaderView*>( m_view->header() ) == static_cast<HeaderView*>( m_view->header() ) );
150  if ( HeaderView * const hv = static_cast<HeaderView*>( m_view->header() ) )
151  return hv->sectionSizes();
152  else
153  return std::vector<int>();
154 }
155 
156 void KeyTreeView::init() {
157  KDAB_SET_OBJECT_NAME( m_proxy );
158  KDAB_SET_OBJECT_NAME( m_view );
159  if ( m_additionalProxy && m_additionalProxy->objectName().isEmpty() )
160  KDAB_SET_OBJECT_NAME( m_additionalProxy );
161 
162  QLayout * layout = new QVBoxLayout( this );
163  KDAB_SET_OBJECT_NAME( layout );
164  layout->setMargin( 0 );
165  layout->addWidget( m_view );
166 
167  HeaderView * headerView = new HeaderView( Qt::Horizontal );
168  KDAB_SET_OBJECT_NAME( headerView );
169  m_view->setHeader( headerView );
170 
171  m_view->setSelectionBehavior( QAbstractItemView::SelectRows );
172  m_view->setSelectionMode( QAbstractItemView::ExtendedSelection );
173  //m_view->setAlternatingRowColors( true );
174  m_view->setAllColumnsShowFocus( true );
175  m_view->setSortingEnabled( true );
176 
177  if ( model() ) {
178  if ( m_additionalProxy )
179  m_additionalProxy->setSourceModel( model() );
180  else
181  m_proxy->setSourceModel( model() );
182  }
183  if ( m_additionalProxy ) {
184  m_proxy->setSourceModel( m_additionalProxy );
185  if ( !m_additionalProxy->parent() )
186  m_additionalProxy->setParent( this );
187  }
188  m_proxy->setFilterFixedString( m_stringFilter );
189  m_proxy->setKeyFilter( m_keyFilter );
190  m_view->setModel( m_proxy );
191 #ifdef KDEPIM_MOBILE_UI
192  m_view->setFrameStyle( QFrame::NoFrame );
193 #endif
194 }
195 
196 KeyTreeView::~KeyTreeView() {}
197 
198 static QAbstractProxyModel * find_last_proxy( QAbstractProxyModel * pm ) {
199  assert( pm );
200  while ( QAbstractProxyModel * const sm = qobject_cast<QAbstractProxyModel*>( pm->sourceModel() ) )
201  pm = sm;
202  return pm;
203 }
204 
205 void KeyTreeView::setFlatModel( AbstractKeyListModel * model ) {
206  if ( model == m_flatModel )
207  return;
208  m_flatModel = model;
209  if ( !m_isHierarchical )
210  // TODO: this fails when called after setHierarchicalView( false )...
211  find_last_proxy( m_proxy )->setSourceModel( model );
212 }
213 
214 void KeyTreeView::setHierarchicalModel( AbstractKeyListModel * model ) {
215  if ( model == m_hierarchicalModel )
216  return;
217  m_hierarchicalModel = model;
218  if ( m_isHierarchical ) {
219  find_last_proxy( m_proxy )->setSourceModel( model );
220  m_view->expandAll();
221  for ( int column = 0; column < m_view->header()->count(); ++column )
222  {
223  m_view->header()->resizeSection( column, qMax( m_view->header()->sectionSize( column ), m_view->header()->sectionSizeHint( column ) ) );
224  }
225  }
226 }
227 
228 void KeyTreeView::setStringFilter( const QString & filter ) {
229  if ( filter == m_stringFilter )
230  return;
231  m_stringFilter = filter;
232  m_proxy->setFilterFixedString( filter );
233  emit stringFilterChanged( filter );
234 }
235 
236 void KeyTreeView::setKeyFilter( const shared_ptr<KeyFilter> & filter ) {
237  if ( filter == m_keyFilter || ( filter && m_keyFilter && filter->id() == m_keyFilter->id( )) )
238  return;
239  m_keyFilter = filter;
240  m_proxy->setKeyFilter( filter );
241  emit keyFilterChanged( filter );
242 }
243 
244 static QItemSelection itemSelectionFromKeys( const std::vector<Key> & keys, const KeyListSortFilterProxyModel & proxy ) {
245  QItemSelection result;
246  Q_FOREACH( const Key & key, keys ) {
247  const QModelIndex mi = proxy.index( key );
248  if ( mi.isValid() )
249  result.merge( QItemSelection( mi, mi ), QItemSelectionModel::Select );
250  }
251  return result;
252 }
253 
254 void KeyTreeView::selectKeys( const std::vector<Key> & keys ) {
255  m_view->selectionModel()->select( itemSelectionFromKeys( keys, *m_proxy ), QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows );
256 }
257 
258 std::vector<Key> KeyTreeView::selectedKeys() const {
259  return m_proxy->keys( m_view->selectionModel()->selectedRows() );
260 }
261 
262 void KeyTreeView::setHierarchicalView( bool on ) {
263  if ( on == m_isHierarchical )
264  return;
265  if ( on && !hierarchicalModel() ) {
266  kWarning() << "hierarchical view requested, but no hierarchical model set";
267  return;
268  }
269  if ( !on && !flatModel() ) {
270  kWarning() << "flat view requested, but no flat model set";
271  return;
272  }
273  const std::vector<Key> selectedKeys = m_proxy->keys( m_view->selectionModel()->selectedRows() );
274  const Key currentKey = m_proxy->key( m_view->currentIndex() );
275 
276  m_isHierarchical = on;
277  find_last_proxy( m_proxy )->setSourceModel( model() );
278  if ( on )
279  m_view->expandAll();
280  selectKeys( selectedKeys );
281  if ( !currentKey.isNull() ) {
282  const QModelIndex currentIndex = m_proxy->index( currentKey );
283  if ( currentIndex.isValid() ) {
284  m_view->selectionModel()->setCurrentIndex( m_proxy->index( currentKey ), QItemSelectionModel::NoUpdate );
285  m_view->scrollTo( currentIndex );
286  }
287  }
288  emit hierarchicalChanged( on );
289 }
290 
291 void KeyTreeView::setKeys( const std::vector<Key> & keys ) {
292  std::vector<Key> sorted = keys;
293  _detail::sort_by_fpr( sorted );
294  _detail::remove_duplicates_by_fpr( sorted );
295  m_keys = sorted;
296  if ( m_flatModel )
297  m_flatModel->setKeys( sorted );
298  if ( m_hierarchicalModel )
299  m_hierarchicalModel->setKeys( sorted );
300  if ( !sorted.empty() )
301  if ( QHeaderView * const hv = m_view ? m_view->header() : 0 )
302  hv->resizeSections( QHeaderView::ResizeToContents );
303 }
304 
305 void KeyTreeView::addKeysImpl( const std::vector<Key> & keys, bool select ) {
306  if ( keys.empty() )
307  return;
308  if ( m_keys.empty() ) {
309  setKeys( keys );
310  return;
311  }
312 
313  std::vector<Key> sorted = keys;
314  _detail::sort_by_fpr( sorted );
315  _detail::remove_duplicates_by_fpr( sorted );
316 
317  std::vector<Key> newKeys = _detail::union_by_fpr( sorted, m_keys );
318  m_keys.swap( newKeys );
319 
320  if ( m_flatModel )
321  m_flatModel->addKeys( sorted );
322  if ( m_hierarchicalModel )
323  m_hierarchicalModel->addKeys( sorted );
324 
325  if ( select )
326  selectKeys( sorted );
327 }
328 
329 void KeyTreeView::addKeysSelected( const std::vector<Key> & keys ) {
330  addKeysImpl( keys, true );
331 }
332 
333 void KeyTreeView::addKeysUnselected( const std::vector<Key> & keys ) {
334  addKeysImpl( keys, false );
335 }
336 
337 void KeyTreeView::removeKeys( const std::vector<Key> & keys ) {
338  if ( keys.empty() )
339  return;
340  std::vector<Key> sorted = keys;
341  _detail::sort_by_fpr( sorted );
342  _detail::remove_duplicates_by_fpr( sorted );
343  std::vector<Key> newKeys;
344  newKeys.reserve( m_keys.size() );
345  std::set_difference( m_keys.begin(), m_keys.end(),
346  sorted.begin(), sorted.end(),
347  std::back_inserter( newKeys ),
348  _detail::ByFingerprint<std::less>() );
349  m_keys.swap( newKeys );
350 
351  if ( m_flatModel )
352  kdtools::for_each( sorted, boost::bind( &AbstractKeyListModel::removeKey, m_flatModel, _1 ) );
353  if ( m_hierarchicalModel )
354  kdtools::for_each( sorted, boost::bind( &AbstractKeyListModel::removeKey, m_hierarchicalModel, _1 ) );
355 
356 }
357 
358 static const struct {
359  const char * signal;
360  const char * slot;
361 } connections[] = {
362  { SIGNAL(stringFilterChanged(QString)),
363  SLOT(setStringFilter(QString)) },
364  { SIGNAL(keyFilterChanged(boost::shared_ptr<Kleo::KeyFilter>)),
365  SLOT(setKeyFilter(boost::shared_ptr<Kleo::KeyFilter>)) },
366 };
367 static const unsigned int numConnections = sizeof connections / sizeof *connections ;
368 
369 void KeyTreeView::disconnectSearchBar( const QObject * bar ) {
370  for ( unsigned int i = 0 ; i < numConnections ; ++i ) {
371  disconnect( this, connections[i].signal, bar, connections[i].slot );
372  disconnect( bar, connections[i].signal, this, connections[i].slot );
373  }
374 }
375 
376 bool KeyTreeView::connectSearchBar( const QObject * bar ) {
377  for ( unsigned int i = 0 ; i < numConnections ; ++i )
378  if ( !connect( this, connections[i].signal, bar, connections[i].slot ) ||
379  !connect( bar, connections[i].signal, this, connections[i].slot ) )
380  return false;
381  return true;
382 }
383 
384 #include "moc_keytreeview.cpp"
Kleo::KeyTreeView::connectSearchBar
bool connectSearchBar(const QObject *bar)
Definition: keytreeview.cpp:376
Kleo::KeyTreeView::sortColumn
int sortColumn() const
Definition: keytreeview.cpp:134
signal
const char * signal
Definition: keytreeview.cpp:359
keytreeview.h
Kleo::AbstractKeyListSortFilterProxyModel::key
GpgME::Key key(const QModelIndex &idx) const
Definition: keylistsortfilterproxymodel.cpp:75
Kleo::KeyTreeView::addKeysUnselected
void addKeysUnselected(const std::vector< GpgME::Key > &keys)
Definition: keytreeview.cpp:333
Kleo::KeyTreeView::keys
const std::vector< GpgME::Key > & keys() const
Definition: keytreeview.h:73
Kleo::AbstractKeyListSortFilterProxyModel::index
QModelIndex index(const GpgME::Key &key) const
Definition: keylistsortfilterproxymodel.cpp:95
Kleo::KeyTreeView
Definition: keytreeview.h:54
Kleo::KeyTreeView::model
AbstractKeyListModel * model() const
Definition: keytreeview.h:64
Kleo::KeyTreeView::stringFilterChanged
void stringFilterChanged(const QString &filter)
Kleo::KeyTreeView::disconnectSearchBar
void disconnectSearchBar(const QObject *bar)
Definition: keytreeview.cpp:369
Kleo::KeyTreeView::KeyTreeView
KeyTreeView(QWidget *parent=0)
Definition: keytreeview.cpp:74
Kleo::KeyTreeView::~KeyTreeView
~KeyTreeView()
Definition: keytreeview.cpp:196
QWidget
Kleo::KeyTreeView::selectKeys
void selectKeys(const std::vector< GpgME::Key > &keys)
Definition: keytreeview.cpp:254
Kleo::_detail::union_by_fpr
T union_by_fpr(const T &t1, const T &t2)
Definition: predicates.h:119
Kleo::HeaderView
Definition: headerview.h:44
Kleo::KeyTreeView::setSortColumn
void setSortColumn(int sortColumn, Qt::SortOrder sortOrder)
Definition: keytreeview.cpp:129
Kleo::KeyTreeView::addKeysSelected
void addKeysSelected(const std::vector< GpgME::Key > &keys)
Definition: keytreeview.cpp:329
boost::shared_ptr< KeyFilter >
Kleo::KeyTreeView::setFlatModel
void setFlatModel(AbstractKeyListModel *model)
Definition: keytreeview.cpp:205
Kleo::KeyTreeView::setColumnSizes
void setColumnSizes(const std::vector< int > &sizes)
Definition: keytreeview.cpp:119
keylistsortfilterproxymodel.h
KDAB_SET_OBJECT_NAME
#define KDAB_SET_OBJECT_NAME(x)
Definition: kdtoolsglobal.h:66
Kleo::AbstractKeyListSortFilterProxyModel
Definition: keylistsortfilterproxymodel.h:51
Kleo::_detail::sort_by_fpr
void sort_by_fpr(T &t)
Definition: predicates.h:109
Kleo::_detail::remove_duplicates_by_fpr
void remove_duplicates_by_fpr(T &t)
Definition: predicates.h:114
Kleo::AbstractKeyListModel::addKeys
QList< QModelIndex > addKeys(const std::vector< GpgME::Key > &keys)
Definition: keylistmodel.cpp:229
Kleo::KeyTreeView::setHierarchicalModel
void setHierarchicalModel(AbstractKeyListModel *model)
Definition: keytreeview.cpp:214
Kleo::AbstractKeyListSortFilterProxyModel::keys
std::vector< GpgME::Key > keys(const QList< QModelIndex > &indexes) const
Definition: keylistsortfilterproxymodel.cpp:84
Kleo::AbstractKeyListModel
Definition: keylistmodel.h:49
Kleo::KeyTreeView::selectedKeys
std::vector< GpgME::Key > selectedKeys() const
Definition: keytreeview.cpp:258
keylistmodel.h
Kleo::KeyListSortFilterProxyModel::setKeyFilter
void setKeyFilter(const boost::shared_ptr< const KeyFilter > &kf)
Definition: keylistsortfilterproxymodel.cpp:150
headerview.h
find_last_proxy
static QAbstractProxyModel * find_last_proxy(QAbstractProxyModel *pm)
Definition: keytreeview.cpp:198
Kleo::KeyTreeView::hierarchicalModel
AbstractKeyListModel * hierarchicalModel() const
Definition: keytreeview.h:67
connections
static const struct @14 connections[]
Kleo::KeyTreeView::columnSizes
std::vector< int > columnSizes() const
Definition: keytreeview.cpp:146
Kleo::KeyListSortFilterProxyModel
Definition: keylistsortfilterproxymodel.h:72
predicates.h
Kleo::KeyTreeView::flatModel
AbstractKeyListModel * flatModel() const
Definition: keytreeview.h:66
Kleo::AbstractKeyListModel::removeKey
void removeKey(const GpgME::Key &key)
Definition: keylistmodel.cpp:222
Kleo::KeyTreeView::setHierarchicalView
virtual void setHierarchicalView(bool on)
Definition: keytreeview.cpp:262
itemSelectionFromKeys
static QItemSelection itemSelectionFromKeys(const std::vector< Key > &keys, const KeyListSortFilterProxyModel &proxy)
Definition: keytreeview.cpp:244
Kleo::KeyTreeView::removeKeys
void removeKeys(const std::vector< GpgME::Key > &keys)
Definition: keytreeview.cpp:337
Kleo::KeyTreeView::setKeyFilter
virtual void setKeyFilter(const boost::shared_ptr< Kleo::KeyFilter > &filter)
Definition: keytreeview.cpp:236
Kleo::KeyTreeView::keyFilterChanged
void keyFilterChanged(const boost::shared_ptr< Kleo::KeyFilter > &filter)
numConnections
static const unsigned int numConnections
Definition: keytreeview.cpp:367
Kleo::AbstractKeyListModel::setKeys
void setKeys(const std::vector< GpgME::Key > &keys)
Definition: keylistmodel.cpp:211
Kleo::KeyTreeView::sortOrder
Qt::SortOrder sortOrder() const
Definition: keytreeview.cpp:140
Kleo::KeyTreeView::setKeys
void setKeys(const std::vector< GpgME::Key > &keys)
Definition: keytreeview.cpp:291
slot
const char * slot
Definition: keytreeview.cpp:360
Kleo::KeyTreeView::hierarchicalChanged
void hierarchicalChanged(bool on)
Kleo::KeyTreeView::setStringFilter
virtual void setStringFilter(const QString &text)
Definition: keytreeview.cpp:228
QHeaderView
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:56:41 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

kleopatra

Skip menu "kleopatra"
  • 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

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