00001
#include "tools_part.h"
00002
00003
#include <qfile.h>
00004
#include <qpopupmenu.h>
00005
#include <qregexp.h>
00006
#include <qtimer.h>
00007
#include <qvbox.h>
00008
#include <qwhatsthis.h>
00009
00010
#include <kaction.h>
00011
#include <kapplication.h>
00012
#include <kconfig.h>
00013
#include <kdebug.h>
00014
#include <kdesktopfile.h>
00015
#include <kdialogbase.h>
00016
#include <kiconloader.h>
00017
#include <klocale.h>
00018
#include <kparts/part.h>
00019
#include <kprocess.h>
00020
#include <ktexteditor/editinterface.h>
00021
#include <ktexteditor/viewcursorinterface.h>
00022
#include <ktexteditor/selectioninterface.h>
00023
00024
#include "kdevcore.h"
00025
#include "kdevproject.h"
00026
#include "kdevpartcontroller.h"
00027
#include "kdevappfrontend.h"
00028
00029
#include "toolsconfig.h"
00030
#include "toolsconfigwidget.h"
00031
00032
00033
static const KAboutData data(
"kdevtools",
I18N_NOOP(
"External Tools"),
"1.0");
00034 K_EXPORT_COMPONENT_FACTORY( libkdevtools,
ToolsFactory( &data ) )
00035
00036
ToolsPart::
ToolsPart(
QObject *parent, const
char *name, const
QStringList &)
00037 :
KDevPlugin( "Tools", "tools", parent, name ? name : "
ToolsPart")
00038 {
00039 setInstance(ToolsFactory::instance());
00040
00041 setXMLFile(
"kdevpart_tools.rc");
00042
00043 connect(core(), SIGNAL(configWidget(
KDialogBase*)),
this, SLOT(configWidget(
KDialogBase*)));
00044
00045 connect(core(), SIGNAL(coreInitialized()),
this, SLOT(updateMenu()));
00046
00047 connect( core(), SIGNAL(contextMenu(
QPopupMenu *,
const Context *)),
00048
this, SLOT(contextMenu(
QPopupMenu *,
const Context *)) );
00049
00050
00051
00052 QTimer::singleShot(0,
this, SLOT(updateToolsMenu()));
00053 }
00054
00055
00056 ToolsPart::~ToolsPart()
00057 {
00058 }
00059
00060
00061 void ToolsPart::configWidget(
KDialogBase *dlg)
00062 {
00063
QVBox *vbox = dlg->
addVBoxPage(i18n(
"Tools Menu"));
00064
ToolsConfig *w =
new ToolsConfig(vbox,
"tools config widget");
00065 connect(dlg, SIGNAL(okClicked()), w, SLOT(accept()));
00066 connect(dlg, SIGNAL(destroyed()),
this, SLOT(
updateMenu()));
00067
00068 vbox = dlg->
addVBoxPage(i18n(
"External Tools"));
00069
ToolsConfigWidget *w2 =
new ToolsConfigWidget(vbox,
"tools config widget");
00070 connect(dlg, SIGNAL(okClicked()), w2, SLOT(accept()));
00071 connect(dlg, SIGNAL(destroyed()),
this, SLOT(
updateToolsMenu()));
00072 }
00073
00074
00075
00076 void ToolsPart::updateMenu()
00077 {
00078
QPtrList<KAction> actions;
00079
00080 unplugActionList(
"tools_list");
00081
00082
KConfig *config = ToolsFactory::instance()->config();
00083 config->
setGroup(
"Tools");
00084
00085
QStringList list = config->
readListEntry(
"Tools");
00086
for (QStringList::Iterator it = list.begin(); it != list.end(); ++it)
00087 {
00088
QString name = *it;
00089
00090
KDesktopFile df(name,
true);
00091
if (df.
readName().isNull())
00092
continue;
00093
00094
KAction *action =
new KAction(df.
readName(), df.
readIcon(), 0,
00095
this, SLOT(
slotToolActivated()), (
QObject*)0, name.latin1());
00096 actions.append(action);
00097 }
00098
00099 plugActionList(
"tools_list", actions);
00100 }
00101
00102
00103 void ToolsPart::slotToolActivated()
00104 {
00105
QString df = sender()->name();
00106 kapp->startServiceByDesktopPath(df);
00107 }
00108
00109
00110
00111
00112 static QString currentWord(
KTextEditor::EditInterface *editiface,
00113
KTextEditor::ViewCursorInterface *cursoriface)
00114 {
00115 uint line, col;
00116 cursoriface->
cursorPositionReal(&line, &col);
00117
QString str = editiface->
textLine(line);
00118
int i;
00119
for (i = col-1; i >= 0; --i)
00120
if (!str[i].isLetter())
00121
break;
00122
00123
return str.mid(i+1, col-i-1);
00124 }
00125
00126
00127 void ToolsPart::startCommand(
QString cmdline,
bool captured,
QString fileName)
00128 {
00129
KParts::Part *part =
partController()->
activePart();
00130
KParts::ReadWritePart *rwpart
00131 = dynamic_cast<KParts::ReadWritePart*>(part);
00132
KTextEditor::SelectionInterface *selectionIface
00133 = dynamic_cast<KTextEditor::SelectionInterface*>(part);
00134
KTextEditor::EditInterface *editIface
00135 = dynamic_cast<KTextEditor::EditInterface*>(part);
00136
KTextEditor::ViewCursorInterface *cursorIface
00137 = dynamic_cast<KTextEditor::ViewCursorInterface*>(part);
00138
00139
if (fileName.isNull() && rwpart)
00140 fileName = rwpart->
url().
path();
00141
00142
QString projectDirectory;
00143
if (
project())
00144 projectDirectory =
project()->
projectDirectory();
00145
00146
QString selection;
00147
if (selectionIface)
00148 selection = KShellProcess::quote(selectionIface->
selection());
00149
00150
QString word;
00151
if (editIface && cursorIface)
00152 word = KShellProcess::quote(
currentWord(editIface, cursorIface));
00153
00154
00155
if (cmdline.contains(
"%D") && projectDirectory.isNull())
00156
return;
00157 cmdline.replace(
QRegExp(
"%D"), projectDirectory);
00158
00159
if (cmdline.contains(
"%S") && fileName.isNull())
00160
return;
00161 cmdline.replace(
QRegExp(
"%S"), fileName);
00162
00163
if (cmdline.contains(
"%T") && selection.isNull())
00164
return;
00165 cmdline.replace(
QRegExp(
"%S"), selection);
00166
00167
if (cmdline.contains(
"%W") && word.isNull())
00168
return;
00169 cmdline.replace(
QRegExp(
"%W"), word);
00170
00171
if (captured)
00172
appFrontend()->
startAppCommand(QString::QString(), cmdline,
false);
00173
else {
00174
KShellProcess proc;
00175 proc << cmdline;
00176 proc.
start(KProcess::DontCare, KProcess::NoCommunication);
00177 }
00178 }
00179
00180
00181 void ToolsPart::updateToolsMenu()
00182 {
00183
KConfig *config = ToolsFactory::instance()->config();
00184 config->
setGroup(
"External Tools");
00185
QStringList l = config->
readListEntry(
"Tool Menu");
00186
00187
QPtrList<KAction> actions;
00188 QStringList::ConstIterator it;
00189
for (it = l.begin(); it != l.end(); ++it) {
00190
QString menutext = *it;
00191
KConfig *config = ToolsFactory::instance()->config();
00192 config->
setGroup(
"Tool Menu " + menutext);
00193
bool isdesktopfile = config->
readBoolEntry(
"DesktopFile");
00194
KAction *action =
new KAction(*it, 0,
00195
this, SLOT(
toolsMenuActivated()),
00196 (
QObject*) 0, menutext.utf8());
00197
if (isdesktopfile) {
00198
KDesktopFile df(config->
readPathEntry(
"CommandLine"));
00199 action->setIcon(df.
readIcon());
00200 }
00201 actions.append(action);
00202 }
00203
00204 unplugActionList(
"tools2_list");
00205 plugActionList(
"tools2_list", actions);
00206 }
00207
00208
00209 void ToolsPart::contextMenu(
QPopupMenu *popup,
const Context *context)
00210 {
00211
if (!context->
hasType( Context::FileContext ))
00212
return;
00213
00214
const FileContext *fcontext = static_cast<const FileContext*>(context);
00215
m_contextPopup = popup;
00216
m_contextFileName = fcontext->
fileName();
00217
00218
KConfig *config = ToolsFactory::instance()->config();
00219 config->
setGroup(
"External Tools");
00220
QStringList filecontextList = config->
readListEntry(
"File Context");
00221
00222
if (fcontext->
isDirectory()) {
00223
QStringList l = config->
readListEntry(
"Dir Context");
00224 QStringList::ConstIterator it;
00225
for (it = l.begin(); it != l.end(); ++it)
00226 popup->insertItem( (*it),
this, SLOT(
dirContextActivated(
int)) );
00227 }
else {
00228
QStringList l = config->
readListEntry(
"File Context");
00229 QStringList::ConstIterator it;
00230
for (it = l.begin(); it != l.end(); ++it)
00231 popup->insertItem( (*it),
this, SLOT(
fileContextActivated(
int)) );
00232 }
00233 }
00234
00235
00236 void ToolsPart::toolsMenuActivated()
00237 {
00238
QString menutext = QString::fromUtf8(sender()->name());
00239
KConfig *config = ToolsFactory::instance()->config();
00240 config->
setGroup(
"Tool Menu " + menutext);
00241
QString cmdline = config->
readPathEntry(
"CommandLine");
00242
bool isdesktopfile = config->
readBoolEntry(
"DesktopFile");
00243
bool captured = config->
readBoolEntry(
"Captured");
00244
kdDebug() <<
"activating " << menutext
00245 <<
"with cmdline " << cmdline
00246 <<
"and desktopfile " << isdesktopfile <<
endl;
00247
if (isdesktopfile)
00248 kapp->startServiceByDesktopPath(cmdline);
00249
else
00250
startCommand(cmdline, captured, QString::null);
00251 }
00252
00253
00254 void ToolsPart::fileContextActivated(
int id)
00255 {
00256
QString menutext =
m_contextPopup->text(
id);
00257
00258
KConfig *config = ToolsFactory::instance()->config();
00259 config->
setGroup(
"File Context " + menutext);
00260
QString cmdline = config->
readPathEntry(
"CommandLine");
00261
bool captured = config->
readBoolEntry(
"Captured");
00262
kdDebug() <<
"activating " << menutext
00263 <<
"with cmdline " << cmdline
00264 <<
" on file " <<
m_contextFileName <<
endl;
00265
startCommand(cmdline, captured,
m_contextFileName);
00266 }
00267
00268
00269 void ToolsPart::dirContextActivated(
int id)
00270 {
00271
QString menutext =
m_contextPopup->text(
id);
00272
00273
KConfig *config = ToolsFactory::instance()->config();
00274 config->
setGroup(
"Dir Context " + menutext);
00275
QString cmdline = config->
readPathEntry(
"CommandLine");
00276
bool captured = config->
readBoolEntry(
"Captured");
00277
kdDebug() <<
"activating " << menutext
00278 <<
"with cmdline " << cmdline
00279 <<
" on directory " <<
m_contextFileName <<
endl;
00280
startCommand(cmdline, captured,
m_contextFileName);
00281 }
00282
00283
#include "tools_part.moc"