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

Kate

kateview.h

Go to the documentation of this file.
00001 /* This file is part of the KDE libraries
00002    Copyright (C) 2002 John Firebaugh <jfirebaugh@kde.org>
00003    Copyright (C) 2001 Christoph Cullmann <cullmann@kde.org>
00004    Copyright (C) 2001 Joseph Wenninger <jowenn@kde.org>
00005    Copyright (C) 1999 Jochen Wilhelmy <digisnap@cs.tu-berlin.de>
00006 
00007    This library is free software; you can redistribute it and/or
00008    modify it under the terms of the GNU Library General Public
00009    License version 2 as published by the Free Software Foundation.
00010 
00011    This library is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014    Library General Public License for more details.
00015 
00016    You should have received a copy of the GNU Library General Public License
00017    along with this library; see the file COPYING.LIB.  If not, write to
00018    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00019    Boston, MA 02110-1301, USA.
00020 */
00021 
00022 #ifndef kate_view_h
00023 #define kate_view_h
00024 
00025 #include "kateviinputmodemanager.h"
00026 
00027 #include <ktexteditor/view.h>
00028 #include <ktexteditor/texthintinterface.h>
00029 #include <ktexteditor/markinterface.h>
00030 #include <ktexteditor/codecompletioninterface.h>
00031 #include <ktexteditor/sessionconfiginterface.h>
00032 #include <ktexteditor/templateinterface.h>
00033 #include <ktexteditor/rangefeedback.h>
00034 #include <ktexteditor/configinterface.h>
00035 #include <ktexteditor/annotationinterface.h>
00036 
00037 #include <QtCore/QPointer>
00038 #include <QModelIndex>
00039 #include <QtGui/QMenu>
00040 #include <QtCore/QLinkedList>
00041 #include <QtCore/QHash>
00042 
00043 #include <kdebug.h>
00044 
00045 namespace KTextEditor
00046 {
00047   class AnnotationModel;
00048 }
00049 
00050 class KateDocument;
00051 class KateBookmarks;
00052 class KateCmdLine;
00053 class KateViewConfig;
00054 class KateRenderer;
00055 class KateSpellCheckDialog;
00056 class KateCompletionWidget;
00057 class KateSmartRange;
00058 class KateViewInternal;
00059 class KateSearchBar;
00060 class KateViModeBar;
00061 class KateViewBar;
00062 class KateGotoBar;
00063 class KateDictionaryBar;
00064 class KateSpellingMenu;
00065 
00066 class KToggleAction;
00067 class KAction;
00068 class KRecentFilesAction;
00069 class KSelectAction;
00070 
00071 class QVBoxLayout;
00072 
00073 //
00074 // Kate KTextEditor::View class ;)
00075 //
00076 class KateView : public KTextEditor::View,
00077                  public KTextEditor::TextHintInterface,
00078                  public KTextEditor::SessionConfigInterface,
00079                  public KTextEditor::TemplateInterface,
00080                  public KTextEditor::CodeCompletionInterface,
00081                  public KTextEditor::ConfigInterface,
00082                  private KTextEditor::SmartRangeWatcher,
00083                  public KTextEditor::AnnotationViewInterface,
00084                  public KTextEditor::CoordinatesToCursorInterface
00085 {
00086     Q_OBJECT
00087     Q_INTERFACES(KTextEditor::TextHintInterface)
00088     Q_INTERFACES(KTextEditor::SessionConfigInterface)
00089     Q_INTERFACES(KTextEditor::TemplateInterface)
00090     Q_INTERFACES(KTextEditor::ConfigInterface)
00091     Q_INTERFACES(KTextEditor::CodeCompletionInterface)
00092     Q_INTERFACES(KTextEditor::AnnotationViewInterface)
00093     Q_INTERFACES(KTextEditor::CoordinatesToCursorInterface)
00094 
00095     friend class KateViewInternal;
00096     friend class KateIconBorder;
00097     friend class KateSearchBar;
00098     friend class KateViModeBase;
00099 
00100   public:
00101     KateView( KateDocument* doc, QWidget* parent );
00102     ~KateView ();
00103 
00104     KTextEditor::Document *document () const;
00105 
00106     QString viewMode () const;
00107 
00108   //
00109   // KTextEditor::ClipboardInterface
00110   //
00111   public Q_SLOTS:
00112     // TODO: Factor out of m_viewInternal
00113     void paste();
00114     void cut();
00115     void copy() const;
00116 
00117   private Q_SLOTS:
00121     void applyWordWrap ();
00122 
00123   //
00124   // KTextEditor::PopupMenuInterface
00125   //
00126   public:
00127     void setContextMenu( QMenu* menu );
00128     QMenu* contextMenu() const;
00129     QMenu* defaultContextMenu(QMenu* menu = 0L) const;
00130 
00131   private Q_SLOTS:
00132     void aboutToShowContextMenu();
00133 
00134   private:
00135     QPointer<QMenu> m_contextMenu;
00136 
00137   //
00138   // KTextEditor::ViewCursorInterface
00139   //
00140   public:
00141     bool setCursorPosition (KTextEditor::Cursor position);
00142 
00143     KTextEditor::Cursor cursorPosition () const;
00144 
00145     KTextEditor::Cursor cursorPositionVirtual () const;
00146 
00147     QPoint cursorToCoordinate(const KTextEditor::Cursor& cursor) const;
00148 
00149     KTextEditor::Cursor coordinatesToCursor(const QPoint& coord) const;
00150 
00151     QPoint cursorPositionCoordinates() const;
00152 
00153     bool setCursorPositionVisual( const KTextEditor::Cursor& position );
00154 
00160     int virtualCursorColumn() const;
00161 
00162     virtual bool mouseTrackingEnabled() const;
00163     virtual bool setMouseTrackingEnabled(bool enable);
00164 
00165   private:
00166     void notifyMousePositionChanged(const KTextEditor::Cursor& newPosition);
00167 
00168   // Internal
00169   public:
00170     bool setCursorPositionInternal( const KTextEditor::Cursor& position, uint tabwidth = 1, bool calledExternally = false );
00171 
00172   //
00173   // KTextEditor::ConfigInterface
00174   //
00175   public:
00176      QStringList configKeys() const;
00177      QVariant configValue(const QString &key);
00178      void setConfigValue(const QString &key, const QVariant &value);
00179 
00180   Q_SIGNALS:
00181     void configChanged();
00182 
00183   //
00184   // KTextEditor::CodeCompletionInterface2
00185   //
00186   public:
00187     virtual bool isCompletionActive() const;
00188     virtual void startCompletion(const KTextEditor::Range& word, KTextEditor::CodeCompletionModel* model);
00189     virtual void abortCompletion();
00190     virtual void forceCompletion();
00191     virtual void registerCompletionModel(KTextEditor::CodeCompletionModel* model);
00192     virtual void unregisterCompletionModel(KTextEditor::CodeCompletionModel* model);
00193     virtual bool isAutomaticInvocationEnabled() const;
00194     virtual void setAutomaticInvocationEnabled(bool enabled = true);
00195 
00196   Q_SIGNALS:
00197     void completionExecuted(KTextEditor::View* view, const KTextEditor::Cursor& position, KTextEditor::CodeCompletionModel* model, const QModelIndex&);
00198     void completionAborted(KTextEditor::View* view);
00199 
00200   public Q_SLOTS:
00201     void userInvokedCompletion();
00202 
00203   public:
00204     KateCompletionWidget* completionWidget() const;
00205     mutable KateCompletionWidget* m_completionWidget;
00206     void sendCompletionExecuted(const KTextEditor::Cursor& position, KTextEditor::CodeCompletionModel* model, const QModelIndex& index);
00207     void sendCompletionAborted();
00208 
00209   //
00210   // KTextEditor::TextHintInterface
00211   //
00212   public:
00213     void enableTextHints(int timeout);
00214     void disableTextHints();
00215 
00216   Q_SIGNALS:
00217     void needTextHint(const KTextEditor::Cursor& position, QString &text);
00218 
00219   public:
00220     bool dynWordWrap() const      { return m_hasWrap; }
00221 
00222   //
00223   // KTextEditor::SelectionInterface stuff
00224   //
00225   public Q_SLOTS:
00226     virtual bool setSelection ( const KTextEditor::Range &selection );
00227 
00228     // unhide method...
00229     bool setSelection (const KTextEditor::Cursor &c, int i, bool b)
00230     { return KTextEditor::View::setSelection (c, i, b); }
00231 
00232     virtual bool removeSelection () { return clearSelection(); }
00233 
00234     virtual bool removeSelectionText () { return removeSelectedText(); }
00235 
00236     virtual bool setBlockSelection (bool on) { return setBlockSelectionMode (on); }
00237 
00238     bool clearSelection ();
00239     bool clearSelection (bool redraw, bool finishedChangingSelection = true);
00240 
00241     bool removeSelectedText ();
00242 
00243     bool selectAll();
00244 
00245   public:
00246     virtual bool selection() const;
00247     virtual QString selectionText() const;
00248     virtual bool blockSelection() const { return blockSelectionMode(); }
00249     virtual const KTextEditor::Range &selectionRange() const;
00250 
00251     static void blockFix(KTextEditor::Range& range);
00252 
00253   private:
00254     // TODO KDE5: remove
00255     mutable KTextEditor::Range m_holdSelectionRangeForAPI;
00256 
00257   //
00258   // Arbitrary Syntax HL + Action extensions
00259   //
00260   public:
00261     // Syntax highlighting extension
00262     void addExternalHighlight(KTextEditor::SmartRange* topRange, bool supportDynamic);
00263     const QList<KTextEditor::SmartRange*>& externalHighlights() const;
00264     void clearExternalHighlights();
00265 
00266     void addInternalHighlight(KTextEditor::SmartRange* topRange);
00267     void removeInternalHighlight(KTextEditor::SmartRange* topRange);
00268     const QList<KTextEditor::SmartRange*>& internalHighlights() const;
00269 
00270     // Action association extension
00271     void addActions(KTextEditor::SmartRange* topRange);
00272     const QList<KTextEditor::SmartRange*>& actions() const;
00273     void clearActions();
00274     void deactivateEditActions();
00275     void activateEditActions();
00276 
00277   Q_SIGNALS:
00278     void dynamicHighlightAdded(KateSmartRange* range);
00279     void dynamicHighlightRemoved(KateSmartRange* range);
00280 
00281   public Q_SLOTS:
00282     void removeExternalHighlight(KTextEditor::SmartRange* topRange);
00283     void removeActions(KTextEditor::SmartRange* topRange);
00284 
00285   private:
00286     // Smart range watcher overrides
00287     virtual void rangeDeleted(KTextEditor::SmartRange* range);
00288 
00289     QList<KTextEditor::SmartRange*> m_externalHighlights;
00290     QList<KTextEditor::SmartRange*> m_externalHighlightsDynamic;
00291     QList<KTextEditor::SmartRange*> m_internalHighlights;
00292     QList<KTextEditor::SmartRange*> m_actions;
00293 
00294     bool m_bottomBarExternal;
00295     bool m_topBarExternal;
00296 
00297   //
00298   // internal helper stuff, for katerenderer and so on
00299   //
00300   public:
00301     // should cursor be wrapped ? take config + blockselection state in account
00302     bool wrapCursor () const;
00303 
00304     // some internal functions to get selection state of a line/col
00305     bool cursorSelected(const KTextEditor::Cursor& cursor);
00306     bool lineSelected (int line);
00307     bool lineEndSelected (const KTextEditor::Cursor& lineEndPos);
00308     bool lineHasSelected (int line);
00309     bool lineIsSelection (int line);
00310 
00311     void ensureCursorColumnValid();
00312 
00313     void tagSelection (const KTextEditor::Range &oldSelection);
00314 
00315     void selectWord(   const KTextEditor::Cursor& cursor );
00316     void selectLine(   const KTextEditor::Cursor& cursor );
00317 
00318   //
00319   // KTextEditor::BlockSelectionInterface stuff
00320   //
00321   public Q_SLOTS:
00322     bool setBlockSelectionMode (bool on);
00323     bool toggleBlockSelectionMode ();
00324 
00325   public:
00326     bool blockSelectionMode() const;
00327 
00328 
00329   //BEGIN EDIT STUFF
00330   public:
00331     void editStart ();
00332     void editEnd (int editTagLineStart, int editTagLineEnd, bool tagFrom);
00333 
00334     void editSetCursor (const KTextEditor::Cursor &cursor);
00335   //END
00336 
00337   //BEGIN TAG & CLEAR
00338   public:
00339     bool tagLine (const KTextEditor::Cursor& virtualCursor);
00340 
00341     bool tagRange (const KTextEditor::Range& range, bool realLines = false);
00342     bool tagLines (int start, int end, bool realLines = false );
00343     bool tagLines (KTextEditor::Cursor start, KTextEditor::Cursor end, bool realCursors = false);
00344     bool tagLines (KTextEditor::Range range, bool realRange = false);
00345 
00346     void tagAll ();
00347 
00348     void relayoutRange(const KTextEditor::Range& range, bool realLines = false);
00349 
00350     void clear ();
00351 
00352     void repaintText (bool paintOnlyDirty = false);
00353 
00354     void updateView (bool changed = false);
00355   //END
00356 
00357   //
00358   // KTextEditor::AnnotationView
00359   //
00360   public:
00361     void setAnnotationModel( KTextEditor::AnnotationModel* model );
00362     KTextEditor::AnnotationModel* annotationModel() const;
00363     void setAnnotationBorderVisible( bool visible);
00364     bool isAnnotationBorderVisible() const;
00365 
00366   Q_SIGNALS:
00367     void annotationContextMenuAboutToShow( KTextEditor::View* view, QMenu* menu, int line );
00368     void annotationActivated( KTextEditor::View* view, int line );
00369     void annotationBorderVisibilityChanged( View* view, bool visible );
00370 
00371     void navigateLeft();
00372     void navigateRight();
00373     void navigateUp();
00374     void navigateDown();
00375     void navigateAccept();
00376     void navigateBack();
00377 
00378   private:
00379     KTextEditor::AnnotationModel* m_annotationModel;
00380 
00381   //
00382   // KTextEditor::View
00383   //
00384   public:
00385     void emitNavigateLeft() {
00386       emit navigateLeft();
00387     }
00388     void emitNavigateRight() {
00389       emit navigateRight();
00390     }
00391     void emitNavigateUp() {
00392       emit navigateUp();
00393     }
00394     void emitNavigateDown() {
00395       emit navigateDown();
00396     }
00397     void emitNavigateAccept() {
00398       emit navigateAccept();
00399     }
00400     void emitNavigateBack() {
00401       emit navigateBack();
00402     }
00406     bool isOverwriteMode() const;
00407     enum KTextEditor::View::EditMode viewEditMode() const {return isOverwriteMode() ? KTextEditor::View::EditOverwrite : KTextEditor::View::EditInsert;}
00408     QString currentTextLine();
00409     QString currentWord();
00410 
00411   public Q_SLOTS:
00412     void indent();
00413     void unIndent();
00414     void cleanIndent();
00415     void align();
00416     void comment();
00417     void uncomment();
00418     void killLine();
00419 
00423     void uppercase();
00427     void lowercase();
00432     void capitalize();
00436     void joinLines();
00437 
00438     // Note - the following functions simply forward to KateViewInternal
00439     void keyReturn();
00440     void smartNewline();
00441     void backspace();
00442     void deleteWordLeft();
00443     void keyDelete();
00444     void deleteWordRight();
00445     void transpose();
00446     void cursorLeft();
00447     void shiftCursorLeft();
00448     void cursorRight();
00449     void shiftCursorRight();
00450     void wordLeft();
00451     void shiftWordLeft();
00452     void wordRight();
00453     void shiftWordRight();
00454     void home();
00455     void shiftHome();
00456     void end();
00457     void shiftEnd();
00458     void up();
00459     void shiftUp();
00460     void down();
00461     void shiftDown();
00462     void scrollUp();
00463     void scrollDown();
00464     void topOfView();
00465     void shiftTopOfView();
00466     void bottomOfView();
00467     void shiftBottomOfView();
00468     void pageUp();
00469     void shiftPageUp();
00470     void pageDown();
00471     void shiftPageDown();
00472     void top();
00473     void shiftTop();
00474     void bottom();
00475     void shiftBottom();
00476     void toMatchingBracket();
00477     void shiftToMatchingBracket();
00478 
00479     void gotoLine();
00480 
00481   // config file / session management functions
00482   public:
00483     void readSessionConfig(const KConfigGroup&);
00484     void writeSessionConfig(KConfigGroup&);
00485 
00486   public Q_SLOTS:
00487     void setEol( int eol );
00488     void setAddBom( bool enabled);
00489     void find();
00490     void findSelectedForwards();
00491     void findSelectedBackwards();
00492     void replace();
00493     void findNext();
00494     void findPrevious();
00495 
00496     void setFoldingMarkersOn( bool enable ); // Not in KTextEditor::View, but should be
00497     void setIconBorder( bool enable );
00498     void setLineNumbersOn( bool enable );
00499     void setScrollBarMarks( bool enable );
00500     void toggleFoldingMarkers();
00501     void toggleIconBorder();
00502     void toggleLineNumbersOn();
00503     void toggleScrollBarMarks();
00504     void toggleDynWordWrap ();
00505     void toggleViInputMode ();
00506     void showViModeBar ();
00507     void hideViModeBar ();
00508     void setDynWrapIndicators(int mode);
00509 
00510   public:
00511     int getEol() const;
00512 
00513   public:
00514     KateRenderer *renderer ();
00515 
00516     bool iconBorder();
00517     bool lineNumbersOn();
00518     bool scrollBarMarks();
00519     int dynWrapIndicators();
00520     bool foldingMarkersOn();
00521 
00522   private Q_SLOTS:
00526     void slotSelectionChanged ();
00527 
00528   public:
00533     KateDocument*  doc() { return m_doc; }
00534     const KateDocument*  doc() const { return m_doc; }
00535 
00536   public Q_SLOTS:
00537     void slotUpdateUndo();
00538     void toggleInsert();
00539     void reloadFile();
00540     void toggleWWMarker();
00541     void toggleWriteLock();
00542     void switchToCmdLine ();
00543     void slotReadWriteChanged ();
00544 
00545   Q_SIGNALS:
00546     void dropEventPass(QDropEvent*);
00547 
00548   public:
00549     void slotTextInserted ( KTextEditor::View *view, const KTextEditor::Cursor &position, const QString &text);
00550 
00551   protected:
00552     void contextMenuEvent( QContextMenuEvent* );
00553 
00554   private Q_SLOTS:
00555     void slotGotFocus();
00556     void slotLostFocus();
00557     void slotDropEventPass( QDropEvent* ev );
00558     void slotSaveCanceled( const QString& error );
00559     void slotExpandToplevel();
00560     void slotCollapseLocal();
00561     void slotExpandLocal();
00562     void slotConfigDialog ();
00563 
00564   private:
00565     void setupConnections();
00566     void setupActions();
00567     void setupEditActions();
00568     void setupCodeFolding();
00569 
00570     QList<QAction*>        m_editActions;
00571     KAction*               m_editUndo;
00572     KAction*               m_editRedo;
00573     KRecentFilesAction*    m_fileRecent;
00574     KToggleAction*         m_toggleFoldingMarkers;
00575     KToggleAction*         m_toggleIconBar;
00576     KToggleAction*         m_toggleLineNumbers;
00577     KToggleAction*         m_toggleScrollBarMarks;
00578     KToggleAction*         m_toggleDynWrap;
00579     KSelectAction*         m_setDynWrapIndicators;
00580     KToggleAction*         m_toggleWWMarker;
00581     KAction*               m_switchCmdLine;
00582     KToggleAction*         m_viInputModeAction;
00583 
00584     KSelectAction*         m_setEndOfLine;
00585     KToggleAction*         m_addBom;
00586 
00587     QAction *m_cut;
00588     QAction *m_copy;
00589     QAction *m_paste;
00590     QAction *m_selectAll;
00591     QAction *m_deSelect;
00592 
00593     KToggleAction *m_toggleBlockSelection;
00594     KToggleAction *m_toggleInsert;
00595     KToggleAction *m_toggleWriteLock;
00596 
00597     KateDocument     *const m_doc;
00598     KateViewInternal*      m_viewInternal;
00599     KateRenderer*          m_renderer;
00600     KateSpellCheckDialog  *m_spell;
00601     KateBookmarks*         m_bookmarks;
00602 
00603     QVBoxLayout *m_vBox;
00604 
00605     bool       m_hasWrap;
00606 
00607   private Q_SLOTS:
00608     void slotNeedTextHint(int line, int col, QString &text);
00609     void slotHlChanged();
00610 
00614   public:
00615     inline KateViewConfig *config () { return m_config; }
00616 
00617     void updateConfig ();
00618 
00619     void updateDocumentConfig();
00620 
00621     void updateRendererConfig();
00622 
00623   private Q_SLOTS:
00624     void updateFoldingConfig ();
00625 
00626   private:
00627     KateViewConfig *m_config;
00628     bool m_startingUp;
00629     bool m_updatingDocumentConfig;
00630 
00631     // stores the current selection
00632     KateSmartRange* m_selection;
00633 
00634     // do we select normal or blockwise ?
00635     bool blockSelect;
00636 
00638   public:
00639     virtual bool insertTemplateTextImplementation ( const KTextEditor::Cursor&, const QString &templateString, const QMap<QString,QString> &initialValues);
00640 
00641 
00645   public:
00646     KateViewBar *viewBar() const;
00647     KateCmdLine *cmdLine ();
00648     KateSearchBar *searchBar (bool initHintAsPower = false);
00649     KateViModeBar *viModeBar();
00650     KateGotoBar *gotoBar ();
00651     KateDictionaryBar *dictionaryBar();
00652 
00657   private:
00658     // created in constructor of the view
00659     KateViewBar *m_bottomViewBar;
00660     KateViewBar *m_topViewBar;
00661     // created on demand..., only access them through the above accessors....
00662     KateCmdLine *m_cmdLine;
00663     KateSearchBar *m_searchBar;
00664     KateViModeBar *m_viModeBar;
00665     KateGotoBar *m_gotoBar;
00666     KateDictionaryBar *m_dictionaryBar;
00667 
00668   // vi Mode
00669   public:
00673     bool viInputMode() const;
00674 
00678     ViMode getCurrentViMode() const;
00679 
00683     KateViInputModeManager* getViInputModeManager();
00684 
00688     bool viInputModeStealKeys() const;
00689 
00693     void updateViModeBarMode();
00694 
00698     void updateViModeBarCmd();
00699 
00700   public:
00701     KTextEditor::Range visibleRange();
00702 
00703   Q_SIGNALS:
00704     void displayRangeChanged(KateView *view);
00705 
00706   protected:
00707     KToggleAction*               m_toggleOnTheFlySpellCheck;
00708     KateSpellingMenu *m_spellingMenu;
00709 
00710   protected Q_SLOTS:
00711     void toggleOnTheFlySpellCheck(bool b);
00712 
00713   public Q_SLOTS:
00714     void changeDictionary();
00715     void reflectOnTheFlySpellCheckStatus(bool enabled);
00716 
00717   public:
00718     KateSpellingMenu* spellingMenu();
00719 };
00720 
00724 Q_DECLARE_METATYPE(KTextEditor::Cursor)
00725 Q_DECLARE_METATYPE(KTextEditor::Range)
00726 
00727 #endif
00728 
00729 // kate: space-indent on; indent-width 2; replace-tabs on;

Kate

Skip menu "Kate"
  • Main Page
  • 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
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUtils
  • Nepomuk
  • Plasma
  •     Sodep
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.5.9-20090814
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