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

kate

kateexternaltools.cpp

Go to the documentation of this file.
00001 /*
00002    This file is part of the Kate text editor of the KDE project.
00003 
00004    This library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Library General Public
00006    License version 2 as published by the Free Software Foundation.
00007 
00008    This library is distributed in the hope that it will be useful,
00009    but WITHOUT ANY WARRANTY; without even the implied warranty of
00010    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011    Library General Public License for more details.
00012 
00013    You should have received a copy of the GNU Library General Public License
00014    along with this library; see the file COPYING.LIB.  If not, write to
00015    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00016    Boston, MA 02110-1301, USA.
00017 
00018    ---
00019    Copyright (C) 2004, Anders Lund <anders@alweb.dk>
00020 */
00021 // TODO
00022 // Icons
00023 // Direct shortcut setting
00024 //BEGIN Includes
00025 #include "kateexternaltools.h"
00026 #include "kateexternaltools.moc"
00027 #include "katedocmanager.h"
00028 #include "kateviewmanager.h"
00029 #include "kateapp.h"
00030 
00031 #include "katemainwindow.h"
00032 
00033 #include <kate/view.h>
00034 #include <kate/document.h>
00035 
00036 #include <klistbox.h>
00037 #include <klocale.h>
00038 #include <kiconloader.h>
00039 #include <kmessagebox.h>
00040 #include <kmimetypechooser.h>
00041 #include <kconfig.h>
00042 #include <krun.h>
00043 #include <kicondialog.h>
00044 #include <kpopupmenu.h>
00045 #include <kdebug.h>
00046 
00047 #include <qbitmap.h>
00048 #include <qcombobox.h>
00049 #include <qfile.h>
00050 #include <qpushbutton.h>
00051 #include <qlineedit.h>
00052 #include <qlayout.h>
00053 #include <qlabel.h>
00054 #include <qlistbox.h>
00055 #include <qmap.h>
00056 #include <qregexp.h>
00057 #include <qtextedit.h>
00058 #include <qtoolbutton.h>
00059 #include <qwhatsthis.h>
00060 
00061 #include <stdlib.h>
00062 #include <unistd.h>
00063 //END Includes
00064 
00065 KateExternalToolsCommand *KateExternalToolsCommand::s_self=0;
00066 
00067 //BEGIN KateExternalTool
00068 KateExternalTool::KateExternalTool( const QString &name,
00069                       const QString &command,
00070                       const QString &icon,
00071                       const QString &tryexec,
00072                       const QStringList &mimetypes,
00073                       const QString &acname,
00074                       const QString &cmdname,
00075                       int save )
00076   : name ( name ),
00077     command ( command ),
00078     icon ( icon ),
00079     tryexec ( tryexec ),
00080     mimetypes ( mimetypes ),
00081     acname ( acname ),
00082     cmdname ( cmdname ),
00083     save ( save )
00084 {
00085   //if ( ! tryexec.isEmpty() )
00086     hasexec = checkExec();
00087 }
00088 
00089 bool KateExternalTool::checkExec()
00090 {
00091   // if tryexec is empty, it is the first word of command
00092   if ( tryexec.isEmpty() )
00093     tryexec = command.section( " ", 0, 0, QString::SectionSkipEmpty );
00094 
00095   // NOTE this code is modified taken from kdesktopfile.cpp, from KDesktopFile::tryExec()
00096   if (!tryexec.isEmpty()) {
00097     if (tryexec[0] == '/') {
00098       if (::access(QFile::encodeName(tryexec), R_OK | X_OK))
00099     return false;
00100 
00101       m_exec = tryexec;
00102     } else {
00103       // !!! Sergey A. Sukiyazov <corwin@micom.don.ru> !!!
00104       // Environment PATH may contain filenames in 8bit locale cpecified
00105       // encoding (Like a filenames).
00106       QStringList dirs = QStringList::split(':', QFile::decodeName(::getenv("PATH")));
00107       QStringList::Iterator it(dirs.begin());
00108       bool match = false;
00109       for (; it != dirs.end(); ++it)
00110       {
00111     QString fName = *it + "/" + tryexec;
00112     if (::access(QFile::encodeName(fName), R_OK | X_OK) == 0)
00113     {
00114       match = true;
00115           m_exec = fName;
00116       break;
00117     }
00118       }
00119       // didn't match at all
00120       if (!match)
00121         return false;
00122     }
00123     return true;
00124   }
00125   return false;
00126 }
00127 
00128 bool KateExternalTool::valid( const QString &mt ) const
00129 {
00130   return mimetypes.isEmpty() || mimetypes.contains( mt );
00131 }
00132 //END KateExternalTool
00133 
00134 //BEGIN KateExternalToolsCommand
00135 KateExternalToolsCommand::KateExternalToolsCommand() : Kate::Command() {
00136     m_inited=false;
00137     reload();
00138 }
00139 
00140 QStringList KateExternalToolsCommand::cmds () {
00141     return m_list;
00142 }
00143 
00144 KateExternalToolsCommand *KateExternalToolsCommand::self () {
00145     if (s_self) return s_self;
00146     s_self=new KateExternalToolsCommand;
00147     return s_self;
00148 }
00149 
00150 void KateExternalToolsCommand::reload () {
00151   m_list.clear();
00152   m_map.clear();
00153 
00154   KConfig config("externaltools", false, false, "appdata");
00155   config.setGroup("Global");
00156   QStringList tools = config.readListEntry("tools");
00157 
00158 
00159   for( QStringList::Iterator it = tools.begin(); it != tools.end(); ++it )
00160   {
00161     if ( *it == "---" )
00162       continue;
00163 
00164 
00165     config.setGroup( *it );
00166 
00167     KateExternalTool t = KateExternalTool(
00168         config.readEntry( "name", "" ),
00169         config.readEntry( "command", ""),
00170         config.readEntry( "icon", ""),
00171         config.readEntry( "executable", ""),
00172         config.readListEntry( "mimetypes" ),
00173         config.readEntry( "acname", "" ),
00174         config.readEntry( "cmdname", "" ) );
00175     // FIXME test for a command name first!
00176     if ( t.hasexec && (!t.cmdname.isEmpty())) {
00177         m_list.append("exttool-"+t.cmdname);
00178         m_map.insert("exttool-"+t.cmdname,t.acname);
00179     }
00180   }
00181   if (m_inited) {
00182       Kate::Document::unregisterCommand(this);
00183       Kate::Document::registerCommand(this);
00184    }
00185   else m_inited=true;
00186 }
00187 
00188 bool KateExternalToolsCommand::exec (Kate::View *view, const QString &cmd, QString &) {
00189     QWidget *wv=dynamic_cast<QWidget*>(view);
00190     if (!wv) {
00191 //      kdDebug(13001)<<"KateExternalToolsCommand::exec: Could not get view widget"<<endl;
00192         return false;
00193     }
00194   KateMDI::MainWindow *dmw=dynamic_cast<KateMDI::MainWindow*>(wv->topLevelWidget());
00195     if (!dmw) {
00196 //      kdDebug(13001)<<"KateExternalToolsCommand::exec: Could not get main window"<<endl;
00197         return false;
00198     }
00199 //  kdDebug(13001)<<"cmd="<<cmd.stripWhiteSpace()<<endl;
00200     QString actionName=m_map[cmd.stripWhiteSpace()];
00201     if (actionName.isEmpty()) return false;
00202 //  kdDebug(13001)<<"actionName is not empty:"<<actionName<<endl;
00203     KateExternalToolsMenuAction *a=
00204         dynamic_cast<KateExternalToolsMenuAction*>(dmw->action("tools_external"));
00205     if (!a) return false;
00206 //  kdDebug(13001)<<"trying to find action"<<endl;
00207     KAction *a1=a->actionCollection()->action(actionName.utf8());
00208     if (!a1) return false;
00209 //  kdDebug(13001)<<"activating action"<<endl;
00210     a1->activate();
00211     return true;
00212 }
00213 
00214 bool KateExternalToolsCommand::help (Kate::View *, const QString &, QString &) {
00215     return false;
00216 }
00217 //END KateExternalToolsCommand
00218 
00219 //BEGIN KateExternalToolAction
00220 KateExternalToolAction::KateExternalToolAction( QObject *parent,
00221              const char *name, KateExternalTool *t)
00222   : KAction( parent, name ),
00223     tool ( t )
00224 {
00225   setText( t->name );
00226   if ( ! t->icon.isEmpty() )
00227     setIconSet( SmallIconSet( t->icon ) );
00228 
00229   connect( this ,SIGNAL(activated()), this, SLOT(slotRun()) );
00230 }
00231 
00232 bool KateExternalToolAction::expandMacro( const QString &str, QStringList &ret )
00233 {
00234   KateMainWindow *mw = (KateMainWindow*)parent()->parent();
00235 
00236   Kate::View *view = mw->viewManager()->activeView();
00237   if ( ! view ) return false;
00238 
00239 
00240   if ( str == "URL" )
00241     ret += mw->activeDocumentUrl().url();
00242   else if ( str == "directory" ) // directory of current doc
00243     ret += mw->activeDocumentUrl().directory();
00244   else if ( str == "filename" )
00245     ret += mw->activeDocumentUrl().fileName();
00246   else if ( str == "line" ) // cursor line of current doc
00247     ret += QString::number( view->cursorLine() );
00248   else if ( str == "col" ) // cursor col of current doc
00249     ret += QString::number( view->cursorColumn() );
00250   else if ( str == "selection" ) // selection of current doc if any
00251     ret += view->getDoc()->selection();
00252   else if ( str == "text" ) // text of current doc
00253     ret += view->getDoc()->text();
00254   else if ( str == "URLs" ) {
00255     for( Kate::Document *doc = KateDocManager::self()->firstDocument(); doc; doc = KateDocManager::self()->nextDocument() )
00256       if ( ! doc->url().isEmpty() )
00257         ret += doc->url().url();
00258   } else
00259     return false;
00260   return true;
00261 }
00262 
00263 KateExternalToolAction::~KateExternalToolAction() {
00264     delete(tool);
00265 }
00266 
00267 void KateExternalToolAction::slotRun()
00268 {
00269   // expand the macros in command if any,
00270   // and construct a command with an absolute path
00271   QString cmd = tool->command;
00272 
00273   if ( ! expandMacrosShellQuote( cmd ) )
00274   {
00275     KMessageBox::sorry( (KateMainWindow*)parent()->parent(),
00276                          i18n("Failed to expand the command '%1'.").arg( cmd ),
00277                          i18n( "Kate External Tools") );
00278     return;
00279   }
00280   kdDebug(13001)<<"externaltools: Running command: "<<cmd<<endl;
00281 
00282   // save documents if requested
00283   KateMainWindow *mw = (KateMainWindow*)parent()->parent();
00284   if ( tool->save == 1 )
00285     mw->viewManager()->activeView()->document()->save();
00286   else if ( tool->save == 2 )
00287     mw->actionCollection()->action("file_save_all")->activate();
00288 
00289   KRun::runCommand( cmd, tool->tryexec, tool->icon );
00290 }
00291 //END KateExternalToolAction
00292 
00293 //BEGIN KateExternalToolsMenuAction
00294 KateExternalToolsMenuAction::KateExternalToolsMenuAction( const QString &text,
00295                                                QObject *parent,
00296                                                const char* name,
00297                                                KateMainWindow *mw )
00298     : KActionMenu( text, parent, name ),
00299       mainwindow( mw )
00300 {
00301 
00302   m_actionCollection = new KActionCollection( mainwindow );
00303 
00304   connect(KateDocManager::self(),SIGNAL(documentChanged()),this,SLOT(slotDocumentChanged()));
00305 
00306   reload();
00307 }
00308 
00309 void KateExternalToolsMenuAction::reload()
00310 {
00311   m_actionCollection->clear ();
00312   popupMenu()->clear();
00313 
00314   // load all the tools, and create a action for each of them
00315   KConfig *config = new KConfig( "externaltools", false, false, "appdata" );
00316   config->setGroup( "Global" );
00317   QStringList tools = config->readListEntry( "tools" );
00318 
00319   // if there are tools that are present but not explicitly removed,
00320   // add them to the end of the list
00321   config->setReadDefaults( true );
00322   QStringList dtools = config->readListEntry( "tools" );
00323   int gver = config->readNumEntry( "version", 1 );
00324   config->setReadDefaults( false );
00325 
00326   int ver = config->readNumEntry( "version" );
00327   if ( ver <= gver )
00328   {
00329     QStringList removed = config->readListEntry( "removed" );
00330     bool sepadded = false;
00331     for (QStringList::iterator itg = dtools.begin(); itg != dtools.end(); ++itg )
00332     {
00333       if ( ! tools.contains( *itg ) &&
00334             ! removed.contains( *itg ) )
00335       {
00336         if ( ! sepadded )
00337         {
00338           tools << "---";
00339           sepadded = true;
00340         }
00341         tools << *itg;
00342       }
00343     }
00344 
00345     config->writeEntry( "tools", tools );
00346     config->sync();
00347     config->writeEntry( "version", gver );
00348   }
00349 
00350   for( QStringList::Iterator it = tools.begin(); it != tools.end(); ++it )
00351   {
00352     if ( *it == "---" )
00353     {
00354       popupMenu()->insertSeparator();
00355       // a separator
00356       continue;
00357     }
00358 
00359     config->setGroup( *it );
00360 
00361     KateExternalTool *t = new KateExternalTool(
00362         config->readEntry( "name", "" ),
00363         config->readEntry( "command", ""),
00364         config->readEntry( "icon", ""),
00365         config->readEntry( "executable", ""),
00366         config->readListEntry( "mimetypes" ),
00367         config->readEntry( "acname", "" ),
00368         config->readEntry( "cmdname", "" ),
00369         config->readNumEntry( "save", 0 ) );
00370 
00371     if ( t->hasexec )
00372       insert( new KateExternalToolAction( m_actionCollection, t->acname.ascii(), t ) );
00373   }
00374 
00375   m_actionCollection->readShortcutSettings( "Shortcuts", config );
00376   slotDocumentChanged();
00377   delete config;
00378 }
00379 
00380 void KateExternalToolsMenuAction::slotDocumentChanged()
00381 {
00382   // try to enable/disable to match current mime type
00383   Kate::DocumentExt *de = documentExt( KateDocManager::self()->activeDocument() );
00384   if ( de )
00385   {
00386     QString mt = de->mimeType();
00387     QStringList l;
00388     bool b;
00389 
00390     KActionPtrList actions = m_actionCollection->actions();
00391     for (KActionPtrList::iterator it = actions.begin(); it != actions.end(); ++it )
00392     {
00393       KateExternalToolAction *action = dynamic_cast<KateExternalToolAction*>(*it);
00394       if ( action )
00395       {
00396         l = action->tool->mimetypes;
00397         b = ( ! l.count() || l.contains( mt ) );
00398         action->setEnabled( b );
00399       }
00400     }
00401   }
00402 }
00403 //END KateExternalToolsMenuAction
00404 
00405 //BEGIN ToolItem
00410 class ToolItem : public QListBoxPixmap
00411 {
00412   public:
00413     ToolItem( QListBox *lb, const QPixmap &icon, KateExternalTool *tool )
00414         : QListBoxPixmap( lb, icon, tool->name ),
00415           tool ( tool )
00416     {;}
00417 
00418     ~ToolItem() {};
00419 
00420     KateExternalTool *tool;
00421 };
00422 //END ToolItem
00423 
00424 //BEGIN KateExternalToolServiceEditor
00425 KateExternalToolServiceEditor::KateExternalToolServiceEditor( KateExternalTool *tool,
00426                                 QWidget *parent, const char *name )
00427     : KDialogBase( parent, name, true, i18n("Edit External Tool"), KDialogBase::Ok|KDialogBase::Cancel ),
00428       tool( tool )
00429 {
00430     // create a entry for each property
00431     // fill in the values from the service if available
00432   QWidget *w = new QWidget( this );
00433   setMainWidget( w );
00434   QGridLayout *lo = new QGridLayout( w );
00435   lo->setSpacing( KDialogBase::spacingHint() );
00436 
00437   QLabel *l;
00438 
00439   leName = new QLineEdit( w );
00440   lo->addWidget( leName, 1, 2 );
00441   l = new QLabel( leName, i18n("&Label:"), w );
00442   l->setAlignment( l->alignment()|Qt::AlignRight );
00443   lo->addWidget( l, 1, 1 );
00444   if ( tool ) leName->setText( tool->name );
00445   QWhatsThis::add( leName, i18n(
00446       "The name will be displayed in the 'Tools->External' menu") );
00447 
00448   btnIcon = new KIconButton( w );
00449   btnIcon->setIconSize( KIcon::SizeSmall );
00450   lo->addWidget( btnIcon, 1, 3 );
00451   if ( tool && !tool->icon.isEmpty() )
00452     btnIcon->setIcon( tool->icon );
00453 
00454   teCommand = new QTextEdit( w );
00455   lo->addMultiCellWidget( teCommand, 2, 2, 2, 3 );
00456   l = new QLabel( teCommand, i18n("S&cript:"), w );
00457   l->setAlignment( Qt::AlignTop|Qt::AlignRight );
00458   lo->addWidget( l, 2, 1 );
00459   if ( tool ) teCommand->setText( tool->command );
00460   QWhatsThis::add( teCommand, i18n(
00461       "<p>The script to execute to invoke the tool. The script is passed "
00462       "to /bin/sh for execution. The following macros "
00463       "will be expanded:</p>"
00464       "<ul><li><code>%URL</code> - the URL of the current document."
00465       "<li><code>%URLs</code> - a list of the URLs of all open documents."
00466       "<li><code>%directory</code> - the URL of the directory containing "
00467       "the current document."
00468       "<li><code>%filename</code> - the filename of the current document."
00469       "<li><code>%line</code> - the current line of the text cursor in the "
00470       "current view."
00471       "<li><code>%column</code> - the column of the text cursor in the "
00472       "current view."
00473       "<li><code>%selection</code> - the selected text in the current view."
00474       "<li><code>%text</code> - the text of the current document.</ul>" ) );
00475 
00476 
00477   leExecutable = new QLineEdit( w );
00478   lo->addMultiCellWidget( leExecutable, 3, 3, 2, 3 );
00479   l = new QLabel( leExecutable, i18n("&Executable:"), w );
00480   l->setAlignment( l->alignment()|Qt::AlignRight );
00481   lo->addWidget( l, 3, 1 );
00482   if ( tool ) leExecutable->setText( tool->tryexec );
00483   QWhatsThis::add( leExecutable, i18n(
00484       "The executable used by the command. This is used to check if a tool "
00485       "should be displayed; if not set, the first word of <em>command</em> "
00486       "will be used.") );
00487 
00488   leMimetypes = new QLineEdit( w );
00489   lo->addWidget( leMimetypes, 4, 2 );
00490   l = new QLabel( leMimetypes, i18n("&Mime types:"), w );
00491   l->setAlignment( l->alignment()|Qt::AlignRight );
00492   lo->addWidget( l, 4, 1 );
00493   if ( tool ) leMimetypes->setText( tool->mimetypes.join("; ") );
00494   QWhatsThis::add( leMimetypes, i18n(
00495       "A semicolon-separated list of mime types for which this tool should "
00496       "be available; if this is left empty, the tool is always available. "
00497       "To choose from known mimetypes, press the button on the right.") );
00498 
00499   QToolButton *btnMTW = new QToolButton(w);
00500   lo->addWidget( btnMTW, 4, 3 );
00501   btnMTW->setIconSet(QIconSet(SmallIcon("wizard")));
00502   connect(btnMTW, SIGNAL(clicked()), this, SLOT(showMTDlg()));
00503   QWhatsThis::add( btnMTW, i18n(
00504       "Click for a dialog that can help you creating a list of mimetypes.") );
00505 
00506   cmbSave = new QComboBox(w);
00507   lo->addMultiCellWidget( cmbSave, 5, 5, 2, 3 );
00508   l = new QLabel( cmbSave, i18n("&Save:"), w );
00509   l->setAlignment( l->alignment()|Qt::AlignRight );
00510   lo->addWidget( l, 5, 1 );
00511   QStringList sl;
00512   sl << i18n("None") << i18n("Current Document") << i18n("All Documents");
00513   cmbSave->insertStringList( sl );
00514   if ( tool ) cmbSave->setCurrentItem( tool->save );
00515   QWhatsThis::add( cmbSave, i18n(
00516       "You can elect to save the current or all [modified] documents prior to "
00517       "running the command. This is helpful if you want to pass URLs to "
00518       "an application like, for example, an FTP client.") );
00519 
00520 
00521   leCmdLine = new QLineEdit( w );
00522   lo->addMultiCellWidget( leCmdLine, 6, 6, 2, 3 );
00523   l = new QLabel( leCmdLine, i18n("&Command line name:"), w );
00524   l->setAlignment( l->alignment()|Qt::AlignRight );
00525   lo->addWidget( l, 6, 1 );
00526   if ( tool ) leCmdLine->setText( tool->cmdname );
00527   QWhatsThis::add( leCmdLine, i18n(
00528       "If you specify a name here, you can invoke the command from the view "
00529       "command lines with exttool-the_name_you_specified_here. "
00530       "Please do not use spaces or tabs in the name."));
00531 
00532 }
00533 
00534 void KateExternalToolServiceEditor::slotOk()
00535 {
00536   if ( leName->text().isEmpty() ||
00537        teCommand->text().isEmpty() )
00538   {
00539     KMessageBox::information( this, i18n("You must specify at least a name and a command") );
00540     return;
00541   }
00542 
00543   KDialogBase::slotOk();
00544 }
00545 
00546 void KateExternalToolServiceEditor::showMTDlg()
00547 {
00548   QString text = i18n("Select the MimeTypes for which to enable this tool.");
00549   QStringList list = QStringList::split( QRegExp("\\s*;\\s*"), leMimetypes->text() );
00550   KMimeTypeChooserDialog d( i18n("Select Mime Types"), text, list, "text", this );
00551   if ( d.exec() == KDialogBase::Accepted ) {
00552     leMimetypes->setText( d.chooser()->mimeTypes().join(";") );
00553   }
00554 }
00555 //END KateExternalToolServiceEditor
00556 
00557 //BEGIN KateExternalToolsConfigWidget
00558 KateExternalToolsConfigWidget::KateExternalToolsConfigWidget( QWidget *parent, const char* name )
00559   : Kate::ConfigPage( parent, name ),
00560     m_changed( false )
00561 {
00562   QGridLayout *lo = new QGridLayout( this, 5, 5, 0, KDialog::spacingHint() );
00563 
00564   lbTools = new KListBox( this );
00565   lo->addMultiCellWidget( lbTools, 1, 4, 0, 3 );
00566   connect( lbTools, SIGNAL(selectionChanged()), this, SLOT(slotSelectionChanged()) );
00567 
00568   btnNew = new QPushButton( i18n("&New..."), this );
00569   lo->addWidget( btnNew, 5, 0 );
00570   connect( btnNew, SIGNAL(clicked()), this, SLOT(slotNew()) );
00571 
00572   btnRemove = new QPushButton( i18n("&Remove"), this );
00573   lo->addWidget( btnRemove, 5, 2 );
00574   connect( btnRemove, SIGNAL(clicked()), this, SLOT(slotRemove()) );
00575 
00576   btnEdit = new QPushButton( i18n("&Edit..."), this );
00577   lo->addWidget( btnEdit, 5, 1 );
00578   connect( btnEdit, SIGNAL(clicked()), this, SLOT(slotEdit()) );
00579 
00580   QPushButton *b = new QPushButton( i18n("Insert &Separator"), this );
00581   lo->addWidget( b, 5, 3 );
00582   connect( b, SIGNAL(clicked()), this, SLOT(slotInsertSeparator()) );
00583 
00584   btnMoveUp = new QPushButton( SmallIconSet("up"), "", this );
00585   lo->addWidget( btnMoveUp, 2, 4 );
00586   connect( btnMoveUp, SIGNAL(clicked()), this, SLOT(slotMoveUp()) );
00587 
00588   btnMoveDwn = new QPushButton( SmallIconSet("down"), "", this );
00589   lo->addWidget( btnMoveDwn, 3, 4 );
00590   connect( btnMoveDwn, SIGNAL(clicked()), this, SLOT(slotMoveDown()) );
00591 
00592   connect( lbTools, SIGNAL( doubleClicked ( QListBoxItem * ) ), this,  SLOT( slotEdit() ) );
00593 
00594   lo->setRowStretch( 1, 1 );
00595   lo->setRowStretch( 4, 1 );
00596   lo->setColStretch( 0, 1 );
00597   lo->setColStretch( 1, 1 );
00598   lo->setColStretch( 2, 1 );
00599 
00600 
00601   QWhatsThis::add( lbTools, i18n(
00602       "This list shows all the configured tools, represented by their menu text.") );
00603 
00604   config = new KConfig("externaltools", false, false, "appdata");
00605   reload();
00606   slotSelectionChanged();
00607 }
00608 
00609 KateExternalToolsConfigWidget::~KateExternalToolsConfigWidget()
00610 {
00611   delete config;
00612 }
00613 
00614 void KateExternalToolsConfigWidget::reload()
00615 {
00616   //m_tools.clear();
00617   lbTools->clear();
00618 
00619   // load the files from a KConfig
00620   config->setGroup( "Global" );
00621   QStringList tools = config->readListEntry("tools");
00622 
00623   for( QStringList::Iterator it = tools.begin(); it != tools.end(); ++it )
00624   {
00625     if ( *it == "---" )
00626     {
00627       new QListBoxText( lbTools, "---" );
00628     }
00629     else
00630     {
00631       config->setGroup( *it );
00632 
00633       KateExternalTool *t = new KateExternalTool(
00634           config->readEntry( "name", "" ),
00635           config->readEntry( "command", ""),
00636           config->readEntry( "icon", ""),
00637           config->readEntry( "executable", ""),
00638           config->readListEntry( "mimetypes" ),
00639           config->readEntry( "acname" ),
00640       config->readEntry( "cmdname"),
00641           config->readNumEntry( "save", 0 ) );
00642 
00643       if ( t->hasexec ) // we only show tools that are also in the menu.
00644         new ToolItem( lbTools, t->icon.isEmpty() ? blankIcon() : SmallIcon( t->icon ), t );
00645     }
00646   }
00647   m_changed = false;
00648 }
00649 
00650 QPixmap KateExternalToolsConfigWidget::blankIcon()
00651 {
00652   QPixmap pm( KIcon::SizeSmall, KIcon::SizeSmall );
00653   pm.fill();
00654   pm.setMask( pm.createHeuristicMask() );
00655   return pm;
00656 }
00657 
00658 void KateExternalToolsConfigWidget::apply()
00659 {
00660   if ( ! m_changed )
00661     return;
00662   m_changed = false;
00663 
00664   // save a new list
00665   // save each item
00666   QStringList tools;
00667   for ( uint i = 0; i < lbTools->count(); i++ )
00668   {
00669     if ( lbTools->text( i ) == "---" )
00670     {
00671       tools << "---";
00672       continue;
00673     }
00674     KateExternalTool *t = ((ToolItem*)lbTools->item( i ))->tool;
00675 //     kdDebug(13001)<<"adding tool: "<<t->name<<endl;
00676     tools << t->acname;
00677 
00678     config->setGroup( t->acname );
00679     config->writeEntry( "name", t->name );
00680     config->writeEntry( "command", t->command );
00681     config->writeEntry( "icon", t->icon );
00682     config->writeEntry( "executable", t->tryexec );
00683     config->writeEntry( "mimetypes", t->mimetypes );
00684     config->writeEntry( "acname", t->acname );
00685     config->writeEntry( "cmdname", t->cmdname );
00686     config->writeEntry( "save", t->save );
00687   }
00688 
00689   config->setGroup("Global");
00690   config->writeEntry( "tools", tools );
00691 
00692   // if any tools was removed, try to delete their groups, and
00693   // add the group names to the list of removed items.
00694   if ( m_removed.count() )
00695   {
00696     for ( QStringList::iterator it = m_removed.begin(); it != m_removed.end(); ++it )
00697     {
00698       if ( config->hasGroup( *it ) )
00699         config->deleteGroup( *it  );
00700     }
00701     QStringList removed = config->readListEntry( "removed" );
00702     removed += m_removed;
00703 
00704     // clean up the list of removed items, so that it does not contain
00705     // non-existing groups (we can't remove groups from a non-owned global file).
00706     config->sync();
00707     QStringList::iterator it1 = removed.begin();
00708     while( it1 != removed.end() )
00709     {
00710       if ( ! config->hasGroup( *it1 ) )
00711         it1 = removed.remove( it1 );
00712       else
00713         ++it1;
00714     }
00715     config->writeEntry( "removed", removed );
00716   }
00717 
00718   config->sync();
00719 }
00720 
00721 void KateExternalToolsConfigWidget::slotSelectionChanged()
00722 {
00723   // update button state
00724   bool hs =  lbTools->selectedItem() != 0;
00725   btnEdit->setEnabled( hs && dynamic_cast<ToolItem*>(lbTools->selectedItem()) );
00726   btnRemove->setEnabled( hs );
00727   btnMoveUp->setEnabled( ( lbTools->currentItem() > 0 ) && hs );
00728   btnMoveDwn->setEnabled( ( lbTools->currentItem() < (int)lbTools->count()-1 )&&hs );
00729 }
00730 
00731 void KateExternalToolsConfigWidget::slotNew()
00732 {
00733   // display a editor, and if it is OK'd, create a new tool and
00734   // create a listbox item for it
00735   KateExternalToolServiceEditor editor( 0, this );
00736 
00737   if ( editor.exec() )
00738   {
00739     KateExternalTool *t = new KateExternalTool(
00740       editor.leName->text(),
00741       editor.teCommand->text(),
00742       editor.btnIcon->icon(),
00743       editor.leExecutable->text(),
00744       QStringList::split( QRegExp("\\s*;\\s*"), editor.leMimetypes->text() ) );
00745 
00746     // This is sticky, it does not change again, so that shortcuts sticks
00747     // TODO check for dups
00748     t->acname = "externaltool_" + QString(t->name).replace( QRegExp("\\W+"), "" );
00749 
00750     new ToolItem ( lbTools, t->icon.isEmpty() ? blankIcon() : SmallIcon( t->icon ), t );
00751 
00752     slotChanged();
00753     m_changed = true;
00754   }
00755 }
00756 
00757 void KateExternalToolsConfigWidget::slotRemove()
00758 {
00759   // add the tool action name to a list of removed items,
00760   // remove the current listbox item
00761   if ( lbTools->currentItem() > -1 ) {
00762     ToolItem *i = dynamic_cast<ToolItem*>(lbTools->selectedItem());
00763     if ( i )
00764       m_removed << i->tool->acname;
00765 
00766     lbTools->removeItem( lbTools->currentItem() );
00767     slotChanged();
00768     m_changed = true;
00769   }
00770 }
00771 
00772 void KateExternalToolsConfigWidget::slotEdit()
00773 {
00774   if( !dynamic_cast<ToolItem*>(lbTools->selectedItem()) ) return;
00775   // show the item in an editor
00776   KateExternalTool *t = ((ToolItem*)lbTools->selectedItem())->tool;
00777   KateExternalToolServiceEditor editor( t, this);
00778   config->setGroup( "Editor" );
00779   editor.resize( config->readSizeEntry( "Size" ) );
00780   if ( editor.exec() /*== KDialogBase::Ok*/ )
00781   {
00782 
00783       bool elementChanged = ( ( editor.btnIcon->icon() != t->icon ) || (editor.leName->text() != t->name ) ) ;
00784 
00785     t->name = editor.leName->text();
00786     t->cmdname = editor.leCmdLine->text();
00787     t->command = editor.teCommand->text();
00788     t->icon = editor.btnIcon->icon();
00789     t->tryexec = editor.leExecutable->text();
00790     t->mimetypes = QStringList::split( QRegExp("\\s*;\\s*"), editor.leMimetypes->text() );
00791     t->save = editor.cmbSave->currentItem();
00792 
00793     //if the icon has changed or name changed, I have to renew the listbox item :S
00794     if ( elementChanged )
00795     {
00796       int idx = lbTools->index( lbTools->selectedItem() );
00797       lbTools->removeItem( idx );
00798       lbTools->insertItem( new ToolItem( 0, t->icon.isEmpty() ? blankIcon() : SmallIcon( t->icon ), t ), idx );
00799     }
00800 
00801     slotChanged();
00802     m_changed = true;
00803   }
00804 
00805   config->setGroup( "Editor" );
00806   config->writeEntry( "Size", editor.size() );
00807   config->sync();
00808 }
00809 
00810 void KateExternalToolsConfigWidget::slotInsertSeparator()
00811 {
00812   lbTools->insertItem( "---", lbTools->currentItem()+1 );
00813   slotChanged();
00814   m_changed = true;
00815 }
00816 
00817 void KateExternalToolsConfigWidget::slotMoveUp()
00818 {
00819   // move the current item in the listbox upwards if possible
00820   QListBoxItem *item = lbTools->selectedItem();
00821   if ( ! item ) return;
00822 
00823   int idx = lbTools->index( item );
00824 
00825   if ( idx < 1 ) return;
00826 
00827   if ( dynamic_cast<ToolItem*>(item) )
00828   {
00829     KateExternalTool *tool = ((ToolItem*)item)->tool;
00830     lbTools->removeItem( idx );
00831     lbTools->insertItem( new ToolItem( 0, tool->icon.isEmpty() ? blankIcon() : SmallIcon( tool->icon ), tool ), idx-1 );
00832   }
00833   else // a separator!
00834   {
00835     lbTools->removeItem( idx );
00836     lbTools->insertItem( new QListBoxText( 0, "---" ), idx-1 );
00837   }
00838 
00839   lbTools->setCurrentItem( idx - 1 );
00840   slotSelectionChanged();
00841   slotChanged();
00842   m_changed = true;
00843 }
00844 
00845 void KateExternalToolsConfigWidget::slotMoveDown()
00846 {
00847   // move the current item in the listbox downwards if possible
00848   QListBoxItem *item = lbTools->selectedItem();
00849   if ( ! item ) return;
00850 
00851   uint idx = lbTools->index( item );
00852 
00853   if ( idx > lbTools->count()-1 ) return;
00854 
00855   if ( dynamic_cast<ToolItem*>(item) )
00856   {
00857     KateExternalTool *tool = ((ToolItem*)item)->tool;
00858     lbTools->removeItem( idx );
00859     lbTools->insertItem( new ToolItem( 0, tool->icon.isEmpty() ? blankIcon() : SmallIcon( tool->icon ), tool ), idx+1 );
00860   }
00861   else // a separator!
00862   {
00863     lbTools->removeItem( idx );
00864     lbTools->insertItem( new QListBoxText( 0, "---" ), idx+1 );
00865   }
00866 
00867   lbTools->setCurrentItem( idx+1 );
00868   slotSelectionChanged();
00869   slotChanged();
00870   m_changed = true;
00871 }
00872 //END KateExternalToolsConfigWidget
00873 // 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

API Reference

Skip menu "API Reference"
  • kate
Generated for API Reference by doxygen 1.5.9
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