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

Kate

katecmds.cpp

Go to the documentation of this file.
00001 /* This file is part of the KDE libraries
00002    Copyright (C) 2003 - 2005 Anders Lund <anders@alweb.dk>
00003    Copyright (C) 2001-2004 Christoph Cullmann <cullmann@kde.org>
00004    Copyright (C) 2001 Charles Samuels <charles@kde.org>
00005 
00006    This library is free software; you can redistribute it and/or
00007    modify it under the terms of the GNU Library General Public
00008    License version 2 as published by the Free Software Foundation.
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 "katecmds.h"
00022 
00023 #include "katedocument.h"
00024 #include "kateview.h"
00025 #include "kateconfig.h"
00026 #include "kateautoindent.h"
00027 #include "katetextline.h"
00028 #include "katesyntaxmanager.h"
00029 #include "kateglobal.h"
00030 #include "katerenderer.h"
00031 #include "katecmd.h"
00032 
00033 #include <kdebug.h>
00034 #include <klocale.h>
00035 #include <kurl.h>
00036 #include <kshellcompletion.h>
00037 
00038 #include <QtCore/QRegExp>
00039 
00040 //BEGIN CoreCommands
00041 // syncs a config flag in the document with a boolean value
00042 static void setDocFlag( KateDocumentConfig::ConfigFlags flag, bool enable,
00043                   KateDocument *doc )
00044 {
00045   doc->config()->setConfigFlags( flag, enable );
00046 }
00047 
00048 // this returns wheather the string s could be converted to
00049 // a bool value, one of on|off|1|0|true|false. the argument val is
00050 // set to the extracted value in case of success
00051 static bool getBoolArg( const QString &t, bool *val  )
00052 {
00053   bool res( false );
00054   QString s = t.toLower();
00055   res = (s == "on" || s == "1" || s == "true");
00056   if ( res )
00057   {
00058     *val = true;
00059     return true;
00060   }
00061   res = (s == "off" || s == "0" || s == "false");
00062   if ( res )
00063   {
00064     *val = false;
00065     return true;
00066   }
00067   return false;
00068 }
00069 
00070 const QStringList &KateCommands::CoreCommands::cmds()
00071 {
00072   static QStringList l;
00073 
00074   if (l.isEmpty())
00075   l << "indent" << "unindent" << "cleanindent"
00076     << "comment" << "uncomment" << "goto" << "kill-line"
00077     << "set-tab-width" << "set-replace-tabs" << "set-show-tabs"
00078     << "set-remove-trailing-space"
00079     << "set-indent-width"
00080     << "set-indent-mode" << "set-auto-indent"
00081     << "set-line-numbers" << "set-folding-markers" << "set-icon-border"
00082     << "set-wrap-cursor"
00083     << "set-word-wrap" << "set-word-wrap-column"
00084     << "set-replace-tabs-save" << "set-remove-trailing-space-save"
00085     << "set-highlight" << "set-mode" << "set-show-indent"
00086     << "w" << "print" << "hardcopy";
00087 
00088   return l;
00089 }
00090 
00091 bool KateCommands::CoreCommands::exec(KTextEditor::View *view,
00092                             const QString &_cmd,
00093                             QString &errorMsg)
00094 {
00095   return exec( view, _cmd, errorMsg, KTextEditor::Range::invalid() );
00096 }
00097 
00098 bool KateCommands::CoreCommands::exec(KTextEditor::View *view,
00099                             const QString &_cmd,
00100                             QString &errorMsg,
00101                             const KTextEditor::Range& range)
00102 {
00103 #define KCC_ERR(s) { errorMsg=s; return false; }
00104   // cast it hardcore, we know that it is really a kateview :)
00105   KateView *v = (KateView*) view;
00106 
00107   if ( ! v )
00108     KCC_ERR( i18n("Could not access view") );
00109 
00110   //create a list of args
00111   QStringList args(_cmd.split( QRegExp("\\s+"), QString::SkipEmptyParts)) ;
00112   QString cmd ( args.takeFirst() );
00113 
00114   // ALL commands that takes no arguments.
00115   if ( cmd == "indent" )
00116   {
00117     if ( range.isValid() ) {
00118       v->doc()->editStart();
00119       for ( int line = range.start().line(); line <= range.end().line(); line++ ) {
00120         v->doc()->indent( v, line, 1 );
00121       }
00122       v->doc()->editEnd();
00123     } else {
00124       v->indent();
00125     }
00126     return true;
00127   }
00128 #if 0
00129   else if ( cmd == "run-myself" )
00130   {
00131 #ifndef Q_WS_WIN //todo
00132     return KateGlobal::self()->jscript()->execute(v, v->doc()->text(), errorMsg);
00133 #else
00134     return 0;
00135 #endif
00136   }
00137 #endif
00138   else if ( cmd == "unindent" )
00139   {
00140     if ( range.isValid() ) {
00141       v->doc()->editStart();
00142       for ( int line = range.start().line(); line <= range.end().line(); line++ ) {
00143         v->doc()->indent( v, line, -1 );
00144       }
00145       v->doc()->editEnd();
00146     } else {
00147       v->unIndent();
00148     }
00149     return true;
00150   }
00151   else if ( cmd == "cleanindent" )
00152   {
00153     if ( range.isValid() ) {
00154       v->doc()->editStart();
00155       for ( int line = range.start().line(); line <= range.end().line(); line++ ) {
00156         v->doc()->indent( v, line, 0 );
00157       }
00158       v->doc()->editEnd();
00159     } else {
00160       v->cleanIndent();
00161     }
00162     return true;
00163   }
00164   else if ( cmd == "comment" )
00165   {
00166     if ( range.isValid() ) {
00167       v->doc()->editStart();
00168       for ( int line = range.start().line(); line <= range.end().line(); line++ ) {
00169         v->doc()->comment( v, line, 0, 1 );
00170       }
00171       v->doc()->editEnd();
00172     } else {
00173       v->comment();
00174     }
00175     return true;
00176   }
00177   else if ( cmd == "uncomment" )
00178   {
00179     if ( range.isValid() ) {
00180       v->doc()->editStart();
00181       for ( int line = range.start().line(); line <= range.end().line(); line++ ) {
00182         v->doc()->comment( v, line, 0, -1 );
00183       }
00184       v->doc()->editEnd();
00185     } else {
00186       v->uncomment();
00187     }
00188     return true;
00189   }
00190   else if ( cmd == "kill-line" )
00191   {
00192     if ( range.isValid() ) {
00193       v->doc()->editStart();
00194       for ( int line = range.start().line(); line <= range.end().line(); line++ ) {
00195         v->doc()->removeLine( range.start().line() );
00196       }
00197       v->doc()->editEnd();
00198     } else {
00199       v->killLine();
00200     }
00201     return true;
00202   }
00203   else if ( cmd == "w" )
00204   {
00205     v->doc()->documentSave();
00206     return true;
00207   }
00208   else if ( cmd == "print" || cmd == "hardcopy" )
00209   {
00210     v->doc()->printDialog();
00211     return true;
00212   }
00213   else if ( cmd == "set-indent-mode" )
00214   {
00215     v->doc()->config()->setIndentationMode( args.first() );
00216     return true;
00217   }
00218   else if ( cmd == "set-highlight" )
00219   {
00220     if ( v->doc()->setHighlightingMode( args.first()) )
00221       return true;
00222 
00223     KCC_ERR( i18n("No such highlighting '%1'",  args.first() ) );
00224   }
00225   else if ( cmd == "set-mode" )
00226   {
00227     if ( v->doc()->setMode( args.first()) )
00228       return true;
00229 
00230     KCC_ERR( i18n("No such mode '%1'",  args.first() ) );
00231   }
00232 
00233   // ALL commands that takes exactly one integer argument.
00234   else if ( cmd == "set-tab-width" ||
00235             cmd == "set-indent-width" ||
00236             cmd == "set-word-wrap-column" ||
00237             cmd == "goto" )
00238   {
00239     // find a integer value > 0
00240     if ( ! args.count() )
00241       KCC_ERR( i18n("Missing argument. Usage: %1 <value>",  cmd ) );
00242     bool ok;
00243     int val ( args.first().toInt( &ok, 10 ) ); // use base 10 even if the string starts with '0'
00244     if ( !ok )
00245       KCC_ERR( i18n("Failed to convert argument '%1' to integer.",
00246                   args.first() ) );
00247 
00248     if ( cmd == "set-tab-width" )
00249     {
00250       if ( val < 1 )
00251         KCC_ERR( i18n("Width must be at least 1.") );
00252       v->doc()->config()->setTabWidth( val );
00253     }
00254     else if ( cmd == "set-indent-width" )
00255     {
00256       if ( val < 1 )
00257         KCC_ERR( i18n("Width must be at least 1.") );
00258       v->doc()->config()->setIndentationWidth( val );
00259     }
00260     else if ( cmd == "set-word-wrap-column" )
00261     {
00262       if ( val < 2 )
00263         KCC_ERR( i18n("Column must be at least 1.") );
00264       v->doc()->setWordWrapAt( val );
00265     }
00266     else if ( cmd == "goto" )
00267     {
00268       if ( args.first().at(0) == '-' || args.first().at(0) == '+' ) {
00269         // if the number starts with a minus or plus sign, add/subract the number
00270         val = v->cursorPosition().line() + val;
00271       } else {
00272         val--; // convert given line number to the internal representation of line numbers
00273       }
00274 
00275       // constrain cursor to the range [0, number of lines]
00276       if ( val < 0 ) {
00277         val = 0;
00278       } else if ( val > v->doc()->lines()-1 ) {
00279         val = v->doc()->lines()-1;
00280       }
00281 
00282       v->setCursorPosition( KTextEditor::Cursor( val, 0 ) );
00283       return true;
00284     }
00285     return true;
00286   }
00287 
00288   // ALL commands that takes 1 boolean argument.
00289   else if ( cmd == "set-icon-border" ||
00290             cmd == "set-folding-markers" ||
00291             cmd == "set-line-numbers" ||
00292             cmd == "set-replace-tabs" ||
00293             cmd == "set-remove-trailing-space" ||
00294             cmd == "set-show-tabs" ||
00295             cmd == "set-word-wrap" ||
00296             cmd == "set-wrap-cursor" ||
00297             cmd == "set-replace-tabs-save" ||
00298             cmd == "set-remove-trailing-space-save" ||
00299             cmd == "set-show-indent" )
00300   {
00301     if ( ! args.count() )
00302       KCC_ERR( i18n("Usage: %1 on|off|1|0|true|false",  cmd ) );
00303     bool enable = false;
00304     if ( getBoolArg( args.first(), &enable ) )
00305     {
00306       if ( cmd == "set-icon-border" )
00307         v->setIconBorder( enable );
00308       else if (cmd == "set-folding-markers")
00309         v->setFoldingMarkersOn( enable );
00310       else if ( cmd == "set-line-numbers" )
00311         v->setLineNumbersOn( enable );
00312       else if ( cmd == "set-show-indent" )
00313         v->renderer()->setShowIndentLines( enable );
00314       else if ( cmd == "set-replace-tabs" )
00315         setDocFlag( KateDocumentConfig::cfReplaceTabsDyn, enable, v->doc() );
00316       else if ( cmd == "set-remove-trailing-space" )
00317         setDocFlag( KateDocumentConfig::cfRemoveTrailingDyn, enable, v->doc() );
00318       else if ( cmd == "set-show-tabs" )
00319         setDocFlag( KateDocumentConfig::cfShowTabs, enable, v->doc() );
00320       else if ( cmd == "set-show-trailing-spaces" )
00321         setDocFlag( KateDocumentConfig::cfShowSpaces, enable, v->doc() );
00322       else if ( cmd == "set-word-wrap" )
00323         v->doc()->setWordWrap( enable );
00324       else if ( cmd == "set-remove-trailing-space-save" )
00325         setDocFlag( KateDocumentConfig::cfRemoveSpaces, enable, v->doc() );
00326       else if ( cmd == "set-wrap-cursor" )
00327         setDocFlag( KateDocumentConfig::cfWrapCursor, enable, v->doc() );
00328 
00329       return true;
00330     }
00331     else
00332       KCC_ERR( i18n("Bad argument '%1'. Usage: %2 on|off|1|0|true|false",
00333                  args.first() ,  cmd ) );
00334   }
00335 
00336   // unlikely..
00337   KCC_ERR( i18n("Unknown command '%1'", cmd) );
00338 }
00339 
00340 bool KateCommands::CoreCommands::supportsRange(const QString &range)
00341 {
00342   static QStringList l;
00343 
00344   if (l.isEmpty())
00345   l << "indent" << "unindent" << "cleanindent"
00346     << "comment" << "uncomment" << "kill-line";
00347 
00348   return l.contains(range);
00349 }
00350 
00351 KCompletion *KateCommands::CoreCommands::completionObject( KTextEditor::View *view, const QString &cmd )
00352 {
00353   Q_UNUSED(view);
00354 
00355   if ( cmd == "set-highlight" )
00356   {
00357     QStringList l;
00358     for ( int i = 0; i < KateHlManager::self()->highlights(); i++ )
00359       l << KateHlManager::self()->hlName (i);
00360 
00361     KateCmdShellCompletion *co = new KateCmdShellCompletion();
00362     co->setItems( l );
00363     co->setIgnoreCase( true );
00364     return co;
00365   }
00366   return 0L;
00367 }
00368 //END CoreCommands
00369 
00370 //BEGIN SedReplace
00371 static void replace(QString &s, const QString &needle, const QString &with)
00372 {
00373   int pos=0;
00374   while (1)
00375   {
00376     pos=s.indexOf(needle, pos);
00377     if (pos==-1) break;
00378     s.replace(pos, needle.length(), with);
00379     pos+=with.length();
00380   }
00381 
00382 }
00383 
00384 static int backslashString(const QString &haystack, const QString &needle, int index)
00385 {
00386   int len=haystack.length();
00387   int searchlen=needle.length();
00388   bool evenCount=true;
00389   while (index<len)
00390   {
00391     if (haystack[index]=='\\')
00392     {
00393       evenCount=!evenCount;
00394     }
00395     else
00396     {  // isn't a slash
00397       if (!evenCount)
00398       {
00399         if (haystack.mid(index, searchlen)==needle)
00400           return index-1;
00401       }
00402       evenCount=true;
00403     }
00404     index++;
00405 
00406   }
00407 
00408   return -1;
00409 }
00410 
00411 // exchange "\t" for the actual tab character, for example
00412 static void exchangeAbbrevs(QString &str)
00413 {
00414   // the format is (findreplace)*[nullzero]
00415   const char *magic="a\x07t\tn\n";
00416 
00417   while (*magic)
00418   {
00419     int index=0;
00420     char replace=magic[1];
00421     while ((index=backslashString(str, QString (QChar::fromAscii(*magic)), index))!=-1)
00422     {
00423       str.replace(index, 2, QChar(replace));
00424       index++;
00425     }
00426     magic++;
00427     magic++;
00428   }
00429 }
00430 
00431 int KateCommands::SedReplace::sedMagic( KateDocument *doc, int &line,
00432                                         const QString &find, const QString &repOld, const QString &delim,
00433                                         bool noCase, bool repeat,
00434                                         uint startcol, int endcol )
00435 {
00436   KateTextLine::Ptr ln = doc->kateTextLine( line );
00437   if ( ! ln || ! ln->length() ) return 0;
00438 
00439   // HANDLING "\n"s in PATTERN
00440   // * Create a list of patterns, splitting PATTERN on (unescaped) "\n"
00441   // * insert $s and ^s to match line ends/beginnings
00442   // * When matching patterhs after the first one, replace \N with the captured
00443   //   text.
00444   // * If all patterns in the list match sequentiel lines, there is a match, so
00445   // * remove line/start to line + patterns.count()-1/patterns.last.length
00446   // * handle capatures by putting them in one list.
00447   // * the existing insertion is fine, including the line calculation.
00448 
00449   QStringList patterns(find.split( QRegExp("(^\\\\n|(?![^\\\\])\\\\n)"), QString::KeepEmptyParts));
00450   if ( patterns.count() > 1 )
00451   {
00452     for ( int i = 0; i < patterns.count(); i++ )
00453     {
00454       if ( i < patterns.count() - 1 )
00455         patterns[i].append("$");
00456       if ( i )
00457         patterns[i].prepend("^");
00458 
00459        kDebug(13025)<<"patterns["<<i<<"] ="<<patterns[i];
00460     }
00461   }
00462 
00463   QRegExp matcher(patterns[0], noCase ?Qt::CaseSensitive:Qt::CaseInsensitive);
00464 
00465   uint len;
00466   int matches = 0;
00467 
00468   while ( ln->searchText( startcol, matcher, &startcol, &len ) )
00469   {
00470 
00471     if ( endcol >= 0  && startcol + len > (uint)endcol )
00472       break;
00473 
00474     matches++;
00475 
00476 
00477     QString rep=repOld;
00478 
00479     // now set the backreferences in the replacement
00480     const QStringList backrefs=matcher.capturedTexts();
00481     int refnum=1;
00482 
00483     QStringList::ConstIterator i = backrefs.begin();
00484     ++i;
00485 
00486     for (; i!=backrefs.end(); ++i)
00487     {
00488       // I need to match "\\" or "", but not "\"
00489       QString number=QString::number(refnum);
00490 
00491       int index=0;
00492       while (index!=-1)
00493       {
00494         index=backslashString(rep, number, index);
00495         if (index>=0)
00496         {
00497           rep.replace(index, 2, *i);
00498           index+=(*i).length();
00499         }
00500       }
00501 
00502       refnum++;
00503     }
00504 
00505     replace(rep, "\\\\", "\\");
00506     replace(rep, "\\" + delim, delim);
00507 
00508     doc->removeText( KTextEditor::Range (line, startcol, line, startcol + len) );
00509     doc->insertText( KTextEditor::Cursor (line, startcol), rep );
00510 
00511     // TODO if replace contains \n,
00512     // change the line number and
00513     // check for text that needs be searched behind the last inserted newline.
00514     int lns = rep.count(QChar::fromLatin1('\n'));
00515     if ( lns > 0 )
00516     {
00517       line += lns;
00518 
00519       if ( doc->lineLength( line ) > 0 && ( endcol < 0 || (uint)endcol  >= startcol + len ) )
00520       {
00521       //  if ( endcol  >= startcol + len )
00522           endcol -= (startcol + len);
00523           uint sc = rep.length() - rep.lastIndexOf('\n') - 1;
00524         matches += sedMagic( doc, line, find, repOld, delim, noCase, repeat, sc, endcol );
00525       }
00526     }
00527 
00528     if (!repeat) break;
00529     startcol+=rep.length();
00530 
00531     // sanity check -- avoid infinite loops eg with %s,.*,,g ;)
00532     uint ll = ln->length();
00533     if ( ! ll || startcol > ll )
00534       break;
00535   }
00536 
00537   return matches;
00538 }
00539 
00540 bool KateCommands::SedReplace::exec (KTextEditor::View *view, const QString &cmd, QString &msg)
00541 {
00542   return exec(view, cmd, msg, KTextEditor::Range::invalid());
00543 }
00544 
00545 bool KateCommands::SedReplace::exec (class KTextEditor::View *view, const QString &cmd,
00546     QString &msg, const KTextEditor::Range &r)
00547 {
00548   kDebug(13025)<<"SedReplace::execCmd( "<<cmd<<" )";
00549   if (r.isValid())
00550     kDebug(13025)<<"Range: " << r;
00551 
00552   QRegExp delim("^s\\s*([^\\w\\s])");
00553   if ( delim.indexIn( cmd ) < 0 ) return false;
00554 
00555   bool noCase=cmd[cmd.length()-1]=='i' || cmd[cmd.length()-2]=='i';
00556   bool repeat=cmd[cmd.length()-1]=='g' || cmd[cmd.length()-2]=='g';
00557 
00558   QString d = delim.cap(1);
00559   kDebug(13025)<<"SedReplace: delimiter is '"<<d<<"'";
00560 
00561   QRegExp splitter( QString("^s\\s*")  + d + "((?:[^\\\\\\" + d + "]|\\\\.)*)\\"
00562       + d +"((?:[^\\\\\\" + d + "]|\\\\.)*)(\\" + d + "[ig]{0,2})?$" );
00563   if (splitter.indexIn(cmd)<0) return false;
00564 
00565   QString find=splitter.cap(1);
00566   kDebug(13025)<< "SedReplace: find=" << find;
00567 
00568   QString replace=splitter.cap(2);
00569   exchangeAbbrevs(replace);
00570   kDebug(13025)<< "SedReplace: replace=" << replace;
00571 
00572   if ( find.contains("\\n") )
00573   {
00574     // FIXME: make replacing newlines work
00575     msg = i18n("Sorry, but Kate is not able to replace newlines, yet");
00576     return false;
00577   }
00578 
00579   KateDocument *doc = ((KateView*)view)->doc();
00580   if ( ! doc ) return false;
00581 
00582   doc->editStart();
00583 
00584   int replacementsDone = 0;
00585   int linesTouched = 0;
00586 
00587   if (r.isValid()) { // given range
00588     for (int line = r.start().line(); line <= r.end().line(); line++) {
00589       int temp = replacementsDone;
00590       replacementsDone += sedMagic( doc, line, find, replace, d, !noCase, repeat );
00591       if (replacementsDone > temp) {
00592         linesTouched++;
00593       }
00594     }
00595   } else { // current line
00596     int line= view->cursorPosition().line();
00597     replacementsDone += sedMagic(doc, line, find, replace, d, !noCase, repeat);
00598     if (replacementsDone > 0) {
00599       linesTouched = 1;
00600     }
00601   }
00602 
00603   msg = i18ncp("%2 is the translation of the next message",
00604                "1 replacement done on %2", "%1 replacements done on %2", replacementsDone,
00605                i18ncp("substituted into the previous message",
00606                       "1 line", "%1 lines", linesTouched));
00607 
00608   doc->editEnd();
00609 
00610   return true;
00611 }
00612 
00613 //END SedReplace
00614 
00615 //BEGIN Character
00616 bool KateCommands::Character::exec (KTextEditor::View *view, const QString &_cmd, QString &)
00617 {
00618   QString cmd = _cmd;
00619 
00620   // hex, octal, base 9+1
00621   QRegExp num("^char *(0?x[0-9A-Fa-f]{1,4}|0[0-7]{1,6}|[0-9]{1,5})$");
00622   if (num.indexIn(cmd)==-1) return false;
00623 
00624   cmd=num.cap(1);
00625 
00626   // identify the base
00627 
00628   unsigned short int number=0;
00629   int base=10;
00630   if (cmd[0]=='x' || cmd.startsWith(QLatin1String("0x")))
00631   {
00632     cmd.remove(QRegExp("^0?x"));
00633     base=16;
00634   }
00635   else if (cmd[0]=='0')
00636     base=8;
00637   bool ok;
00638   number=cmd.toUShort(&ok, base);
00639   if (!ok || number==0) return false;
00640   if (number<=255)
00641   {
00642     char buf[2];
00643     buf[0]=(char)number;
00644     buf[1]=0;
00645 
00646     view->document()->insertText(view->cursorPosition(), QString(buf));
00647   }
00648   else
00649   { // do the unicode thing
00650     QChar c(number);
00651 
00652     view->document()->insertText(view->cursorPosition(), QString(&c, 1));
00653   }
00654 
00655   return true;
00656 }
00657 
00658 //END Character
00659 
00660 //BEGIN Date
00661 bool KateCommands::Date::exec (KTextEditor::View *view, const QString &cmd, QString &)
00662 {
00663   if (!cmd.startsWith(QLatin1String("date")))
00664     return false;
00665 
00666   if (QDateTime::currentDateTime().toString(cmd.mid(5, cmd.length()-5)).length() > 0)
00667     view->document()->insertText(view->cursorPosition(), QDateTime::currentDateTime().toString(cmd.mid(5, cmd.length()-5)));
00668   else
00669     view->document()->insertText(view->cursorPosition(), QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"));
00670 
00671   return true;
00672 }
00673 
00674 //END Date
00675 
00676 // 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
  • 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