summaryrefslogtreecommitdiffstats
path: root/kate/app/kateexternaltools.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kate/app/kateexternaltools.cpp')
-rw-r--r--kate/app/kateexternaltools.cpp873
1 files changed, 873 insertions, 0 deletions
diff --git a/kate/app/kateexternaltools.cpp b/kate/app/kateexternaltools.cpp
new file mode 100644
index 000000000..50c07709b
--- /dev/null
+++ b/kate/app/kateexternaltools.cpp
@@ -0,0 +1,873 @@
+/*
+ This file is part of the Kate text editor of the KDE project.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+
+ ---
+ Copyright (C) 2004, Anders Lund <anders@alweb.dk>
+*/
+// TODO
+// Icons
+// Direct shortcut setting
+//BEGIN Includes
+#include "kateexternaltools.h"
+#include "kateexternaltools.moc"
+#include "katedocmanager.h"
+#include "kateviewmanager.h"
+#include "kateapp.h"
+
+#include "katemainwindow.h"
+
+#include <kate/view.h>
+#include <kate/document.h>
+
+#include <klistbox.h>
+#include <klocale.h>
+#include <kiconloader.h>
+#include <kmessagebox.h>
+#include <kmimetypechooser.h>
+#include <kconfig.h>
+#include <krun.h>
+#include <kicondialog.h>
+#include <kpopupmenu.h>
+#include <kdebug.h>
+
+#include <qbitmap.h>
+#include <qcombobox.h>
+#include <qfile.h>
+#include <qpushbutton.h>
+#include <qlineedit.h>
+#include <qlayout.h>
+#include <qlabel.h>
+#include <qlistbox.h>
+#include <qmap.h>
+#include <qregexp.h>
+#include <qtextedit.h>
+#include <qtoolbutton.h>
+#include <qwhatsthis.h>
+
+#include <stdlib.h>
+#include <unistd.h>
+//END Includes
+
+KateExternalToolsCommand *KateExternalToolsCommand::s_self=0;
+
+//BEGIN KateExternalTool
+KateExternalTool::KateExternalTool( const QString &name,
+ const QString &command,
+ const QString &icon,
+ const QString &tryexec,
+ const QStringList &mimetypes,
+ const QString &acname,
+ const QString &cmdname,
+ int save )
+ : name ( name ),
+ command ( command ),
+ icon ( icon ),
+ tryexec ( tryexec ),
+ mimetypes ( mimetypes ),
+ acname ( acname ),
+ cmdname ( cmdname ),
+ save ( save )
+{
+ //if ( ! tryexec.isEmpty() )
+ hasexec = checkExec();
+}
+
+bool KateExternalTool::checkExec()
+{
+ // if tryexec is empty, it is the first word of command
+ if ( tryexec.isEmpty() )
+ tryexec = command.section( " ", 0, 0, QString::SectionSkipEmpty );
+
+ // NOTE this code is modified taken from kdesktopfile.cpp, from KDesktopFile::tryExec()
+ if (!tryexec.isEmpty()) {
+ if (tryexec[0] == '/') {
+ if (::access(QFile::encodeName(tryexec), R_OK | X_OK))
+ return false;
+
+ m_exec = tryexec;
+ } else {
+ // !!! Sergey A. Sukiyazov <corwin@micom.don.ru> !!!
+ // Environment PATH may contain filenames in 8bit locale cpecified
+ // encoding (Like a filenames).
+ QStringList dirs = QStringList::split(':', QFile::decodeName(::getenv("PATH")));
+ QStringList::Iterator it(dirs.begin());
+ bool match = false;
+ for (; it != dirs.end(); ++it)
+ {
+ QString fName = *it + "/" + tryexec;
+ if (::access(QFile::encodeName(fName), R_OK | X_OK) == 0)
+ {
+ match = true;
+ m_exec = fName;
+ break;
+ }
+ }
+ // didn't match at all
+ if (!match)
+ return false;
+ }
+ return true;
+ }
+ return false;
+}
+
+bool KateExternalTool::valid( const QString &mt ) const
+{
+ return mimetypes.isEmpty() || mimetypes.contains( mt );
+}
+//END KateExternalTool
+
+//BEGIN KateExternalToolsCommand
+KateExternalToolsCommand::KateExternalToolsCommand() : Kate::Command() {
+ m_inited=false;
+ reload();
+}
+
+QStringList KateExternalToolsCommand::cmds () {
+ return m_list;
+}
+
+KateExternalToolsCommand *KateExternalToolsCommand::self () {
+ if (s_self) return s_self;
+ s_self=new KateExternalToolsCommand;
+ return s_self;
+}
+
+void KateExternalToolsCommand::reload () {
+ m_list.clear();
+ m_map.clear();
+
+ KConfig config("externaltools", false, false, "appdata");
+ config.setGroup("Global");
+ QStringList tools = config.readListEntry("tools");
+
+
+ for( QStringList::Iterator it = tools.begin(); it != tools.end(); ++it )
+ {
+ if ( *it == "---" )
+ continue;
+
+
+ config.setGroup( *it );
+
+ KateExternalTool t = KateExternalTool(
+ config.readEntry( "name", "" ),
+ config.readEntry( "command", ""),
+ config.readEntry( "icon", ""),
+ config.readEntry( "executable", ""),
+ config.readListEntry( "mimetypes" ),
+ config.readEntry( "acname", "" ),
+ config.readEntry( "cmdname", "" ) );
+ // FIXME test for a command name first!
+ if ( t.hasexec && (!t.cmdname.isEmpty())) {
+ m_list.append("exttool-"+t.cmdname);
+ m_map.insert("exttool-"+t.cmdname,t.acname);
+ }
+ }
+ if (m_inited) {
+ Kate::Document::unregisterCommand(this);
+ Kate::Document::registerCommand(this);
+ }
+ else m_inited=true;
+}
+
+bool KateExternalToolsCommand::exec (Kate::View *view, const QString &cmd, QString &) {
+ QWidget *wv=dynamic_cast<QWidget*>(view);
+ if (!wv) {
+// kdDebug(13001)<<"KateExternalToolsCommand::exec: Could not get view widget"<<endl;
+ return false;
+ }
+ KateMDI::MainWindow *dmw=dynamic_cast<KateMDI::MainWindow*>(wv->topLevelWidget());
+ if (!dmw) {
+// kdDebug(13001)<<"KateExternalToolsCommand::exec: Could not get main window"<<endl;
+ return false;
+ }
+// kdDebug(13001)<<"cmd="<<cmd.stripWhiteSpace()<<endl;
+ QString actionName=m_map[cmd.stripWhiteSpace()];
+ if (actionName.isEmpty()) return false;
+// kdDebug(13001)<<"actionName is not empty:"<<actionName<<endl;
+ KateExternalToolsMenuAction *a=
+ dynamic_cast<KateExternalToolsMenuAction*>(dmw->action("tools_external"));
+ if (!a) return false;
+// kdDebug(13001)<<"trying to find action"<<endl;
+ KAction *a1=a->actionCollection()->action(actionName.utf8());
+ if (!a1) return false;
+// kdDebug(13001)<<"activating action"<<endl;
+ a1->activate();
+ return true;
+}
+
+bool KateExternalToolsCommand::help (Kate::View *, const QString &, QString &) {
+ return false;
+}
+//END KateExternalToolsCommand
+
+//BEGIN KateExternalToolAction
+KateExternalToolAction::KateExternalToolAction( QObject *parent,
+ const char *name, KateExternalTool *t)
+ : KAction( parent, name ),
+ tool ( t )
+{
+ setText( t->name );
+ if ( ! t->icon.isEmpty() )
+ setIconSet( SmallIconSet( t->icon ) );
+
+ connect( this ,SIGNAL(activated()), this, SLOT(slotRun()) );
+}
+
+bool KateExternalToolAction::expandMacro( const QString &str, QStringList &ret )
+{
+ KateMainWindow *mw = (KateMainWindow*)parent()->parent();
+
+ Kate::View *view = mw->viewManager()->activeView();
+ if ( ! view ) return false;
+
+
+ if ( str == "URL" )
+ ret += mw->activeDocumentUrl().url();
+ else if ( str == "directory" ) // directory of current doc
+ ret += mw->activeDocumentUrl().directory();
+ else if ( str == "filename" )
+ ret += mw->activeDocumentUrl().fileName();
+ else if ( str == "line" ) // cursor line of current doc
+ ret += QString::number( view->cursorLine() );
+ else if ( str == "col" ) // cursor col of current doc
+ ret += QString::number( view->cursorColumn() );
+ else if ( str == "selection" ) // selection of current doc if any
+ ret += view->getDoc()->selection();
+ else if ( str == "text" ) // text of current doc
+ ret += view->getDoc()->text();
+ else if ( str == "URLs" ) {
+ for( Kate::Document *doc = KateDocManager::self()->firstDocument(); doc; doc = KateDocManager::self()->nextDocument() )
+ if ( ! doc->url().isEmpty() )
+ ret += doc->url().url();
+ } else
+ return false;
+ return true;
+}
+
+KateExternalToolAction::~KateExternalToolAction() {
+ delete(tool);
+}
+
+void KateExternalToolAction::slotRun()
+{
+ // expand the macros in command if any,
+ // and construct a command with an absolute path
+ QString cmd = tool->command;
+
+ if ( ! expandMacrosShellQuote( cmd ) )
+ {
+ KMessageBox::sorry( (KateMainWindow*)parent()->parent(),
+ i18n("Failed to expand the command '%1'.").arg( cmd ),
+ i18n( "Kate External Tools") );
+ return;
+ }
+ kdDebug(13001)<<"externaltools: Running command: "<<cmd<<endl;
+
+ // save documents if requested
+ KateMainWindow *mw = (KateMainWindow*)parent()->parent();
+ if ( tool->save == 1 )
+ mw->viewManager()->activeView()->document()->save();
+ else if ( tool->save == 2 )
+ mw->actionCollection()->action("file_save_all")->activate();
+
+ KRun::runCommand( cmd, tool->tryexec, tool->icon );
+}
+//END KateExternalToolAction
+
+//BEGIN KateExternalToolsMenuAction
+KateExternalToolsMenuAction::KateExternalToolsMenuAction( const QString &text,
+ QObject *parent,
+ const char* name,
+ KateMainWindow *mw )
+ : KActionMenu( text, parent, name ),
+ mainwindow( mw )
+{
+
+ m_actionCollection = new KActionCollection( mainwindow );
+
+ connect(KateDocManager::self(),SIGNAL(documentChanged()),this,SLOT(slotDocumentChanged()));
+
+ reload();
+}
+
+void KateExternalToolsMenuAction::reload()
+{
+ m_actionCollection->clear ();
+ popupMenu()->clear();
+
+ // load all the tools, and create a action for each of them
+ KConfig *config = new KConfig( "externaltools", false, false, "appdata" );
+ config->setGroup( "Global" );
+ QStringList tools = config->readListEntry( "tools" );
+
+ // if there are tools that are present but not explicitly removed,
+ // add them to the end of the list
+ config->setReadDefaults( true );
+ QStringList dtools = config->readListEntry( "tools" );
+ int gver = config->readNumEntry( "version", 1 );
+ config->setReadDefaults( false );
+
+ int ver = config->readNumEntry( "version" );
+ if ( ver <= gver )
+ {
+ QStringList removed = config->readListEntry( "removed" );
+ bool sepadded = false;
+ for (QStringList::iterator itg = dtools.begin(); itg != dtools.end(); ++itg )
+ {
+ if ( ! tools.contains( *itg ) &&
+ ! removed.contains( *itg ) )
+ {
+ if ( ! sepadded )
+ {
+ tools << "---";
+ sepadded = true;
+ }
+ tools << *itg;
+ }
+ }
+
+ config->writeEntry( "tools", tools );
+ config->sync();
+ config->writeEntry( "version", gver );
+ }
+
+ for( QStringList::Iterator it = tools.begin(); it != tools.end(); ++it )
+ {
+ if ( *it == "---" )
+ {
+ popupMenu()->insertSeparator();
+ // a separator
+ continue;
+ }
+
+ config->setGroup( *it );
+
+ KateExternalTool *t = new KateExternalTool(
+ config->readEntry( "name", "" ),
+ config->readEntry( "command", ""),
+ config->readEntry( "icon", ""),
+ config->readEntry( "executable", ""),
+ config->readListEntry( "mimetypes" ),
+ config->readEntry( "acname", "" ),
+ config->readEntry( "cmdname", "" ),
+ config->readNumEntry( "save", 0 ) );
+
+ if ( t->hasexec )
+ insert( new KateExternalToolAction( m_actionCollection, t->acname.ascii(), t ) );
+ }
+
+ m_actionCollection->readShortcutSettings( "Shortcuts", config );
+ slotDocumentChanged();
+ delete config;
+}
+
+void KateExternalToolsMenuAction::slotDocumentChanged()
+{
+ // try to enable/disable to match current mime type
+ Kate::DocumentExt *de = documentExt( KateDocManager::self()->activeDocument() );
+ if ( de )
+ {
+ QString mt = de->mimeType();
+ QStringList l;
+ bool b;
+
+ KActionPtrList actions = m_actionCollection->actions();
+ for (KActionPtrList::iterator it = actions.begin(); it != actions.end(); ++it )
+ {
+ KateExternalToolAction *action = dynamic_cast<KateExternalToolAction*>(*it);
+ if ( action )
+ {
+ l = action->tool->mimetypes;
+ b = ( ! l.count() || l.contains( mt ) );
+ action->setEnabled( b );
+ }
+ }
+ }
+}
+//END KateExternalToolsMenuAction
+
+//BEGIN ToolItem
+/**
+ * This is a QListBoxItem, that has a KateExternalTool. The text is the Name
+ * of the tool.
+ */
+class ToolItem : public QListBoxPixmap
+{
+ public:
+ ToolItem( QListBox *lb, const QPixmap &icon, KateExternalTool *tool )
+ : QListBoxPixmap( lb, icon, tool->name ),
+ tool ( tool )
+ {;}
+
+ ~ToolItem() {};
+
+ KateExternalTool *tool;
+};
+//END ToolItem
+
+//BEGIN KateExternalToolServiceEditor
+KateExternalToolServiceEditor::KateExternalToolServiceEditor( KateExternalTool *tool,
+ QWidget *parent, const char *name )
+ : KDialogBase( parent, name, true, i18n("Edit External Tool"), KDialogBase::Ok|KDialogBase::Cancel ),
+ tool( tool )
+{
+ // create a entry for each property
+ // fill in the values from the service if available
+ QWidget *w = new QWidget( this );
+ setMainWidget( w );
+ QGridLayout *lo = new QGridLayout( w );
+ lo->setSpacing( KDialogBase::spacingHint() );
+
+ QLabel *l;
+
+ leName = new QLineEdit( w );
+ lo->addWidget( leName, 1, 2 );
+ l = new QLabel( leName, i18n("&Label:"), w );
+ l->setAlignment( l->alignment()|Qt::AlignRight );
+ lo->addWidget( l, 1, 1 );
+ if ( tool ) leName->setText( tool->name );
+ QWhatsThis::add( leName, i18n(
+ "The name will be displayed in the 'Tools->External' menu") );
+
+ btnIcon = new KIconButton( w );
+ btnIcon->setIconSize( KIcon::SizeSmall );
+ lo->addWidget( btnIcon, 1, 3 );
+ if ( tool && !tool->icon.isEmpty() )
+ btnIcon->setIcon( tool->icon );
+
+ teCommand = new QTextEdit( w );
+ lo->addMultiCellWidget( teCommand, 2, 2, 2, 3 );
+ l = new QLabel( teCommand, i18n("S&cript:"), w );
+ l->setAlignment( Qt::AlignTop|Qt::AlignRight );
+ lo->addWidget( l, 2, 1 );
+ if ( tool ) teCommand->setText( tool->command );
+ QWhatsThis::add( teCommand, i18n(
+ "<p>The script to execute to invoke the tool. The script is passed "
+ "to /bin/sh for execution. The following macros "
+ "will be expanded:</p>"
+ "<ul><li><code>%URL</code> - the URL of the current document."
+ "<li><code>%URLs</code> - a list of the URLs of all open documents."
+ "<li><code>%directory</code> - the URL of the directory containing "
+ "the current document."
+ "<li><code>%filename</code> - the filename of the current document."
+ "<li><code>%line</code> - the current line of the text cursor in the "
+ "current view."
+ "<li><code>%column</code> - the column of the text cursor in the "
+ "current view."
+ "<li><code>%selection</code> - the selected text in the current view."
+ "<li><code>%text</code> - the text of the current document.</ul>" ) );
+
+
+ leExecutable = new QLineEdit( w );
+ lo->addMultiCellWidget( leExecutable, 3, 3, 2, 3 );
+ l = new QLabel( leExecutable, i18n("&Executable:"), w );
+ l->setAlignment( l->alignment()|Qt::AlignRight );
+ lo->addWidget( l, 3, 1 );
+ if ( tool ) leExecutable->setText( tool->tryexec );
+ QWhatsThis::add( leExecutable, i18n(
+ "The executable used by the command. This is used to check if a tool "
+ "should be displayed; if not set, the first word of <em>command</em> "
+ "will be used.") );
+
+ leMimetypes = new QLineEdit( w );
+ lo->addWidget( leMimetypes, 4, 2 );
+ l = new QLabel( leMimetypes, i18n("&Mime types:"), w );
+ l->setAlignment( l->alignment()|Qt::AlignRight );
+ lo->addWidget( l, 4, 1 );
+ if ( tool ) leMimetypes->setText( tool->mimetypes.join("; ") );
+ QWhatsThis::add( leMimetypes, i18n(
+ "A semicolon-separated list of mime types for which this tool should "
+ "be available; if this is left empty, the tool is always available. "
+ "To choose from known mimetypes, press the button on the right.") );
+
+ QToolButton *btnMTW = new QToolButton(w);
+ lo->addWidget( btnMTW, 4, 3 );
+ btnMTW->setIconSet(QIconSet(SmallIcon("wizard")));
+ connect(btnMTW, SIGNAL(clicked()), this, SLOT(showMTDlg()));
+ QWhatsThis::add( btnMTW, i18n(
+ "Click for a dialog that can help you creating a list of mimetypes.") );
+
+ cmbSave = new QComboBox(w);
+ lo->addMultiCellWidget( cmbSave, 5, 5, 2, 3 );
+ l = new QLabel( cmbSave, i18n("&Save:"), w );
+ l->setAlignment( l->alignment()|Qt::AlignRight );
+ lo->addWidget( l, 5, 1 );
+ QStringList sl;
+ sl << i18n("None") << i18n("Current Document") << i18n("All Documents");
+ cmbSave->insertStringList( sl );
+ if ( tool ) cmbSave->setCurrentItem( tool->save );
+ QWhatsThis::add( cmbSave, i18n(
+ "You can elect to save the current or all [modified] documents prior to "
+ "running the command. This is helpful if you want to pass URLs to "
+ "an application like, for example, an FTP client.") );
+
+
+ leCmdLine = new QLineEdit( w );
+ lo->addMultiCellWidget( leCmdLine, 6, 6, 2, 3 );
+ l = new QLabel( leCmdLine, i18n("&Command line name:"), w );
+ l->setAlignment( l->alignment()|Qt::AlignRight );
+ lo->addWidget( l, 6, 1 );
+ if ( tool ) leCmdLine->setText( tool->cmdname );
+ QWhatsThis::add( leCmdLine, i18n(
+ "If you specify a name here, you can invoke the command from the view "
+ "command lines with exttool-the_name_you_specified_here. "
+ "Please do not use spaces or tabs in the name."));
+
+}
+
+void KateExternalToolServiceEditor::slotOk()
+{
+ if ( leName->text().isEmpty() ||
+ teCommand->text().isEmpty() )
+ {
+ KMessageBox::information( this, i18n("You must specify at least a name and a command") );
+ return;
+ }
+
+ KDialogBase::slotOk();
+}
+
+void KateExternalToolServiceEditor::showMTDlg()
+{
+ QString text = i18n("Select the MimeTypes for which to enable this tool.");
+ QStringList list = QStringList::split( QRegExp("\\s*;\\s*"), leMimetypes->text() );
+ KMimeTypeChooserDialog d( i18n("Select Mime Types"), text, list, "text", this );
+ if ( d.exec() == KDialogBase::Accepted ) {
+ leMimetypes->setText( d.chooser()->mimeTypes().join(";") );
+ }
+}
+//END KateExternalToolServiceEditor
+
+//BEGIN KateExternalToolsConfigWidget
+KateExternalToolsConfigWidget::KateExternalToolsConfigWidget( QWidget *parent, const char* name )
+ : Kate::ConfigPage( parent, name ),
+ m_changed( false )
+{
+ QGridLayout *lo = new QGridLayout( this, 5, 5, 0, KDialog::spacingHint() );
+
+ lbTools = new KListBox( this );
+ lo->addMultiCellWidget( lbTools, 1, 4, 0, 3 );
+ connect( lbTools, SIGNAL(selectionChanged()), this, SLOT(slotSelectionChanged()) );
+
+ btnNew = new QPushButton( i18n("&New..."), this );
+ lo->addWidget( btnNew, 5, 0 );
+ connect( btnNew, SIGNAL(clicked()), this, SLOT(slotNew()) );
+
+ btnRemove = new QPushButton( i18n("&Remove"), this );
+ lo->addWidget( btnRemove, 5, 2 );
+ connect( btnRemove, SIGNAL(clicked()), this, SLOT(slotRemove()) );
+
+ btnEdit = new QPushButton( i18n("&Edit..."), this );
+ lo->addWidget( btnEdit, 5, 1 );
+ connect( btnEdit, SIGNAL(clicked()), this, SLOT(slotEdit()) );
+
+ QPushButton *b = new QPushButton( i18n("Insert &Separator"), this );
+ lo->addWidget( b, 5, 3 );
+ connect( b, SIGNAL(clicked()), this, SLOT(slotInsertSeparator()) );
+
+ btnMoveUp = new QPushButton( SmallIconSet("up"), "", this );
+ lo->addWidget( btnMoveUp, 2, 4 );
+ connect( btnMoveUp, SIGNAL(clicked()), this, SLOT(slotMoveUp()) );
+
+ btnMoveDwn = new QPushButton( SmallIconSet("down"), "", this );
+ lo->addWidget( btnMoveDwn, 3, 4 );
+ connect( btnMoveDwn, SIGNAL(clicked()), this, SLOT(slotMoveDown()) );
+
+ connect( lbTools, SIGNAL( doubleClicked ( QListBoxItem * ) ), this, SLOT( slotEdit() ) );
+
+ lo->setRowStretch( 1, 1 );
+ lo->setRowStretch( 4, 1 );
+ lo->setColStretch( 0, 1 );
+ lo->setColStretch( 1, 1 );
+ lo->setColStretch( 2, 1 );
+
+
+ QWhatsThis::add( lbTools, i18n(
+ "This list shows all the configured tools, represented by their menu text.") );
+
+ config = new KConfig("externaltools", false, false, "appdata");
+ reload();
+ slotSelectionChanged();
+}
+
+KateExternalToolsConfigWidget::~KateExternalToolsConfigWidget()
+{
+ delete config;
+}
+
+void KateExternalToolsConfigWidget::reload()
+{
+ //m_tools.clear();
+ lbTools->clear();
+
+ // load the files from a KConfig
+ config->setGroup( "Global" );
+ QStringList tools = config->readListEntry("tools");
+
+ for( QStringList::Iterator it = tools.begin(); it != tools.end(); ++it )
+ {
+ if ( *it == "---" )
+ {
+ new QListBoxText( lbTools, "---" );
+ }
+ else
+ {
+ config->setGroup( *it );
+
+ KateExternalTool *t = new KateExternalTool(
+ config->readEntry( "name", "" ),
+ config->readEntry( "command", ""),
+ config->readEntry( "icon", ""),
+ config->readEntry( "executable", ""),
+ config->readListEntry( "mimetypes" ),
+ config->readEntry( "acname" ),
+ config->readEntry( "cmdname"),
+ config->readNumEntry( "save", 0 ) );
+
+ if ( t->hasexec ) // we only show tools that are also in the menu.
+ new ToolItem( lbTools, t->icon.isEmpty() ? blankIcon() : SmallIcon( t->icon ), t );
+ }
+ }
+ m_changed = false;
+}
+
+QPixmap KateExternalToolsConfigWidget::blankIcon()
+{
+ QPixmap pm( KIcon::SizeSmall, KIcon::SizeSmall );
+ pm.fill();
+ pm.setMask( pm.createHeuristicMask() );
+ return pm;
+}
+
+void KateExternalToolsConfigWidget::apply()
+{
+ if ( ! m_changed )
+ return;
+ m_changed = false;
+
+ // save a new list
+ // save each item
+ QStringList tools;
+ for ( uint i = 0; i < lbTools->count(); i++ )
+ {
+ if ( lbTools->text( i ) == "---" )
+ {
+ tools << "---";
+ continue;
+ }
+ KateExternalTool *t = ((ToolItem*)lbTools->item( i ))->tool;
+// kdDebug(13001)<<"adding tool: "<<t->name<<endl;
+ tools << t->acname;
+
+ config->setGroup( t->acname );
+ config->writeEntry( "name", t->name );
+ config->writeEntry( "command", t->command );
+ config->writeEntry( "icon", t->icon );
+ config->writeEntry( "executable", t->tryexec );
+ config->writeEntry( "mimetypes", t->mimetypes );
+ config->writeEntry( "acname", t->acname );
+ config->writeEntry( "cmdname", t->cmdname );
+ config->writeEntry( "save", t->save );
+ }
+
+ config->setGroup("Global");
+ config->writeEntry( "tools", tools );
+
+ // if any tools was removed, try to delete their groups, and
+ // add the group names to the list of removed items.
+ if ( m_removed.count() )
+ {
+ for ( QStringList::iterator it = m_removed.begin(); it != m_removed.end(); ++it )
+ {
+ if ( config->hasGroup( *it ) )
+ config->deleteGroup( *it );
+ }
+ QStringList removed = config->readListEntry( "removed" );
+ removed += m_removed;
+
+ // clean up the list of removed items, so that it does not contain
+ // non-existing groups (we can't remove groups from a non-owned global file).
+ config->sync();
+ QStringList::iterator it1 = removed.begin();
+ while( it1 != removed.end() )
+ {
+ if ( ! config->hasGroup( *it1 ) )
+ it1 = removed.remove( it1 );
+ else
+ ++it1;
+ }
+ config->writeEntry( "removed", removed );
+ }
+
+ config->sync();
+}
+
+void KateExternalToolsConfigWidget::slotSelectionChanged()
+{
+ // update button state
+ bool hs = lbTools->selectedItem() != 0;
+ btnEdit->setEnabled( hs && dynamic_cast<ToolItem*>(lbTools->selectedItem()) );
+ btnRemove->setEnabled( hs );
+ btnMoveUp->setEnabled( ( lbTools->currentItem() > 0 ) && hs );
+ btnMoveDwn->setEnabled( ( lbTools->currentItem() < (int)lbTools->count()-1 )&&hs );
+}
+
+void KateExternalToolsConfigWidget::slotNew()
+{
+ // display a editor, and if it is OK'd, create a new tool and
+ // create a listbox item for it
+ KateExternalToolServiceEditor editor( 0, this );
+
+ if ( editor.exec() )
+ {
+ KateExternalTool *t = new KateExternalTool(
+ editor.leName->text(),
+ editor.teCommand->text(),
+ editor.btnIcon->icon(),
+ editor.leExecutable->text(),
+ QStringList::split( QRegExp("\\s*;\\s*"), editor.leMimetypes->text() ) );
+
+ // This is sticky, it does not change again, so that shortcuts sticks
+ // TODO check for dups
+ t->acname = "externaltool_" + QString(t->name).replace( QRegExp("\\W+"), "" );
+
+ new ToolItem ( lbTools, t->icon.isEmpty() ? blankIcon() : SmallIcon( t->icon ), t );
+
+ slotChanged();
+ m_changed = true;
+ }
+}
+
+void KateExternalToolsConfigWidget::slotRemove()
+{
+ // add the tool action name to a list of removed items,
+ // remove the current listbox item
+ if ( lbTools->currentItem() > -1 ) {
+ ToolItem *i = dynamic_cast<ToolItem*>(lbTools->selectedItem());
+ if ( i )
+ m_removed << i->tool->acname;
+
+ lbTools->removeItem( lbTools->currentItem() );
+ slotChanged();
+ m_changed = true;
+ }
+}
+
+void KateExternalToolsConfigWidget::slotEdit()
+{
+ if( !dynamic_cast<ToolItem*>(lbTools->selectedItem()) ) return;
+ // show the item in an editor
+ KateExternalTool *t = ((ToolItem*)lbTools->selectedItem())->tool;
+ KateExternalToolServiceEditor editor( t, this);
+ config->setGroup( "Editor" );
+ editor.resize( config->readSizeEntry( "Size" ) );
+ if ( editor.exec() /*== KDialogBase::Ok*/ )
+ {
+
+ bool elementChanged = ( ( editor.btnIcon->icon() != t->icon ) || (editor.leName->text() != t->name ) ) ;
+
+ t->name = editor.leName->text();
+ t->cmdname = editor.leCmdLine->text();
+ t->command = editor.teCommand->text();
+ t->icon = editor.btnIcon->icon();
+ t->tryexec = editor.leExecutable->text();
+ t->mimetypes = QStringList::split( QRegExp("\\s*;\\s*"), editor.leMimetypes->text() );
+ t->save = editor.cmbSave->currentItem();
+
+ //if the icon has changed or name changed, I have to renew the listbox item :S
+ if ( elementChanged )
+ {
+ int idx = lbTools->index( lbTools->selectedItem() );
+ lbTools->removeItem( idx );
+ lbTools->insertItem( new ToolItem( 0, t->icon.isEmpty() ? blankIcon() : SmallIcon( t->icon ), t ), idx );
+ }
+
+ slotChanged();
+ m_changed = true;
+ }
+
+ config->setGroup( "Editor" );
+ config->writeEntry( "Size", editor.size() );
+ config->sync();
+}
+
+void KateExternalToolsConfigWidget::slotInsertSeparator()
+{
+ lbTools->insertItem( "---", lbTools->currentItem()+1 );
+ slotChanged();
+ m_changed = true;
+}
+
+void KateExternalToolsConfigWidget::slotMoveUp()
+{
+ // move the current item in the listbox upwards if possible
+ QListBoxItem *item = lbTools->selectedItem();
+ if ( ! item ) return;
+
+ int idx = lbTools->index( item );
+
+ if ( idx < 1 ) return;
+
+ if ( dynamic_cast<ToolItem*>(item) )
+ {
+ KateExternalTool *tool = ((ToolItem*)item)->tool;
+ lbTools->removeItem( idx );
+ lbTools->insertItem( new ToolItem( 0, tool->icon.isEmpty() ? blankIcon() : SmallIcon( tool->icon ), tool ), idx-1 );
+ }
+ else // a separator!
+ {
+ lbTools->removeItem( idx );
+ lbTools->insertItem( new QListBoxText( 0, "---" ), idx-1 );
+ }
+
+ lbTools->setCurrentItem( idx - 1 );
+ slotSelectionChanged();
+ slotChanged();
+ m_changed = true;
+}
+
+void KateExternalToolsConfigWidget::slotMoveDown()
+{
+ // move the current item in the listbox downwards if possible
+ QListBoxItem *item = lbTools->selectedItem();
+ if ( ! item ) return;
+
+ uint idx = lbTools->index( item );
+
+ if ( idx > lbTools->count()-1 ) return;
+
+ if ( dynamic_cast<ToolItem*>(item) )
+ {
+ KateExternalTool *tool = ((ToolItem*)item)->tool;
+ lbTools->removeItem( idx );
+ lbTools->insertItem( new ToolItem( 0, tool->icon.isEmpty() ? blankIcon() : SmallIcon( tool->icon ), tool ), idx+1 );
+ }
+ else // a separator!
+ {
+ lbTools->removeItem( idx );
+ lbTools->insertItem( new QListBoxText( 0, "---" ), idx+1 );
+ }
+
+ lbTools->setCurrentItem( idx+1 );
+ slotSelectionChanged();
+ slotChanged();
+ m_changed = true;
+}
+//END KateExternalToolsConfigWidget
+// kate: space-indent on; indent-width 2; replace-tabs on;