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

kleopatra

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