• 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
tabwidget.cpp
Go to the documentation of this file.
1 /* -*- mode: c++; c-basic-offset:4 -*-
2  view/tabwidget.cpp
3 
4  This file is part of Kleopatra, the KDE keymanager
5  Copyright (c) 2007 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 "tabwidget.h"
36 #include "keytreeview.h"
37 
38 #include <models/keylistmodel.h>
39 #include <models/keylistsortfilterproxymodel.h>
40 
41 #include <utils/action_data.h>
42 
43 #include <kleo/stl_util.h>
44 #include <kleo/keyfilter.h>
45 #include <kleo/keyfiltermanager.h>
46 
47 #include <gpgme++/key.h>
48 
49 #include <KLocale>
50 #include <KTabWidget>
51 #include <KConfigGroup>
52 #include <KConfig>
53 #include <KAction>
54 #include <KActionCollection>
55 
56 #include <QGridLayout>
57 #include <QTimer>
58 #include <QTreeView>
59 #include <QToolButton>
60 #include <QAction>
61 #include <QMenu>
62 #include <QInputDialog>
63 
64 #include <map>
65 #include <vector>
66 #include <cassert>
67 
68 using namespace Kleo;
69 using namespace boost;
70 using namespace GpgME;
71 
72 namespace {
73 
74 class Page : public Kleo::KeyTreeView {
75  Q_OBJECT
76  Page( const Page & other );
77 public:
78  Page( const QString & title, const QString & id, const QString & text, AbstractKeyListSortFilterProxyModel * proxy=0, const QString & toolTip=QString(), QWidget * parent=0 );
79  Page( const KConfigGroup & group, QWidget * parent=0 );
80  ~Page();
81 
82  void setTemporary( bool temporary );
83  bool isTemporary() const { return m_isTemporary; }
84 
85  /* reimp */ void setHierarchicalView( bool hierarchical );
86  /* reimp */ void setStringFilter( const QString & filter );
87  /* reimp */ void setKeyFilter( const shared_ptr<KeyFilter> & filter );
88 
89  QString title() const { return m_title.isEmpty() && keyFilter() ? keyFilter()->name() : m_title ; }
90  void setTitle( const QString & title );
91 
92  QString toolTip() const { return m_toolTip.isEmpty() ? title() : m_toolTip ; }
93  void setToolTip( const QString & tip );
94 
95  bool canBeClosed() const { return m_canBeClosed; }
96  bool canBeRenamed() const { return m_canBeRenamed; }
97  bool canChangeStringFilter() const { return m_canChangeStringFilter; }
98  bool canChangeKeyFilter() const { return m_canChangeKeyFilter && !m_isTemporary; }
99  bool canChangeHierarchical() const { return m_canChangeHierarchical; }
100 
101  void saveTo( KConfigGroup & group ) const;
102 
103  /* reimp */ Page * clone() const { return new Page( *this ); }
104 
105  void liftAllRestrictions() {
106  m_canBeClosed = m_canBeRenamed = m_canChangeStringFilter = m_canChangeKeyFilter = m_canChangeHierarchical = true;
107  }
108 
109 Q_SIGNALS:
110  void titleChanged( const QString & title );
111 
112 private:
113  void init();
114 
115 private:
116  QString m_title;
117  QString m_toolTip;
118  bool m_isTemporary : 1;
119  bool m_canBeClosed : 1;
120  bool m_canBeRenamed : 1;
121  bool m_canChangeStringFilter : 1;
122  bool m_canChangeKeyFilter : 1;
123  bool m_canChangeHierarchical : 1;
124 };
125 } // anon namespace
126 
127 Page::Page( const Page & other )
128  : KeyTreeView( other ),
129  m_title( other.m_title ),
130  m_toolTip( other.m_toolTip ),
131  m_isTemporary( other.m_isTemporary ),
132  m_canBeClosed( other.m_canBeClosed ),
133  m_canBeRenamed( other.m_canBeRenamed ),
134  m_canChangeStringFilter( other.m_canChangeStringFilter ),
135  m_canChangeKeyFilter( other.m_canChangeKeyFilter ),
136  m_canChangeHierarchical( other.m_canChangeHierarchical )
137 {
138  init();
139 }
140 
141 Page::Page( const QString & title, const QString & id, const QString & text, AbstractKeyListSortFilterProxyModel * proxy, const QString & toolTip, QWidget * parent )
142  : KeyTreeView( text, KeyFilterManager::instance()->keyFilterByID( id ), proxy, parent ),
143  m_title( title ),
144  m_toolTip( toolTip ),
145  m_isTemporary( false ),
146  m_canBeClosed( true ),
147  m_canBeRenamed( true ),
148  m_canChangeStringFilter( true ),
149  m_canChangeKeyFilter( true ),
150  m_canChangeHierarchical( true )
151 {
152  init();
153 }
154 
155 static const char TITLE_ENTRY[] = "title";
156 static const char STRING_FILTER_ENTRY[] = "string-filter";
157 static const char KEY_FILTER_ENTRY[] = "key-filter";
158 static const char HIERARCHICAL_VIEW_ENTRY[] = "hierarchical-view";
159 static const char COLUMN_SIZES[] = "column-sizes";
160 static const char SORT_COLUMN[] = "sort-column";
161 static const char SORT_DESCENDING[] = "sort-descending";
162 
163 Page::Page( const KConfigGroup & group, QWidget * parent )
164  : KeyTreeView( group.readEntry( STRING_FILTER_ENTRY ),
165  KeyFilterManager::instance()->keyFilterByID( group.readEntry( KEY_FILTER_ENTRY ) ),
166  0, parent ),
167  m_title( group.readEntry( TITLE_ENTRY ) ),
168  m_toolTip(),
169  m_isTemporary( false ),
170  m_canBeClosed( !group.isImmutable() ),
171  m_canBeRenamed( !group.isEntryImmutable( TITLE_ENTRY ) ),
172  m_canChangeStringFilter( !group.isEntryImmutable( STRING_FILTER_ENTRY ) ),
173  m_canChangeKeyFilter( !group.isEntryImmutable( KEY_FILTER_ENTRY ) ),
174  m_canChangeHierarchical( !group.isEntryImmutable( HIERARCHICAL_VIEW_ENTRY ) )
175 {
176  init();
177  setHierarchicalView( group.readEntry( HIERARCHICAL_VIEW_ENTRY, true ) );
178  setColumnSizes( kdtools::copy< std::vector<int> >( group.readEntry( COLUMN_SIZES, QList<int>() ) ) );
179  setSortColumn( group.readEntry( SORT_COLUMN, 0 ),
180  group.readEntry( SORT_DESCENDING, true ) ? Qt::DescendingOrder : Qt::AscendingOrder );
181 }
182 
183 void Page::init() {
184 
185 }
186 
187 Page::~Page() {}
188 
189 void Page::saveTo( KConfigGroup & group ) const {
190 
191  group.writeEntry( TITLE_ENTRY, m_title );
192  group.writeEntry( STRING_FILTER_ENTRY, stringFilter() );
193  group.writeEntry( KEY_FILTER_ENTRY, keyFilter() ? keyFilter()->id() : QString() );
194  group.writeEntry( HIERARCHICAL_VIEW_ENTRY, isHierarchicalView() );
195  group.writeEntry( COLUMN_SIZES, kdtools::copy< QList<int> >( columnSizes() ) );
196  group.writeEntry( SORT_COLUMN, sortColumn() );
197  group.writeEntry( SORT_DESCENDING, sortOrder() == Qt::DescendingOrder );
198 }
199 
200 void Page::setStringFilter( const QString & filter ) {
201  if ( !m_canChangeStringFilter )
202  return;
203  KeyTreeView::setStringFilter( filter );
204 }
205 
206 void Page::setKeyFilter( const shared_ptr<KeyFilter> & filter ) {
207  if ( !canChangeKeyFilter() )
208  return;
209  const QString oldTitle = title();
210  KeyTreeView::setKeyFilter( filter );
211  const QString newTitle = title();
212  if ( oldTitle != newTitle )
213  emit titleChanged( newTitle );
214 }
215 
216 void Page::setTitle( const QString & t ) {
217  if ( t == m_title )
218  return;
219  if ( !m_canBeRenamed )
220  return;
221  const QString oldTitle = title();
222  m_title = t;
223  const QString newTitle = title();
224  if ( oldTitle != newTitle )
225  emit titleChanged( newTitle );
226 }
227 
228 void Page::setToolTip( const QString & tip ) {
229  if ( tip == m_toolTip )
230  return;
231  if ( !m_canBeRenamed )
232  return;
233  const QString oldTip = toolTip();
234  m_toolTip = tip;
235  const QString newTip = toolTip();
236  if ( oldTip != newTip )
237  emit titleChanged( title() );
238 }
239 
240 void Page::setHierarchicalView( bool on ) {
241  if ( !m_canChangeHierarchical )
242  return;
243  KeyTreeView::setHierarchicalView( on );
244 }
245 
246 void Page::setTemporary( bool on ) {
247  if ( on == m_isTemporary )
248  return;
249  m_isTemporary = on;
250  if ( on )
251  setKeyFilter( shared_ptr<KeyFilter>() );
252 }
253 
254 //
255 //
256 // TabWidget
257 //
258 //
259 
260 class TabWidget::Private {
261  friend class ::Kleo::TabWidget;
262  TabWidget * const q;
263 public:
264  explicit Private( TabWidget * qq );
265  ~Private() {}
266 
267 private:
268  void slotContextMenu( const QPoint & p ) {
269  slotContextMenu( 0, p );
270  }
271  void slotContextMenu( QWidget * w, const QPoint & p );
272  void currentIndexChanged( int index );
273  void slotPageTitleChanged( const QString & title );
274  void slotPageKeyFilterChanged( const shared_ptr<KeyFilter> & filter );
275  void slotPageStringFilterChanged( const QString & filter );
276  void slotPageHierarchyChanged( bool on );
277 
278 #ifndef QT_NO_INPUTDIALOG
279  void slotRenameCurrentTab() {
280  renamePage( currentPage() );
281  }
282 #endif // QT_NO_INPUTDIALOG
283  void slotNewTab();
284  void slotDuplicateCurrentTab() {
285  duplicatePage( currentPage() );
286  }
287  void slotCloseCurrentTab() {
288  closePage( currentPage() );
289  }
290  void slotMoveCurrentTabLeft() {
291  movePageLeft( currentPage() );
292  }
293  void slotMoveCurrentTabRight() {
294  movePageRight( currentPage() );
295  }
296  void slotToggleHierarchicalView( bool on ) {
297  toggleHierarchicalView( currentPage(), on );
298  }
299  void slotExpandAll() {
300  expandAll( currentPage() );
301  }
302  void slotCollapseAll() {
303  collapseAll( currentPage() );
304  }
305 
306 #ifndef QT_NO_INPUTDIALOG
307  void renamePage( Page * page );
308 #endif
309  void duplicatePage( Page * page );
310  void closePage( Page * page );
311  void movePageLeft( Page * page );
312  void movePageRight( Page * page );
313  void toggleHierarchicalView( Page * page, bool on );
314  void expandAll( Page * page );
315  void collapseAll( Page * page );
316 
317  void enableDisableCurrentPageActions();
318  void enableDisablePageActions( QAction * actions[], const Page * page );
319 
320  Page * currentPage() const {
321  assert( !tabWidget.currentWidget() || qobject_cast<Page*>( tabWidget.currentWidget() ) );
322  return static_cast<Page*>( tabWidget.currentWidget() );
323  }
324  Page * page( unsigned int idx ) const {
325  assert( !tabWidget.widget( idx ) || qobject_cast<Page*>( tabWidget.widget( idx ) ) );
326  return static_cast<Page*>( tabWidget.widget( idx ) );
327  }
328 
329  Page * senderPage() const {
330  QObject * const sender = q->sender();
331  assert( !sender || qobject_cast<Page*>( sender ) );
332  return static_cast<Page*>( sender );
333  }
334 
335  bool isSenderCurrentPage() const {
336  Page * const sp = senderPage();
337  return sp && sp == currentPage();
338  }
339 
340  QTreeView * addView( Page * page, Page * columnReference );
341  void setCornerAction( QAction * action, Qt::Corner corner );
342 
343 private:
344  AbstractKeyListModel * flatModel;
345  AbstractKeyListModel * hierarchicalModel;
346  KTabWidget tabWidget;
347  QVBoxLayout layout;
348  enum {
349  Rename,
350  Duplicate,
351  Close,
352  MoveLeft,
353  MoveRight,
354  Hierarchical,
355  ExpandAll,
356  CollapseAll,
357 
358  NumPageActions
359  };
360  QAction * newAction;
361  QAction * currentPageActions[NumPageActions];
362  QAction * otherPageActions[NumPageActions];
363 };
364 
365 TabWidget::Private::Private( TabWidget * qq )
366  : q( qq ),
367  flatModel( 0 ),
368  hierarchicalModel( 0 ),
369  tabWidget( q ),
370  layout( q )
371 {
372  KDAB_SET_OBJECT_NAME( tabWidget );
373  KDAB_SET_OBJECT_NAME( layout );
374 
375  layout.setMargin( 0 );
376  layout.addWidget( &tabWidget );
377 
378  tabWidget.setTabBarHidden( true );
379  tabWidget.setMovable( true );
380 
381  connect( &tabWidget, SIGNAL(currentChanged(int)),
382  q, SLOT(currentIndexChanged(int)) );
383  connect( &tabWidget, SIGNAL(contextMenu(QPoint)),
384  q, SLOT(slotContextMenu(QPoint)) );
385  connect( &tabWidget, SIGNAL(contextMenu(QWidget*,QPoint)),
386  q, SLOT(slotContextMenu(QWidget*,QPoint)) );
387 
388  const action_data actionDataNew = {
389  "window_new_tab", i18n("New Tab"), i18n("Open a new tab"),
390  "tab-new-background", q, SLOT(slotNewTab()), i18n("CTRL+SHIFT+N"), false, true
391  };
392 
393  newAction = make_action_from_data( actionDataNew, q );
394 
395  struct action_data actionData[NumPageActions] = {
396  { "window_rename_tab", i18n("Rename Tab..."), i18n("Rename this tab"),
397  "edit-rename", q, SLOT(slotRenameCurrentTab()), i18n("CTRL+SHIFT+R"), false, false },
398  { "window_duplicate_tab", i18n("Duplicate Tab"), i18n("Duplicate this tab"),
399  "tab-duplicate", q, SLOT(slotDuplicateCurrentTab()), i18n("CTRL+SHIFT+D"), false, true },
400  { "window_close_tab", i18n("Close Tab"), i18n("Close this tab"),
401  "tab-close", q, SLOT(slotCloseCurrentTab()), i18n("CTRL+SHIFT+W"), false, false }, // ### CTRL-W when available
402  { "window_move_tab_left", i18n("Move Tab Left"), QString(),
403  0, q, SLOT(slotMoveCurrentTabLeft()), i18n("CTRL+SHIFT+LEFT"), false, false },
404  { "window_move_tab_right", i18n("Move Tab Right"), QString(),
405  0, q, SLOT(slotMoveCurrentTabRight()), i18n("CTRL+SHIFT+RIGHT"), false, false },
406  { "window_view_hierarchical", i18n("Hierarchical Certificate List"), QString(),
407  0, q, SLOT(slotToggleHierarchicalView(bool)), QString(), true, false },
408  { "window_expand_all", i18n("Expand All"), QString(),
409  0, q, SLOT(slotExpandAll()), i18n("CTRL+."), false, false },
410  { "window_collapse_all", i18n("Collapse All"), QString(),
411  0, q, SLOT(slotCollapseAll()), i18n("CTRL+,"), false, false },
412  };
413 
414  for ( unsigned int i = 0 ; i < NumPageActions ; ++i )
415  currentPageActions[i] = make_action_from_data( actionData[i], q );
416 
417  for ( unsigned int i = 0 ; i < NumPageActions ; ++i ) {
418  action_data ad = actionData[i];
419  assert( QString::fromLatin1( ad.name ).startsWith( QLatin1String( "window_" ) ) );
420  ad.name = ad.name + strlen("window_");
421  ad.tooltip.clear();
422  ad.receiver = 0;
423  ad.shortcut.clear();
424  otherPageActions[i] = make_action_from_data( ad, q );
425  }
426 
427  setCornerAction( newAction, Qt::TopLeftCorner );
428  setCornerAction( currentPageActions[Close], Qt::TopRightCorner );
429 }
430 
431 void TabWidget::Private::slotContextMenu( QWidget * w, const QPoint & p ) {
432  assert( !w || qobject_cast<Page*>( w ) );
433  Page * const contextMenuPage = static_cast<Page*>( w );
434  const Page * const current = currentPage();
435 
436  QAction ** const actions = contextMenuPage == current ? currentPageActions : otherPageActions ;
437 
438  if ( contextMenuPage != current )
439  enableDisablePageActions( actions, contextMenuPage );
440 
441  QMenu menu;
442  menu.addAction( actions[Rename] );
443  menu.addSeparator();
444  menu.addAction( newAction );
445  menu.addAction( actions[Duplicate] );
446  menu.addSeparator();
447  menu.addAction( actions[MoveLeft] );
448  menu.addAction( actions[MoveRight] );
449  menu.addSeparator();
450  menu.addAction( actions[Close] );
451 
452  const QAction * const action = menu.exec( p );
453 
454  if ( contextMenuPage == current || action == newAction )
455  return; // performed through signal/slot connections...
456 
457 #ifndef QT_NO_INPUTDIALOG
458  if ( action == otherPageActions[Rename] )
459  renamePage( contextMenuPage );
460 #endif // QT_NO_INPUTDIALOG
461  else if ( action == otherPageActions[Duplicate] )
462  duplicatePage( contextMenuPage );
463  else if ( action == otherPageActions[Close] )
464  closePage( contextMenuPage );
465  else if ( action == otherPageActions[MoveLeft] )
466  movePageLeft( contextMenuPage );
467  else if ( action == otherPageActions[MoveRight] )
468  movePageRight( contextMenuPage );
469 
470 }
471 
472 void TabWidget::Private::currentIndexChanged( int index ) {
473  const Page * const page = this->page( index );
474  emit q->currentViewChanged( page ? page->view() : 0 );
475  emit q->keyFilterChanged( page ? page->keyFilter() : shared_ptr<KeyFilter>() );
476  emit q->stringFilterChanged( page ? page->stringFilter() : QString() );
477  enableDisableCurrentPageActions();
478 }
479 
480 void TabWidget::Private::enableDisableCurrentPageActions() {
481  const Page * const page = currentPage();
482 
483  emit q->enableChangeStringFilter( page && page->canChangeStringFilter() );
484  emit q->enableChangeKeyFilter( page && page->canChangeKeyFilter() );
485 
486  enableDisablePageActions( currentPageActions, page );
487 }
488 
489 void TabWidget::Private::enableDisablePageActions( QAction * actions[], const Page * p ) {
490  actions[Rename] ->setEnabled( p && p->canBeRenamed() );
491  actions[Duplicate] ->setEnabled( p );
492  actions[Close] ->setEnabled( p && p->canBeClosed() && tabWidget.count() > 1 );
493  actions[MoveLeft] ->setEnabled( p && tabWidget.indexOf( const_cast<Page*>(p) ) != 0 );
494  actions[MoveRight] ->setEnabled( p && tabWidget.indexOf( const_cast<Page*>(p) ) != tabWidget.count()-1 );
495  actions[Hierarchical]->setEnabled( p && p->canChangeHierarchical() );
496  actions[Hierarchical]->setChecked( p && p->isHierarchicalView() );
497  actions[ExpandAll] ->setEnabled( p && p->isHierarchicalView() );
498  actions[CollapseAll] ->setEnabled( p && p->isHierarchicalView() );
499 
500  tabWidget.setTabBarHidden( tabWidget.count() < 2 );
501 }
502 
503 void TabWidget::Private::slotPageTitleChanged( const QString & ) {
504  if ( Page * const page = senderPage() ) {
505  const int idx = tabWidget.indexOf( page );
506  tabWidget.setTabText( idx, page->title() );
507  tabWidget.setTabToolTip( idx, page->toolTip() );
508  }
509 }
510 
511 void TabWidget::Private::slotPageKeyFilterChanged( const shared_ptr<KeyFilter> & kf ) {
512  if ( isSenderCurrentPage() )
513  emit q->keyFilterChanged( kf );
514 }
515 
516 void TabWidget::Private::slotPageStringFilterChanged( const QString & filter ) {
517  if ( isSenderCurrentPage() )
518  emit q->stringFilterChanged( filter );
519 }
520 
521 void TabWidget::Private::slotPageHierarchyChanged( bool ) {
522  enableDisableCurrentPageActions();
523 }
524 
525 void TabWidget::Private::slotNewTab() {
526  Page * page = new Page( QString(), QLatin1String("all-certificates"), QString() );
527  addView( page, currentPage() );
528  tabWidget.setCurrentIndex( tabWidget.count()-1 );
529 }
530 
531 #ifndef QT_NO_INPUTDIALOG
532 void TabWidget::Private::renamePage( Page * page ) {
533  if ( !page )
534  return;
535  bool ok = false;
536  const QString text = QInputDialog::getText( q, i18n("Rename Tab"), i18n("New tab title:"), QLineEdit::Normal, page->title(), &ok );
537  if ( !ok )
538  return;
539  page->setTitle( text );
540 }
541 #endif
542 
543 void TabWidget::Private::duplicatePage( Page * page ) {
544  if ( !page )
545  return;
546  Page * const clone = page->clone();
547  assert( clone );
548  clone->liftAllRestrictions();
549  addView( clone, page );
550 }
551 
552 void TabWidget::Private::closePage( Page * page) {
553  if ( !page || !page->canBeClosed() || tabWidget.count() <= 1 )
554  return;
555  emit q->viewAboutToBeRemoved( page->view() );
556  tabWidget.removeTab( tabWidget.indexOf( page ) );
557  enableDisableCurrentPageActions();
558 }
559 
560 void TabWidget::Private::movePageLeft( Page * page ) {
561  if ( !page )
562  return;
563  const int idx = tabWidget.indexOf( page );
564  if ( idx <= 0 )
565  return;
566  tabWidget.moveTab( idx, idx-1 );
567  enableDisableCurrentPageActions();
568 }
569 
570 void TabWidget::Private::movePageRight( Page * page ) {
571  if ( !page )
572  return;
573  const int idx = tabWidget.indexOf( page );
574  if ( idx < 0 || idx >= tabWidget.count()-1 )
575  return;
576  tabWidget.moveTab( idx, idx+1 );
577  enableDisableCurrentPageActions();
578 }
579 
580 void TabWidget::Private::toggleHierarchicalView( Page * page, bool on ) {
581  if ( !page )
582  return;
583  page->setHierarchicalView( on );
584 }
585 
586 void TabWidget::Private::expandAll( Page * page ) {
587  if ( !page || !page->view() )
588  return;
589  page->view()->expandAll();
590 }
591 
592 void TabWidget::Private::collapseAll( Page * page ) {
593  if ( !page || !page->view() )
594  return;
595  page->view()->collapseAll();
596 }
597 
598 TabWidget::TabWidget( QWidget * p, Qt::WindowFlags f )
599  : QWidget( p, f ), d( new Private( this ) )
600 {
601 
602 }
603 
604 TabWidget::~TabWidget() {}
605 
606 void TabWidget::setFlatModel( AbstractKeyListModel * model ) {
607  if ( model == d->flatModel )
608  return;
609  d->flatModel = model;
610  for ( unsigned int i = 0, end = count() ; i != end ; ++i )
611  if ( Page * const page = d->page( i ) )
612  page->setFlatModel( model );
613 }
614 
615 AbstractKeyListModel * TabWidget::flatModel() const {
616  return d->flatModel;
617 }
618 
619 void TabWidget::setHierarchicalModel( AbstractKeyListModel * model ) {
620  if ( model == d->hierarchicalModel )
621  return;
622  d->hierarchicalModel = model;
623  for ( unsigned int i = 0, end = count() ; i != end ; ++i )
624  if ( Page * const page = d->page( i ) )
625  page->setHierarchicalModel( model );
626 }
627 
628 AbstractKeyListModel * TabWidget::hierarchicalModel() const {
629  return d->hierarchicalModel;
630 }
631 
632 void TabWidget::Private::setCornerAction( QAction * action, Qt::Corner corner ) {
633  if ( !action )
634  return;
635  QToolButton * b = new QToolButton;
636  b->setDefaultAction( action );
637  tabWidget.setCornerWidget( b, corner );
638 }
639 
640 void TabWidget::setStringFilter( const QString & filter ) {
641  if ( Page * const page = d->currentPage() )
642  page->setStringFilter( filter );
643 }
644 
645 void TabWidget::setKeyFilter( const shared_ptr<KeyFilter> & filter ) {
646  if ( Page * const page = d->currentPage() )
647  page->setKeyFilter( filter );
648 }
649 
650 std::vector<QAbstractItemView*> TabWidget::views() const {
651  std::vector<QAbstractItemView*> result;
652  const unsigned int N = count();
653  result.reserve( N );
654  for ( unsigned int i = 0 ; i != N ; ++i )
655  if ( const Page * const p = d->page( i ) )
656  result.push_back( p->view() );
657  return result;
658 }
659 
660 QAbstractItemView * TabWidget::currentView() const {
661  if ( Page * const page = d->currentPage() )
662  return page->view();
663  else
664  return 0;
665 }
666 
667 unsigned int TabWidget::count() const {
668  return d->tabWidget.count();
669 }
670 
671 void TabWidget::setMultiSelection( bool on ) {
672  for ( unsigned int i = 0, end = count() ; i != end ; ++i )
673  if ( const Page * const p = d->page( i ) )
674  if ( QTreeView * const view = p->view() )
675  view->setSelectionMode( on ? QAbstractItemView::ExtendedSelection : QAbstractItemView::SingleSelection );
676 }
677 
678 void TabWidget::createActions( KActionCollection * coll ) {
679  if ( !coll )
680  return;
681  coll->addAction( d->newAction->objectName(), d->newAction );
682  for ( unsigned int i = 0 ; i < Private::NumPageActions ; ++i ) {
683  QAction * a = d->currentPageActions[i];
684  coll->addAction( a->objectName(), a );
685  }
686 }
687 
688 QAbstractItemView * TabWidget::addView( const QString & title, const QString & id, const QString & text ) {
689  return d->addView( new Page( title, id, text ), d->currentPage() );
690 }
691 
692 QAbstractItemView * TabWidget::addView( const KConfigGroup & group ) {
693  return d->addView( new Page( group ), 0 );
694 }
695 
696 QAbstractItemView * TabWidget::addTemporaryView( const QString & title, AbstractKeyListSortFilterProxyModel * proxy, const QString & tabToolTip ) {
697  Page * const page = new Page( title, QString(), QString(), proxy, tabToolTip );
698  page->setTemporary( true );
699  QAbstractItemView * v = d->addView( page, d->currentPage() );
700  d->tabWidget.setCurrentIndex( d->tabWidget.count()-1 );
701  return v;
702 }
703 
704 QTreeView * TabWidget::Private::addView( Page * page, Page * columnReference ) {
705  if ( !page )
706  return 0;
707 
708  page->setFlatModel( flatModel );
709  page->setHierarchicalModel( hierarchicalModel );
710 
711  connect( page, SIGNAL(titleChanged(QString)),
712  q, SLOT(slotPageTitleChanged(QString)) );
713  connect( page, SIGNAL(keyFilterChanged(boost::shared_ptr<Kleo::KeyFilter>)),
714  q, SLOT(slotPageKeyFilterChanged(boost::shared_ptr<Kleo::KeyFilter>)) );
715  connect( page, SIGNAL(stringFilterChanged(QString)),
716  q, SLOT(slotPageStringFilterChanged(QString)) );
717  connect( page, SIGNAL(hierarchicalChanged(bool)),
718  q, SLOT(slotPageHierarchyChanged(bool)) );
719 
720  if ( columnReference ) {
721  page->setColumnSizes( columnReference->columnSizes() );
722  page->setSortColumn( columnReference->sortColumn(), columnReference->sortOrder() );
723  }
724 
725  QAbstractItemView * const previous = q->currentView();
726  const int tabIndex = tabWidget.addTab( page, page->title() );
727  tabWidget.setTabToolTip( tabIndex, page->toolTip() );
728  // work around a bug in QTabWidget (tested with 4.3.2) not emitting currentChanged() when the first widget is inserted
729  QAbstractItemView * const current = q->currentView();
730  if ( previous != current )
731  currentIndexChanged( tabWidget.currentIndex() );
732  enableDisableCurrentPageActions();
733  QTreeView * view = page->view();
734  emit q->viewAdded( view );
735  return view;
736 }
737 
738 static QStringList extractViewGroups( const KConfig * config ) {
739  return config ? config->groupList().filter( QRegExp( QLatin1String("^View #\\d+$") ) ) : QStringList() ;
740 }
741 
742 // work around deleteGroup() not deleting groups out of groupList():
743 static const bool KCONFIG_DELETEGROUP_BROKEN = true;
744 
745 void TabWidget::loadViews( const KConfig * config ) {
746  if ( config )
747  Q_FOREACH( const QString & group, extractViewGroups( config ) ) {
748  const KConfigGroup kcg( config, group );
749  if ( !KCONFIG_DELETEGROUP_BROKEN || kcg.readEntry( "magic", 0U ) == 0xFA1AFE1U )
750  addView( kcg );
751  }
752  if ( !count() ) {
753  // add default views:
754  addView( QString(), QLatin1String("my-certificates") );
755  addView( QString(), QLatin1String("trusted-certificates") );
756  addView( QString(), QLatin1String("other-certificates") );
757  }
758 }
759 
760 void TabWidget::saveViews( KConfig * config ) const {
761  if ( !config )
762  return;
763  Q_FOREACH( const QString & group, extractViewGroups( config ) )
764  config->deleteGroup( group );
765  unsigned int vg = 0;
766  for ( unsigned int i = 0, end = count() ; i != end ; ++i ) {
767  if ( const Page * const p = d->page( i ) ) {
768  if ( p->isTemporary() )
769  continue;
770  KConfigGroup group( config, QString().sprintf( "View #%u", vg++ ) );
771  p->saveTo( group );
772  if ( KCONFIG_DELETEGROUP_BROKEN )
773  group.writeEntry( "magic", 0xFA1AFE1U );
774  }
775  }
776 }
777 
778 static void xconnect( const QObject * o1, const char * signal, const QObject * o2, const char * slot ) {
779  QObject::connect( o1, signal, o2, slot );
780  QObject::connect( o2, signal, o1, slot );
781 }
782 
783 void TabWidget::connectSearchBar( QObject * sb ) {
784  xconnect( sb, SIGNAL(stringFilterChanged(QString)),
785  this, SLOT(setStringFilter(QString)) );
786  xconnect( sb, SIGNAL(keyFilterChanged(boost::shared_ptr<Kleo::KeyFilter>)),
787  this, SLOT(setKeyFilter(boost::shared_ptr<Kleo::KeyFilter>)) );
788  connect( this, SIGNAL(enableChangeStringFilter(bool)),
789  sb, SLOT(setChangeStringFilterEnabled(bool)) );
790  connect( this, SIGNAL(enableChangeKeyFilter(bool)),
791  sb, SLOT(setChangeKeyFilterEnabled(bool)) );
792 }
793 
794 #include "moc_tabwidget.cpp"
795 #include "tabwidget.moc"
signal
const char * signal
Definition: keytreeview.cpp:359
STRING_FILTER_ENTRY
static const char STRING_FILTER_ENTRY[]
Definition: tabwidget.cpp:156
keytreeview.h
Kleo::TabWidget::createActions
void createActions(KActionCollection *collection)
Definition: tabwidget.cpp:678
Kleo::TabWidget::connectSearchBar
void connectSearchBar(QObject *sb)
Definition: tabwidget.cpp:783
Kleo::KeyTreeView
Definition: keytreeview.h:54
Kleo::TabWidget
Definition: tabwidget.h:56
Kleo::TabWidget::stringFilterChanged
void stringFilterChanged(const QString &filter)
Kleo::action_data::tooltip
QString tooltip
Definition: action_data.h:47
QWidget
Kleo::Formatting::toolTip
QString toolTip(const GpgME::Key &key, int opts)
KCONFIG_DELETEGROUP_BROKEN
static const bool KCONFIG_DELETEGROUP_BROKEN
Definition: tabwidget.cpp:743
TITLE_ENTRY
static const char TITLE_ENTRY[]
Definition: tabwidget.cpp:155
Kleo::action_data::shortcut
QString shortcut
Definition: action_data.h:51
Kleo::TabWidget::addTemporaryView
QAbstractItemView * addTemporaryView(const QString &title=QString(), AbstractKeyListSortFilterProxyModel *proxy=0, const QString &tabToolTip=QString())
Definition: tabwidget.cpp:696
Kleo::TabWidget::enableChangeStringFilter
void enableChangeStringFilter(bool enable)
Kleo::TabWidget::setMultiSelection
void setMultiSelection(bool on)
Definition: tabwidget.cpp:671
COLUMN_SIZES
static const char COLUMN_SIZES[]
Definition: tabwidget.cpp:159
Kleo::action_data::receiver
const QObject * receiver
Definition: action_data.h:49
Kleo::TabWidget::setHierarchicalModel
void setHierarchicalModel(AbstractKeyListModel *model)
Definition: tabwidget.cpp:619
boost::shared_ptr< KeyFilter >
d
#define d
Definition: adduseridcommand.cpp:90
tabwidget.h
action_data.h
extractViewGroups
static QStringList extractViewGroups(const KConfig *config)
Definition: tabwidget.cpp:738
HIERARCHICAL_VIEW_ENTRY
static const char HIERARCHICAL_VIEW_ENTRY[]
Definition: tabwidget.cpp:158
keylistsortfilterproxymodel.h
KDAB_SET_OBJECT_NAME
#define KDAB_SET_OBJECT_NAME(x)
Definition: kdtoolsglobal.h:66
Kleo::xconnect
static bool xconnect(const QObject *a, const char *signal, const QObject *b, const char *slot)
Definition: gui-helper.h:46
SORT_COLUMN
static const char SORT_COLUMN[]
Definition: tabwidget.cpp:160
Kleo::TabWidget::flatModel
AbstractKeyListModel * flatModel() const
Definition: tabwidget.cpp:615
Kleo::AbstractKeyListSortFilterProxyModel
Definition: keylistsortfilterproxymodel.h:51
Kleo::action_data
Definition: action_data.h:44
Kleo::AbstractKeyListModel
Definition: keylistmodel.h:49
Kleo::TabWidget::setKeyFilter
void setKeyFilter(const boost::shared_ptr< Kleo::KeyFilter > &filter)
Definition: tabwidget.cpp:645
Kleo::TabWidget::setStringFilter
void setStringFilter(const QString &filter)
Definition: tabwidget.cpp:640
keylistmodel.h
Kleo::TabWidget::setFlatModel
void setFlatModel(AbstractKeyListModel *model)
Definition: tabwidget.cpp:606
SORT_DESCENDING
static const char SORT_DESCENDING[]
Definition: tabwidget.cpp:161
Kleo::TabWidget::addView
QAbstractItemView * addView(const QString &title=QString(), const QString &keyFilterID=QString(), const QString &searchString=QString())
Definition: tabwidget.cpp:688
q
#define q
Definition: adduseridcommand.cpp:91
Kleo::TabWidget::~TabWidget
~TabWidget()
Definition: tabwidget.cpp:604
Page
Page
Definition: newsignencryptfileswizard.cpp:86
Kleo::TabWidget::hierarchicalModel
AbstractKeyListModel * hierarchicalModel() const
Definition: tabwidget.cpp:628
Kleo::TabWidget::enableChangeKeyFilter
void enableChangeKeyFilter(bool enable)
Kleo::TabWidget::saveViews
void saveViews(KConfig *cfg) const
Definition: tabwidget.cpp:760
Kleo::action_data::name
const char * name
Definition: action_data.h:45
Kleo::TabWidget::views
std::vector< QAbstractItemView * > views() const
Definition: tabwidget.cpp:650
KEY_FILTER_ENTRY
static const char KEY_FILTER_ENTRY[]
Definition: tabwidget.cpp:157
Kleo::TabWidget::loadViews
void loadViews(const KConfig *cfg)
Definition: tabwidget.cpp:745
slot
const char * slot
Definition: keytreeview.cpp:360
Kleo::TabWidget::keyFilterChanged
void keyFilterChanged(const boost::shared_ptr< Kleo::KeyFilter > &filter)
QList< int >
Kleo::make_action_from_data
KAction * make_action_from_data(const action_data &data, QObject *parent)
Definition: action_data.cpp:40
Kleo::TabWidget::count
unsigned int count() const
Definition: tabwidget.cpp:667
Kleo::TabWidget::currentView
QAbstractItemView * currentView() const
Definition: tabwidget.cpp:660
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:56:42 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