• Skip to content
  • Skip to link menu
KDE 4.2 API Reference
  • KDE API Reference
  • kdelibs
  • Sitemap
  • Contact Us
 

KDEUI

keditlistbox.cpp

Go to the documentation of this file.
00001 /* This file is part of the KDE libraries
00002    Copyright (C) 2000 David Faure <faure@kde.org>, Alexander Neundorf <neundorf@kde.org>
00003    2000, 2002 Carsten Pfeiffer <pfeiffer@kde.org>
00004 
00005    This library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Library General Public
00007    License as published by the Free Software Foundation; either
00008    version 2 of the License, or (at your option) any later version.
00009 
00010    This library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Library General Public License for more details.
00014 
00015    You should have received a copy of the GNU Library General Public License
00016    along with this library; see the file COPYING.LIB.  If not, write to
00017    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018    Boston, MA 02110-1301, USA.
00019 */
00020 
00021 #include "keditlistbox.h"
00022 
00023 #include <QtCore/QStringList>
00024 #include <QtGui/QKeyEvent>
00025 #include <QtGui/QLabel>
00026 #include <QtGui/QLayout>
00027 #include <QtGui/QListView>
00028 
00029 #include <kcombobox.h>
00030 #include <kdebug.h>
00031 #include <kdialog.h>
00032 #include <klineedit.h>
00033 #include <klocale.h>
00034 #include <knotification.h>
00035 #include <kpushbutton.h>
00036 
00037 #include <assert.h>
00038 
00039 class KEditListBoxPrivate
00040 {
00041 public:
00042     KEditListBoxPrivate( KEditListBox* parent )
00043         : lineEdit(0),
00044           editingWidget(0),
00045           q(parent) {
00046     }
00047     QListView *listView;
00048     QPushButton *servUpButton, *servDownButton;
00049     QPushButton *servNewButton, *servRemoveButton;
00050     KLineEdit *lineEdit;
00051     QWidget* editingWidget;
00052     QVBoxLayout* mainLayout;
00053     QVBoxLayout* btnsLayout;
00054     QStringListModel *model;
00055 
00056     bool checkAtEntering;
00057     KEditListBox::Buttons buttons;
00058 
00059     void init( bool checkAtEntering = false, KEditListBox::Buttons buttons = KEditListBox::All,
00060                QWidget *representationWidget = 0 );
00061     void setEditor( KLineEdit* lineEdit, QWidget* representationWidget = 0 );
00062     void updateButtonState();
00063     QModelIndex selectedIndex();
00064 
00065 private:
00066     KEditListBox* q;
00067 };
00068 
00069 
00070 void KEditListBoxPrivate::init( bool checkAtEntering, KEditListBox::Buttons newButtons,
00071                                 QWidget *representationWidget )
00072 {
00073     checkAtEntering = checkAtEntering;
00074 
00075     servNewButton = servRemoveButton = servUpButton = servDownButton = 0L;
00076     q->setSizePolicy(QSizePolicy(QSizePolicy::MinimumExpanding,
00077                                  QSizePolicy::Preferred));
00078 
00079     mainLayout = new QVBoxLayout(q);
00080 
00081     QHBoxLayout* subLayout = new QHBoxLayout;
00082     btnsLayout = new QVBoxLayout;
00083     btnsLayout->addStretch();
00084 
00085     model = new QStringListModel();
00086     listView = new QListView(q);
00087     listView->setModel(model);
00088 
00089     subLayout->addWidget(listView);
00090     subLayout->addLayout(btnsLayout);
00091 
00092     mainLayout->insertLayout(1, subLayout);
00093 
00094     setEditor( lineEdit, representationWidget );
00095 
00096     buttons = 0;
00097     q->setButtons( newButtons );
00098 
00099     q->connect(listView->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)),
00100                SLOT(slotSelectionChanged(const QItemSelection&, const QItemSelection&)));
00101 }
00102 
00103 
00104 void KEditListBoxPrivate::setEditor( KLineEdit* newLineEdit, QWidget* representationWidget )
00105 {
00106     if (editingWidget != lineEdit &&
00107         editingWidget != representationWidget) {
00108         delete editingWidget;
00109     }
00110     if (lineEdit != newLineEdit) {
00111         delete lineEdit;
00112     }
00113     lineEdit = newLineEdit ? newLineEdit : new KLineEdit(q);
00114     editingWidget = representationWidget ?
00115                     representationWidget : lineEdit;
00116 
00117     if ( representationWidget )
00118         representationWidget->setParent(q);
00119 
00120     mainLayout->insertWidget(0,editingWidget);
00121 
00122     lineEdit->setTrapReturnKey(true);
00123     lineEdit->installEventFilter(q);
00124 
00125     q->connect(lineEdit,SIGNAL(textChanged(const QString&)),SLOT(typedSomething(const QString&)));
00126     q->connect(lineEdit,SIGNAL(returnPressed()),SLOT(addItem()));
00127 
00128     // maybe supplied lineedit has some text already
00129     q->typedSomething( lineEdit->text() );
00130 
00131 
00132     // fix tab ordering
00133     q->setTabOrder(editingWidget, listView);
00134     QWidget* w = listView;
00135     if (servNewButton) {
00136         q->setTabOrder(w,servNewButton);
00137         w = servNewButton;
00138     }
00139     if (servRemoveButton) {
00140         q->setTabOrder(w,servRemoveButton);
00141         w = servRemoveButton;
00142     }
00143     if (servUpButton) {
00144         q->setTabOrder(w,servUpButton);
00145         w = servUpButton;
00146     }
00147     if (servDownButton) {
00148         q->setTabOrder(w,servDownButton);
00149         w = servDownButton;
00150     }
00151 }
00152 
00153 
00154 void KEditListBoxPrivate::updateButtonState()
00155 {
00156     QModelIndex index = selectedIndex();
00157     if (servUpButton) {
00158         servUpButton->setEnabled(index.isValid());
00159     }
00160     if (servDownButton) {
00161         servDownButton->setEnabled(index.isValid());
00162     }
00163     if (servRemoveButton) {
00164         servRemoveButton->setEnabled(index.isValid());
00165     }
00166 }
00167 
00168 QModelIndex KEditListBoxPrivate::selectedIndex()
00169 {
00170     QItemSelectionModel *selection = listView->selectionModel();
00171     const QModelIndexList selectedIndexes = selection->selectedIndexes();
00172     if ( !selectedIndexes.isEmpty() && selectedIndexes[0].isValid() )
00173         return selectedIndexes[0];
00174     else
00175         return QModelIndex();
00176 }
00177 
00178 
00179 class KEditListBox::CustomEditorPrivate
00180 {
00181 public:
00182     CustomEditorPrivate(KEditListBox::CustomEditor *q):
00183         q(q),
00184         representationWidget(0),
00185         lineEdit(0) {}
00186 
00187     KEditListBox::CustomEditor *q;
00188     QWidget *representationWidget;
00189     KLineEdit *lineEdit;
00190 };
00191 
00192 KEditListBox::CustomEditor::CustomEditor()
00193     : d(new CustomEditorPrivate(this))
00194 {
00195 }
00196 
00197 KEditListBox::CustomEditor::CustomEditor( QWidget *repWidget, KLineEdit *edit )
00198     : d(new CustomEditorPrivate(this))
00199 {
00200     d->representationWidget = repWidget;
00201     d->lineEdit = edit;
00202 }
00203 
00204 KEditListBox::CustomEditor::CustomEditor( KComboBox *combo )
00205     : d(new CustomEditorPrivate(this))
00206 {
00207     d->representationWidget = combo;
00208     d->lineEdit = qobject_cast<KLineEdit*>( combo->lineEdit() );
00209     Q_ASSERT( d->lineEdit );
00210 }
00211 
00212 KEditListBox::CustomEditor::~CustomEditor()
00213 {
00214     delete d;
00215 }
00216 
00217 void KEditListBox::CustomEditor::setRepresentationWidget( QWidget *repWidget )
00218 {
00219     d->representationWidget = repWidget;
00220 }
00221 
00222 void KEditListBox::CustomEditor::setLineEdit( KLineEdit *edit )
00223 {
00224     d->lineEdit = edit;
00225 }
00226 
00227 QWidget *KEditListBox::CustomEditor::representationWidget() const
00228 {
00229     return d->representationWidget;
00230 }
00231 
00232 KLineEdit *KEditListBox::CustomEditor::lineEdit() const
00233 {
00234     return d->lineEdit;
00235 }
00236 
00237 KEditListBox::KEditListBox(QWidget *parent)
00238     : QGroupBox(parent), d(new KEditListBoxPrivate(this))
00239 {
00240     d->init();
00241 }
00242 
00243 KEditListBox::KEditListBox(const QString &title, QWidget *parent)
00244     :QGroupBox(title, parent), d(new KEditListBoxPrivate(this))
00245 {
00246     d->init();
00247 }
00248 
00249 KEditListBox::KEditListBox(QWidget *parent, const char *name,
00250                            bool checkAtEntering, Buttons buttons )
00251     :QGroupBox(parent ), d(new KEditListBoxPrivate(this))
00252 {
00253     setObjectName(name);
00254     d->init( checkAtEntering, buttons );
00255 }
00256 
00257 KEditListBox::KEditListBox(const QString& title, QWidget *parent,
00258                            const char *name, bool checkAtEntering, Buttons buttons)
00259     :QGroupBox(title, parent ), d(new KEditListBoxPrivate(this))
00260 {
00261     setObjectName(name);
00262     d->init( checkAtEntering, buttons );
00263 }
00264 
00265 KEditListBox::KEditListBox(const QString& title, const CustomEditor& custom,
00266                            QWidget *parent, const char *name,
00267                            bool checkAtEntering, Buttons buttons)
00268     :QGroupBox(title, parent), d(new KEditListBoxPrivate(this))
00269 {
00270     setObjectName(name);
00271     d->lineEdit = custom.lineEdit();
00272     d->init( checkAtEntering, buttons, custom.representationWidget() );
00273 }
00274 
00275 KEditListBox::~KEditListBox()
00276 {
00277     delete d;
00278 }
00279 
00280 void KEditListBox::setCustomEditor( const CustomEditor& editor )
00281 {
00282     d->setEditor( editor.lineEdit(), editor.representationWidget() );
00283 }
00284 
00285 QListView *KEditListBox::listView() const
00286 {
00287     return d->listView;
00288 }
00289 
00290 KLineEdit *KEditListBox::lineEdit() const
00291 {
00292     return d->lineEdit;
00293 }
00294 
00295 QPushButton *KEditListBox::addButton() const
00296 {
00297     return d->servNewButton;
00298 }
00299 
00300 QPushButton *KEditListBox::removeButton() const
00301 {
00302     return d->servRemoveButton;
00303 }
00304 
00305 QPushButton *KEditListBox::upButton() const
00306 {
00307     return d->servUpButton;
00308 }
00309 
00310 QPushButton *KEditListBox::downButton() const
00311 {
00312     return d->servDownButton;
00313 }
00314 
00315 int KEditListBox::count() const
00316 {
00317     return int(d->model->rowCount());
00318 }
00319 
00320 void KEditListBox::setButtons( Buttons buttons )
00321 {
00322     if ( d->buttons == buttons )
00323         return;
00324 
00325     if ( ( buttons & Add ) && !d->servNewButton ) {
00326         d->servNewButton = new KPushButton(KIcon("list-add"), i18n("&Add"), this);
00327         d->servNewButton->setEnabled(false);
00328         d->servNewButton->show();
00329         connect(d->servNewButton, SIGNAL(clicked()), SLOT(addItem()));
00330 
00331         d->btnsLayout->insertWidget(0, d->servNewButton);
00332     } else if ( ( buttons & Add ) == 0 && d->servNewButton ) {
00333         delete d->servNewButton;
00334         d->servNewButton = 0;
00335     }
00336 
00337     if ( ( buttons & Remove ) && !d->servRemoveButton ) {
00338         d->servRemoveButton = new KPushButton(KIcon("list-remove"), i18n("&Remove"), this);
00339         d->servRemoveButton->setEnabled(false);
00340         d->servRemoveButton->show();
00341         connect(d->servRemoveButton, SIGNAL(clicked()), SLOT(removeItem()));
00342 
00343         d->btnsLayout->insertWidget(1, d->servRemoveButton);
00344     } else if ( ( buttons & Remove ) == 0 && d->servRemoveButton ) {
00345         delete d->servRemoveButton;
00346         d->servRemoveButton = 0;
00347     }
00348 
00349     if ( ( buttons & UpDown ) && !d->servUpButton ) {
00350         d->servUpButton = new KPushButton(KIcon("arrow-up"), i18n("Move &Up"), this);
00351         d->servUpButton->setEnabled(false);
00352         d->servUpButton->show();
00353         connect(d->servUpButton, SIGNAL(clicked()), SLOT(moveItemUp()));
00354 
00355         d->servDownButton = new KPushButton(KIcon("arrow-down"), i18n("Move &Down"), this);
00356         d->servDownButton->setEnabled(false);
00357         d->servDownButton->show();
00358         connect(d->servDownButton, SIGNAL(clicked()), SLOT(moveItemDown()));
00359 
00360         d->btnsLayout->insertWidget(2, d->servUpButton);
00361         d->btnsLayout->insertWidget(3, d->servDownButton);
00362     } else if ( ( buttons & UpDown ) == 0 && d->servUpButton ) {
00363         delete d->servUpButton; d->servUpButton = 0;
00364         delete d->servDownButton; d->servDownButton = 0;
00365     }
00366 
00367     d->buttons = buttons;
00368 }
00369 
00370 void KEditListBox::setCheckAtEntering(bool check)
00371 {
00372     d->checkAtEntering = check;
00373 }
00374 
00375 bool KEditListBox::checkAtEntering()
00376 {
00377     return d->checkAtEntering;
00378 }
00379 
00380 void KEditListBox::typedSomething(const QString& text)
00381 {
00382     if(currentItem() >= 0) {
00383         if(currentText() != d->lineEdit->text())
00384         {
00385             // IMHO changeItem() shouldn't do anything with the value
00386             // of currentItem() ... like changing it or emitting signals ...
00387             // but TT disagree with me on this one (it's been that way since ages ... grrr)
00388             bool block = d->listView->signalsBlocked();
00389             d->listView->blockSignals( true );
00390             QModelIndex currentIndex = d->selectedIndex();
00391             if ( currentIndex.isValid() )
00392               d->model->setData(currentIndex,text);
00393             d->listView->blockSignals( block );
00394             emit changed();
00395         }
00396     }
00397 
00398     if ( !d->servNewButton )
00399         return;
00400 
00401     if (!d->checkAtEntering)
00402         d->servNewButton->setEnabled(!text.isEmpty());
00403     else
00404     {
00405         if (text.isEmpty())
00406         {
00407             d->servNewButton->setEnabled(false);
00408         }
00409         else
00410         {
00411             QStringList list = d->model->stringList();
00412             bool enable = !list.contains( text, Qt::CaseSensitive );
00413             d->servNewButton->setEnabled( enable );
00414         }
00415     }
00416 }
00417 
00418 void KEditListBox::moveItemUp()
00419 {
00420     if (!d->listView->isEnabled())
00421     {
00422         KNotification::beep();
00423         return;
00424     }
00425 
00426     QModelIndex index = d->selectedIndex();
00427     if ( index.isValid() ) {
00428       if (index.row() == 0) {
00429           KNotification::beep();
00430           return;
00431       }
00432 
00433       QModelIndex aboveIndex = d->model->index( index.row() - 1, index.column() );
00434 
00435       QString tmp = d->model->data( aboveIndex, Qt::DisplayRole ).toString();
00436       d->model->setData( aboveIndex, d->model->data( index, Qt::DisplayRole ) );
00437       d->model->setData( index, tmp );
00438 
00439       d->listView->selectionModel()->select(index, QItemSelectionModel::Deselect);
00440       d->listView->selectionModel()->select(aboveIndex, QItemSelectionModel::Select);
00441     }
00442 
00443     emit changed();
00444 }
00445 
00446 void KEditListBox::moveItemDown()
00447 {
00448     if (!d->listView->isEnabled())
00449     {
00450         KNotification::beep();
00451         return;
00452     }
00453 
00454     QModelIndex index = d->selectedIndex();
00455     if ( index.isValid() ) {
00456       if (index.row() == d->model->rowCount() - 1) {
00457           KNotification::beep();
00458           return;
00459       }
00460 
00461       QModelIndex belowIndex = d->model->index( index.row() + 1, index.column() );
00462 
00463       QString tmp = d->model->data( belowIndex, Qt::DisplayRole ).toString();
00464       d->model->setData( belowIndex, d->model->data( index, Qt::DisplayRole ) );
00465       d->model->setData( index, tmp );
00466 
00467       d->listView->selectionModel()->select(index, QItemSelectionModel::Deselect);
00468       d->listView->selectionModel()->select(belowIndex, QItemSelectionModel::Select);
00469     }
00470 
00471     emit changed();
00472 }
00473 
00474 void KEditListBox::addItem()
00475 {
00476     // when checkAtEntering is true, the add-button is disabled, but this
00477     // slot can still be called through Key_Return/Key_Enter. So we guard
00478     // against this.
00479     if ( !d->servNewButton || !d->servNewButton->isEnabled() )
00480         return;
00481 
00482     QModelIndex currentIndex = d->selectedIndex();
00483 
00484     const QString& currentTextLE=d->lineEdit->text();
00485     bool alreadyInList(false);
00486     //if we didn't check for dupes at the inserting we have to do it now
00487     if (!d->checkAtEntering)
00488     {
00489         // first check current item instead of dumb iterating the entire list
00490         if ( currentIndex.isValid() ) {
00491           if ( d->model->data( currentIndex, Qt::DisplayRole ).toString() == currentTextLE )
00492             alreadyInList = true;
00493         }
00494         else
00495         {
00496             alreadyInList = d->model->stringList().contains( currentTextLE, Qt::CaseSensitive );
00497         }
00498     }
00499     if ( d->servNewButton )
00500         d->servNewButton->setEnabled(false);
00501 
00502     bool block = d->lineEdit->signalsBlocked();
00503     d->lineEdit->blockSignals(true);
00504     d->lineEdit->clear();
00505     d->lineEdit->blockSignals(block);
00506 
00507     d->listView->selectionModel()->setCurrentIndex(currentIndex, QItemSelectionModel::Deselect);
00508 
00509     if (!alreadyInList)
00510     {
00511         block = d->listView->signalsBlocked();
00512 
00513         if ( currentIndex.isValid() ) {
00514           d->model->setData(currentIndex, currentTextLE );
00515         } else {
00516             QStringList lst;
00517             lst<<currentTextLE;
00518             lst<<d->model->stringList();
00519             d->model->setStringList(lst);
00520         }
00521         emit changed();
00522         emit added( currentTextLE );
00523     }
00524 
00525     d->updateButtonState();
00526 }
00527 
00528 int KEditListBox::currentItem() const
00529 {
00530     QModelIndex selectedIndex = d->selectedIndex();
00531     if ( selectedIndex.isValid() )
00532         return selectedIndex.row();
00533     else
00534         return -1;
00535 }
00536 
00537 void KEditListBox::removeItem()
00538 {
00539     QModelIndex currentIndex = d->selectedIndex();
00540     if ( !currentIndex.isValid() )
00541       return;
00542 
00543     if ( currentIndex.row() >= 0 )
00544     {
00545         QString removedText = d->model->data( currentIndex, Qt::DisplayRole ).toString();
00546 
00547         d->model->removeRows( currentIndex.row(), 1 );
00548 
00549         d->listView->selectionModel()->clear();
00550 
00551         emit changed();
00552 
00553         emit removed( removedText );
00554     }
00555 
00556     d->updateButtonState();
00557 }
00558 
00559 void KEditListBox::enableMoveButtons(const QModelIndex &newIndex, const QModelIndex&)
00560 {
00561     int index = newIndex.row();
00562 
00563     // Update the lineEdit when we select a different line.
00564     if(currentText() != d->lineEdit->text())
00565         d->lineEdit->setText(currentText());
00566 
00567     bool moveEnabled = d->servUpButton && d->servDownButton;
00568 
00569     if (moveEnabled )
00570     {
00571         if (d->model->rowCount() <= 1)
00572         {
00573             d->servUpButton->setEnabled(false);
00574             d->servDownButton->setEnabled(false);
00575         }
00576         else if (index == (d->model->rowCount() - 1))
00577         {
00578             d->servUpButton->setEnabled(true);
00579             d->servDownButton->setEnabled(false);
00580         }
00581         else if (index == 0)
00582         {
00583             d->servUpButton->setEnabled(false);
00584             d->servDownButton->setEnabled(true);
00585         }
00586         else
00587         {
00588             d->servUpButton->setEnabled(true);
00589             d->servDownButton->setEnabled(true);
00590         }
00591     }
00592 
00593     if ( d->servRemoveButton )
00594         d->servRemoveButton->setEnabled(true);
00595 }
00596 
00597 void KEditListBox::clear()
00598 {
00599     d->lineEdit->clear();
00600     d->model->setStringList( QStringList() );
00601     emit changed();
00602 }
00603 
00604 void KEditListBox::insertStringList(const QStringList& list, int index)
00605 {
00606     QStringList content = d->model->stringList();
00607     if ( index > content.count() )
00608       content += list;
00609     else
00610       for ( int i = 0, j = index; i < list.count(); ++i, ++j )
00611         content.insert( j, list[ i ] );
00612 
00613     d->model->setStringList( content );
00614 }
00615 
00616 void KEditListBox::insertItem(const QString& text, int index)
00617 {
00618   QStringList list = d->model->stringList();
00619 
00620   if ( index == -1 )
00621     list.append( text );
00622   else
00623     list.insert( index, text );
00624 
00625   d->model->setStringList(list);
00626 }
00627 
00628 QString KEditListBox::text(int index) const
00629 {
00630   const QStringList list = d->model->stringList();
00631 
00632   return list[ index ];
00633 }
00634 
00635 QString KEditListBox::currentText() const
00636 {
00637   QModelIndex index = d->selectedIndex();
00638   if ( !index.isValid() )
00639     return QString();
00640   else
00641     return text( index.row() );
00642 }
00643 
00644 QStringList KEditListBox::items() const
00645 {
00646     return d->model->stringList();
00647 }
00648 
00649 void KEditListBox::setItems(const QStringList& items)
00650 {
00651   d->model->setStringList(items);
00652 }
00653 
00654 KEditListBox::Buttons KEditListBox::buttons() const
00655 {
00656   return d->buttons;
00657 }
00658 
00659 void KEditListBox::slotSelectionChanged( const QItemSelection&, const QItemSelection& )
00660 {
00661     d->updateButtonState();
00662     QModelIndex index = d->selectedIndex();
00663     enableMoveButtons(index,  QModelIndex());
00664     if (index.isValid()) {
00665         d->lineEdit->setFocus( Qt::OtherFocusReason );
00666     }
00667 }
00668 
00669 bool KEditListBox::eventFilter( QObject* o, QEvent* e )
00670 {
00671     if (o == d->lineEdit && e->type() == QEvent::KeyPress ) {
00672         QKeyEvent* keyEvent = (QKeyEvent*)e;
00673         if (keyEvent->key() == Qt::Key_Down ||
00674             keyEvent->key() == Qt::Key_Up) {
00675             return ((QObject*)d->listView)->event(e);
00676         }
00677     }
00678 
00679     return false;
00680 }
00681 
00682 #include "keditlistbox.moc"

KDEUI

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

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • Kross
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.5.7
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal