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

mailcommon

  • sources
  • kde-4.12
  • kdepim
  • mailcommon
  • folder
foldertreewidget.cpp
Go to the documentation of this file.
1 /* -*- mode: C++; c-file-style: "gnu" -*-
2 
3  Copyright (c) 2009, 2010 Montel Laurent <montel@kde.org>
4 
5  This program is free software; you can redistribute it and/or modify it
6  under the terms of the GNU General Public License, version 2, as
7  published by the Free Software Foundation.
8 
9  This program is distributed in the hope that it will be useful, but
10  WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License along
15  with this program; if not, write to the Free Software Foundation, Inc.,
16  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18 
19 #include "foldertreewidget.h"
20 #include "entitycollectionorderproxymodel.h"
21 #include "foldertreeview.h"
22 #include "foldertreewidgetproxymodel.h"
23 #include "kernel/mailkernel.h"
24 #include "util/mailutil.h"
25 
26 #include "pimcommon/acl/imapaclattribute.h"
27 #include "pimcommon/util/pimutil.h"
28 
29 #include <akonadi_next/quotacolorproxymodel.h>
30 
31 #include <libkdepim/misc/statisticsproxymodel.h>
32 
33 #include <messageviewer/settings/globalsettings.h>
34 
35 #include <messagecore/settings/globalsettings.h>
36 
37 #include <Akonadi/AttributeFactory>
38 #include <Akonadi/ChangeRecorder>
39 #include <Akonadi/Collection>
40 #include <Akonadi/EntityMimeTypeFilterModel>
41 #include <Akonadi/EntityTreeModel>
42 #include <Akonadi/EntityTreeView>
43 #include <Akonadi/ETMViewStateSaver>
44 #include <Akonadi/ItemFetchScope>
45 
46 #include <KLineEdit>
47 #include <KLocalizedString>
48 
49 #include <QKeyEvent>
50 #include <QLabel>
51 
52 namespace MailCommon {
53 
54 class FolderTreeWidget::FolderTreeWidgetPrivate
55 {
56  public:
57  FolderTreeWidgetPrivate()
58  : filterModel( 0 ),
59  folderTreeView( 0 ),
60  quotaModel( 0 ),
61  readableproxy( 0 ),
62  entityOrderProxy( 0 ),
63  filterFolderLineEdit( 0 ),
64  saver( 0 ),
65  label( 0 ),
66  dontKeyFilter( false )
67  {
68  }
69 
70  QString filter;
71  QString oldFilterStr;
72  KPIM::StatisticsProxyModel *filterModel;
73  FolderTreeView *folderTreeView;
74  Akonadi::QuotaColorProxyModel *quotaModel;
75  FolderTreeWidgetProxyModel *readableproxy;
76  EntityCollectionOrderProxyModel *entityOrderProxy;
77  KLineEdit *filterFolderLineEdit;
78  QPointer<Akonadi::ETMViewStateSaver> saver;
79  QStringList expandedItems;
80  QString currentItem;
81  QLabel *label;
82  bool dontKeyFilter;
83 };
84 
85 FolderTreeWidget::FolderTreeWidget(
86  QWidget *parent, KXMLGUIClient *xmlGuiClient,
87  FolderTreeWidget::TreeViewOptions options,
88  FolderTreeWidgetProxyModel::FolderTreeWidgetProxyModelOptions optReadableProxy )
89  : QWidget( parent ), d( new FolderTreeWidgetPrivate() )
90 {
91  Akonadi::AttributeFactory::registerAttribute<PimCommon::ImapAclAttribute>();
92 
93  d->folderTreeView = new FolderTreeView( xmlGuiClient, this, options & ShowUnreadCount );
94  d->folderTreeView->showStatisticAnimation( options & ShowCollectionStatisticAnimation );
95 
96  connect( d->folderTreeView, SIGNAL(manualSortingChanged(bool)),
97  this, SLOT(slotManualSortingChanged(bool)) );
98 
99  QVBoxLayout *lay = new QVBoxLayout( this );
100  lay->setMargin( 0 );
101 
102  d->label = new QLabel( i18n( "You can start typing to filter the list of folders." ), this );
103  lay->addWidget( d->label );
104 
105  d->filterFolderLineEdit = new KLineEdit( this );
106  d->filterFolderLineEdit->setClearButtonShown( true );
107  d->filterFolderLineEdit->setClickMessage(
108  i18nc( "@info/plain Displayed grayed-out inside the textbox, verb to search",
109  "Search" ) );
110  lay->addWidget( d->filterFolderLineEdit );
111 
112  // ... with statistics...
113  d->quotaModel = new Akonadi::QuotaColorProxyModel( this );
114  d->quotaModel->setSourceModel( KernelIf->collectionModel() );
115 
116  d->filterModel = new KPIM::StatisticsProxyModel( this );
117  d->filterModel->setSourceModel( d->quotaModel );
118 
119  d->readableproxy = new FolderTreeWidgetProxyModel( this, optReadableProxy );
120  d->readableproxy->setSourceModel( d->filterModel );
121  d->readableproxy->addContentMimeTypeInclusionFilter( KMime::Message::mimeType() );
122 
123  connect( d->folderTreeView, SIGNAL(changeTooltipsPolicy(FolderTreeWidget::ToolTipDisplayPolicy)),
124  this, SLOT(slotChangeTooltipsPolicy(FolderTreeWidget::ToolTipDisplayPolicy)) );
125 
126  d->folderTreeView->setSelectionMode( QAbstractItemView::SingleSelection );
127  d->folderTreeView->setEditTriggers( QAbstractItemView::NoEditTriggers );
128  d->folderTreeView->installEventFilter( this );
129 
130  //Order proxy
131  d->entityOrderProxy = new EntityCollectionOrderProxyModel( this );
132  d->entityOrderProxy->setSourceModel( d->readableproxy );
133  KConfigGroup grp( KernelIf->config(), "CollectionTreeOrder" );
134  d->entityOrderProxy->setOrderConfig( grp );
135  d->folderTreeView->setModel( d->entityOrderProxy );
136 
137  if ( options & UseDistinctSelectionModel ) {
138  d->folderTreeView->setSelectionModel( new QItemSelectionModel( d->entityOrderProxy, this ) );
139  }
140 
141  lay->addWidget( d->folderTreeView );
142 
143  d->dontKeyFilter = ( options & DontKeyFilter );
144 
145  if ( ( options & UseLineEditForFiltering ) ) {
146  connect( d->filterFolderLineEdit, SIGNAL(textChanged(QString)),
147  this, SLOT(slotFilterFixedString(QString)) );
148  d->label->hide();
149  } else {
150  d->filterFolderLineEdit->hide();
151  }
152 
153  connect( KGlobalSettings::self(), SIGNAL(kdisplayFontChanged()),
154  this, SLOT(slotGeneralFontChanged()));
155  connect( KGlobalSettings::self(), SIGNAL(kdisplayPaletteChanged()),
156  this, SLOT(slotGeneralPaletteChanged()));
157 }
158 
159 FolderTreeWidget::~FolderTreeWidget()
160 {
161  delete d;
162 }
163 
164 void FolderTreeWidget::slotFilterFixedString( const QString &text )
165 {
166  delete d->saver;
167  if ( d->oldFilterStr.isEmpty() ) {
168  //Save it.
169  Akonadi::ETMViewStateSaver saver;
170  saver.setView( folderTreeView() );
171  d->expandedItems = saver.expansionKeys();
172  d->currentItem = saver.currentIndexKey();
173  } else if ( text.isEmpty() ) {
174  d->saver = new Akonadi::ETMViewStateSaver;
175  d->saver->setView( folderTreeView() );
176  QString currentIndex = d->saver->currentIndexKey();
177  if ( d->saver->selectionKeys().isEmpty() ) {
178  currentIndex = d->currentItem;
179  } else if ( !currentIndex.isEmpty() ) {
180  d->expandedItems << currentIndex;
181  }
182  d->saver->restoreExpanded( d->expandedItems );
183  d->saver->restoreCurrentItem( currentIndex );
184  } else {
185  d->folderTreeView->expandAll();
186  }
187  d->oldFilterStr = text;
188  d->readableproxy->setFilterFolder( text );
189 }
190 
191 void FolderTreeWidget::disableContextMenuAndExtraColumn()
192 {
193  d->folderTreeView->disableContextMenuAndExtraColumn();
194 }
195 
196 void FolderTreeWidget::selectCollectionFolder( const Akonadi::Collection &collection )
197 {
198  const QModelIndex index =
199  Akonadi::EntityTreeModel::modelIndexForCollection( d->folderTreeView->model(), collection );
200 
201  d->folderTreeView->setCurrentIndex( index );
202  d->folderTreeView->setExpanded( index, true );
203  d->folderTreeView->scrollTo( index );
204 }
205 
206 void FolderTreeWidget::setSelectionMode( QAbstractItemView::SelectionMode mode )
207 {
208  d->folderTreeView->setSelectionMode( mode );
209 }
210 
211 QAbstractItemView::SelectionMode FolderTreeWidget::selectionMode() const
212 {
213  return d->folderTreeView->selectionMode();
214 }
215 
216 QItemSelectionModel * FolderTreeWidget::selectionModel () const
217 {
218  return d->folderTreeView->selectionModel();
219 }
220 
221 QModelIndex FolderTreeWidget::currentIndex() const
222 {
223  return d->folderTreeView->currentIndex();
224 }
225 
226 Akonadi::Collection FolderTreeWidget::selectedCollection() const
227 {
228  if ( d->folderTreeView->selectionMode() == QAbstractItemView::SingleSelection ) {
229  Akonadi::Collection::List lstCollection = selectedCollections();
230  if ( lstCollection.isEmpty() ) {
231  return Akonadi::Collection();
232  } else {
233  return lstCollection.at( 0 );
234  }
235  }
236 
237  return Akonadi::Collection();
238 }
239 
240 Akonadi::Collection::List FolderTreeWidget::selectedCollections() const
241 {
242  Akonadi::Collection::List collections;
243  const QItemSelectionModel *selectionModel = d->folderTreeView->selectionModel();
244  const QModelIndexList selectedIndexes = selectionModel->selectedIndexes();
245  foreach ( const QModelIndex &index, selectedIndexes ) {
246  if ( index.isValid() ) {
247  const Akonadi::Collection collection =
248  index.model()->data(
249  index, Akonadi::EntityTreeModel::CollectionRole ).value<Akonadi::Collection>();
250  if ( collection.isValid() ) {
251  collections.append( collection );
252  }
253  }
254  }
255 
256  return collections;
257 }
258 
259 FolderTreeView *FolderTreeWidget::folderTreeView() const
260 {
261  return d->folderTreeView;
262 }
263 
264 void FolderTreeWidget::slotGeneralFontChanged()
265 {
266  // Custom/System font support
267  if ( MessageCore::GlobalSettings::self()->useDefaultFonts() ) {
268  setFont( KGlobalSettings::generalFont() );
269  }
270 }
271 
272 void FolderTreeWidget::slotGeneralPaletteChanged()
273 {
274  d->readableproxy->updatePalette();
275  d->folderTreeView->updatePalette();
276 }
277 
278 void FolderTreeWidget::readConfig()
279 {
280  // Custom/System font support
281  if ( !MessageCore::GlobalSettings::self()->useDefaultFonts() ) {
282  KConfigGroup fontConfig( KernelIf->config(), "Fonts" );
283  setFont( fontConfig.readEntry( "folder-font", KGlobalSettings::generalFont() ) );
284  } else {
285  setFont( KGlobalSettings::generalFont() );
286  }
287 
288  d->folderTreeView->readConfig();
289  d->folderTreeView->setDropActionMenuEnabled( SettingsIf->showPopupAfterDnD() );
290  d->readableproxy->readConfig();
291 
292  KConfigGroup readerConfig( KernelIf->config(), "AccountOrder" );
293  const QStringList listOrder = readerConfig.readEntry( "order", QStringList() );
294  d->entityOrderProxy->setTopLevelOrder(listOrder);
295 
296  readQuotaConfig();
297 }
298 
299 void FolderTreeWidget::restoreHeaderState( const QByteArray &data )
300 {
301  d->folderTreeView->restoreHeaderState( data );
302 }
303 
304 void FolderTreeWidget::slotChangeTooltipsPolicy( FolderTreeWidget::ToolTipDisplayPolicy policy )
305 {
306  changeToolTipsPolicyConfig( policy );
307 }
308 
309 void FolderTreeWidget::changeToolTipsPolicyConfig( ToolTipDisplayPolicy policy )
310 {
311  switch( policy ){
312  case DisplayAlways:
313  case DisplayWhenTextElided: //Need to implement in the future
314  d->filterModel->setToolTipEnabled( true );
315  break;
316  case DisplayNever:
317  d->filterModel->setToolTipEnabled( false );
318  }
319  d->folderTreeView->setTooltipsPolicy( policy );
320 }
321 
322 void FolderTreeWidget::quotaWarningParameters( const QColor &color, qreal threshold )
323 {
324  d->quotaModel->setWarningThreshold( threshold );
325  d->quotaModel->setWarningColor( color );
326 }
327 
328 void FolderTreeWidget::readQuotaConfig()
329 {
330  QColor quotaColor = MailCommon::Util::defaultQuotaColor();
331  qreal threshold = 100;
332  if ( !MessageCore::GlobalSettings::self()->useDefaultColors() ) {
333  KConfigGroup readerConfig( KernelIf->config(), "Reader" );
334  quotaColor = readerConfig.readEntry( "CloseToQuotaColor", quotaColor );
335  }
336  threshold = SettingsIf->closeToQuotaThreshold();
337  quotaWarningParameters( quotaColor, threshold );
338 }
339 
340 KPIM::StatisticsProxyModel *FolderTreeWidget::statisticsProxyModel() const
341 {
342  return d->filterModel;
343 }
344 
345 FolderTreeWidgetProxyModel *FolderTreeWidget::folderTreeWidgetProxyModel() const
346 {
347  return d->readableproxy;
348 }
349 
350 EntityCollectionOrderProxyModel *FolderTreeWidget::entityOrderProxy() const
351 {
352  return d->entityOrderProxy;
353 }
354 
355 KLineEdit *FolderTreeWidget::filterFolderLineEdit() const
356 {
357  return d->filterFolderLineEdit;
358 }
359 
360 void FolderTreeWidget::applyFilter( const QString &filter )
361 {
362  d->label->setText(
363  filter.isEmpty() ?
364  i18n( "You can start typing to filter the list of folders." ) :
365  i18n( "Path: (%1)", filter ) );
366 
367  d->readableproxy->setFilterFolder( filter );
368  d->folderTreeView->expandAll();
369  QAbstractItemModel *model = d->folderTreeView->model();
370  QModelIndex current = d->folderTreeView->currentIndex();
371  QModelIndex start = current.isValid() ? current : model->index(0, 0);
372  QModelIndexList list = model->match( start, Qt::DisplayRole, d->filter, 1 /* stop at first hit */,
373  Qt::MatchContains | Qt::MatchWrap | Qt::MatchRecursive );
374  if ( !list.isEmpty() ) {
375  current = list.first();
376  d->folderTreeView->setCurrentIndex( current );
377  d->folderTreeView->scrollTo( current );
378  }
379 }
380 
381 void FolderTreeWidget::clearFilter()
382 {
383  d->filter.clear();
384  applyFilter( d->filter );
385  const QModelIndexList lst = d->folderTreeView->selectionModel()->selectedIndexes();
386  if ( !lst.isEmpty() ) {
387  d->folderTreeView->scrollTo( lst.first() );
388  }
389 }
390 
391 void FolderTreeWidget::slotManualSortingChanged( bool active )
392 {
393  d->entityOrderProxy->setManualSortingActive( active );
394  d->folderTreeView->setManualSortingActive( active );
395 }
396 
397 bool FolderTreeWidget::eventFilter( QObject *o, QEvent *e )
398 {
399  Q_UNUSED( o );
400  if ( d->dontKeyFilter ) {
401  return false;
402  }
403 
404  if ( e->type() == QEvent::KeyPress ) {
405  const QKeyEvent* const ke = static_cast<QKeyEvent*>( e );
406  switch( ke->key() ) {
407  case Qt::Key_Backspace:
408  {
409  const int filterLength( d->filter.length() );
410  if ( filterLength > 0 ) {
411  d->filter.truncate( filterLength-1 );
412  }
413  applyFilter( d->filter );
414  return false;
415  }
416  break;
417  case Qt::Key_Delete:
418  d->filter.clear();
419  applyFilter( d->filter );
420  return false;
421  break;
422  default:
423  {
424  const QString s = ke->text();
425  if ( !s.isEmpty() && s.at( 0 ).isPrint() ) {
426  d->filter += s;
427  applyFilter( d->filter );
428  return false;
429  }
430  }
431  break;
432  }
433  }
434  return false;
435 }
436 
437 }
438 
439 #include "foldertreewidget.moc"
MailCommon::Util::defaultQuotaColor
MAILCOMMON_EXPORT QColor defaultQuotaColor()
Definition: mailutil.cpp:597
MailCommon::FolderTreeWidget::UseLineEditForFiltering
Definition: foldertreewidget.h:58
SettingsIf
#define SettingsIf
Definition: mailkernel.h:188
MailCommon::FolderTreeWidget::applyFilter
void applyFilter(const QString &)
Definition: foldertreewidget.cpp:360
MailCommon::FolderTreeWidget::FolderTreeWidget
FolderTreeWidget(QWidget *parent=0, KXMLGUIClient *xmlGuiClient=0, TreeViewOptions options=(TreeViewOptions)(ShowUnreadCount|ShowCollectionStatisticAnimation), FolderTreeWidgetProxyModel::FolderTreeWidgetProxyModelOptions optReadableProxy=FolderTreeWidgetProxyModel::None)
Definition: foldertreewidget.cpp:85
KernelIf
#define KernelIf
Definition: mailkernel.h:186
foldertreewidgetproxymodel.h
entitycollectionorderproxymodel.h
text
const char * text
Definition: mdnadvicedialog.cpp:52
QWidget
MailCommon::FolderTreeWidget::ToolTipDisplayPolicy
ToolTipDisplayPolicy
The possible tooltip display policies.
Definition: foldertreewidget.h:76
MailCommon::FolderTreeWidget::DisplayNever
Nevery display tooltips.
Definition: foldertreewidget.h:79
MailCommon::FolderTreeWidget::currentIndex
QModelIndex currentIndex() const
Definition: foldertreewidget.cpp:221
QObject
MailCommon::FolderTreeWidget::slotFilterFixedString
void slotFilterFixedString(const QString &)
Definition: foldertreewidget.cpp:164
MailCommon::FolderTreeWidget::folderTreeWidgetProxyModel
FolderTreeWidgetProxyModel * folderTreeWidgetProxyModel() const
Definition: foldertreewidget.cpp:345
MailCommon::FolderTreeWidget::ShowUnreadCount
Definition: foldertreewidget.h:57
MailCommon::FolderTreeView
This is an enhanced EntityTreeView specially suited for the folders in KMail's main folder widget...
Definition: foldertreeview.h:41
MailCommon::FolderTreeWidget::restoreHeaderState
void restoreHeaderState(const QByteArray &data)
Definition: foldertreewidget.cpp:299
foldertreeview.h
MailCommon::FolderTreeWidget::filterFolderLineEdit
KLineEdit * filterFolderLineEdit() const
Definition: foldertreewidget.cpp:355
foldertreewidget.h
MailCommon::FolderTreeWidgetProxyModel
Definition: foldertreewidgetproxymodel.h:28
MailCommon::FolderTreeWidget::ShowCollectionStatisticAnimation
Definition: foldertreewidget.h:60
MailCommon::FolderTreeWidget::UseDistinctSelectionModel
Definition: foldertreewidget.h:59
QAbstractItemModel
MailCommon::FolderTreeWidget::clearFilter
void clearFilter()
Definition: foldertreewidget.cpp:381
MailCommon::FolderTreeWidget::selectCollectionFolder
void selectCollectionFolder(const Akonadi::Collection &col)
Definition: foldertreewidget.cpp:196
MailCommon::FolderTreeWidget::folderTreeView
FolderTreeView * folderTreeView() const
Definition: foldertreewidget.cpp:259
MailCommon::EntityCollectionOrderProxyModel
Definition: entitycollectionorderproxymodel.h:26
MailCommon::FolderTreeWidget::selectionMode
QAbstractItemView::SelectionMode selectionMode() const
Definition: foldertreewidget.cpp:211
MailCommon::FolderTreeWidget::selectedCollection
Akonadi::Collection selectedCollection() const
Definition: foldertreewidget.cpp:226
MailCommon::FolderTreeWidget::disableContextMenuAndExtraColumn
void disableContextMenuAndExtraColumn()
Definition: foldertreewidget.cpp:191
MailCommon::FolderTreeWidget::slotManualSortingChanged
void slotManualSortingChanged(bool)
Definition: foldertreewidget.cpp:391
mailkernel.h
MailCommon::FolderTreeWidget::statisticsProxyModel
KPIM::StatisticsProxyModel * statisticsProxyModel() const
Definition: foldertreewidget.cpp:340
MailCommon::FolderTreeWidget::~FolderTreeWidget
~FolderTreeWidget()
Definition: foldertreewidget.cpp:159
MailCommon::FolderTreeWidget::selectionModel
QItemSelectionModel * selectionModel() const
Definition: foldertreewidget.cpp:216
MailCommon::FolderTreeWidget::slotGeneralPaletteChanged
void slotGeneralPaletteChanged()
Definition: foldertreewidget.cpp:272
MailCommon::FolderTreeWidget::quotaWarningParameters
void quotaWarningParameters(const QColor &color, qreal threshold)
Definition: foldertreewidget.cpp:322
MailCommon::FolderTreeWidget::readConfig
void readConfig()
Definition: foldertreewidget.cpp:278
MailCommon::FolderTreeWidget::entityOrderProxy
EntityCollectionOrderProxyModel * entityOrderProxy() const
Definition: foldertreewidget.cpp:350
MailCommon::FolderTreeWidget::selectedCollections
Akonadi::Collection::List selectedCollections() const
Definition: foldertreewidget.cpp:240
MailCommon::FolderTreeWidget::DisplayWhenTextElided
Display the tooltip if the item text is actually elided.
Definition: foldertreewidget.h:78
MailCommon::FolderTreeWidget::slotGeneralFontChanged
void slotGeneralFontChanged()
Definition: foldertreewidget.cpp:264
MailCommon::FolderTreeWidget::slotChangeTooltipsPolicy
void slotChangeTooltipsPolicy(FolderTreeWidget::ToolTipDisplayPolicy)
Definition: foldertreewidget.cpp:304
MailCommon::FolderTreeWidget::setSelectionMode
void setSelectionMode(QAbstractItemView::SelectionMode mode)
Definition: foldertreewidget.cpp:206
MailCommon::FolderTreeWidget::DontKeyFilter
Definition: foldertreewidget.h:61
MailCommon::FolderTreeWidget::readQuotaConfig
void readQuotaConfig()
Definition: foldertreewidget.cpp:328
MailCommon::FolderTreeWidget::changeToolTipsPolicyConfig
void changeToolTipsPolicyConfig(ToolTipDisplayPolicy)
Definition: foldertreewidget.cpp:309
mailutil.h
MailCommon::FolderTreeWidget::DisplayAlways
Always display a tooltip when hovering over an item.
Definition: foldertreewidget.h:77
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:55:14 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

mailcommon

Skip menu "mailcommon"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

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