kate Library API Documentation

kateexternaltools.cpp

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