447
447
static QLatin1String stringForOutputHandling(ExternalTool::OutputHandling handling)
449
449
switch (handling) {
450
case Core::Internal::ExternalTool::Ignore:
450
case ExternalTool::Ignore:
451
451
return QLatin1String(kOutputIgnore);
452
case Core::Internal::ExternalTool::ShowInPane:
452
case ExternalTool::ShowInPane:
453
453
return QLatin1String(kOutputShowInPane);
454
case Core::Internal::ExternalTool::ReplaceSelection:
454
case ExternalTool::ReplaceSelection:
455
455
return QLatin1String(kOutputReplaceSelection);
457
457
return QLatin1String("");
561
561
if (m_resolvedExecutable.isEmpty()) {
562
562
m_hasError = true;
563
563
for (int i = 0; i < expandedExecutables.size(); ++i) {
564
m_errorString += tr("Could not find executable for '%1' (expanded '%2')\n")
564
m_errorString += tr("Could not find executable for '%1' (expanded '%2')")
565
565
.arg(m_tool->executables().at(i))
566
566
.arg(expandedExecutables.at(i));
567
m_errorString += QLatin1Char('\n');
568
569
if (!m_errorString.isEmpty())
569
570
m_errorString.chop(1);
592
593
if (m_tool->modifiesCurrentDocument()) {
593
if (IEditor *editor = EditorManager::currentEditor()) {
594
m_expectedFileName = editor->document()->fileName();
594
if (IDocument *document = EditorManager::currentDocument()) {
595
m_expectedFileName = document->filePath();
595
596
bool cancelled = false;
596
DocumentManager::saveModifiedDocuments(QList<IDocument *>() << editor->document(), &cancelled);
597
DocumentManager::saveModifiedDocuments(QList<IDocument *>() << document, &cancelled);
625
626
void ExternalToolRunner::finished(int exitCode, QProcess::ExitStatus status)
627
if (status == QProcess::NormalExit && exitCode == 0) {
628
if (m_tool->outputHandling() == ExternalTool::ReplaceSelection
629
|| m_tool->errorHandling() == ExternalTool::ReplaceSelection) {
630
emit ExternalToolManager::instance()->replaceSelectionRequested(m_processOutput);
632
if (m_tool->modifiesCurrentDocument())
633
DocumentManager::unexpectFileChange(m_expectedFileName);
628
if (status == QProcess::NormalExit && exitCode == 0
629
&& (m_tool->outputHandling() == ExternalTool::ReplaceSelection
630
|| m_tool->errorHandling() == ExternalTool::ReplaceSelection)) {
631
ExternalToolManager::emitReplaceSelectionRequested(m_processOutput);
635
ICore::messageManager()->printToOutputPane(
633
if (m_tool->modifiesCurrentDocument())
634
DocumentManager::unexpectFileChange(m_expectedFileName);
635
MessageManager::write(
636
636
tr("'%1' finished").arg(m_resolvedExecutable), MessageManager::Silent);
653
653
QByteArray data = m_process->readAllStandardOutput();
654
654
QString output = m_outputCodec->toUnicode(data.constData(), data.length(), &m_outputCodecState);
655
655
if (m_tool->outputHandling() == ExternalTool::ShowInPane)
656
ICore::messageManager()->printToOutputPane(output, MessageManager::NoModeSwitch);
656
MessageManager::write(output);
657
657
else if (m_tool->outputHandling() == ExternalTool::ReplaceSelection)
658
658
m_processOutput.append(output);
665
665
QByteArray data = m_process->readAllStandardError();
666
666
QString output = m_outputCodec->toUnicode(data.constData(), data.length(), &m_errorCodecState);
667
667
if (m_tool->errorHandling() == ExternalTool::ShowInPane)
668
ICore::messageManager()->printToOutputPane(output, MessageManager::NoModeSwitch);
668
MessageManager::write(output);
669
669
else if (m_tool->errorHandling() == ExternalTool::ReplaceSelection)
670
670
m_processOutput.append(output);
673
// #pragma mark -- ExternalToolManager
675
ExternalToolManager *ExternalToolManager::m_instance = 0;
673
// ExternalToolManager
675
struct ExternalToolManagerPrivate
677
QMap<QString, ExternalTool *> m_tools;
678
QMap<QString, QList<ExternalTool *> > m_categoryMap;
679
QMap<QString, QAction *> m_actions;
680
QMap<QString, ActionContainer *> m_containers;
681
QAction *m_configureSeparator;
682
QAction *m_configureAction;
685
static ExternalToolManager *m_instance = 0;
686
static ExternalToolManagerPrivate *d = 0;
688
static void writeSettings();
689
static void readSettings(const QMap<QString, ExternalTool *> &tools,
690
QMap<QString, QList<ExternalTool*> > *categoryPriorityMap);
692
static void parseDirectory(const QString &directory,
693
QMap<QString, QMultiMap<int, ExternalTool*> > *categoryMenus,
694
QMap<QString, ExternalTool *> *tools,
695
bool isPreset = false);
677
697
ExternalToolManager::ExternalToolManager()
678
698
: QObject(ICore::instance())
680
700
m_instance = this;
684
ExternalToolManager::~ExternalToolManager()
687
// TODO kill running tools
691
void ExternalToolManager::initialize()
693
m_configureSeparator = new QAction(this);
694
m_configureSeparator->setSeparator(true);
695
m_configureAction = new QAction(tr("Configure..."), this);
696
connect(m_configureAction, SIGNAL(triggered()), this, SLOT(openPreferences()));
701
d = new ExternalToolManagerPrivate;
703
d->m_configureSeparator = new QAction(this);
704
d->m_configureSeparator->setSeparator(true);
705
d->m_configureAction = new QAction(tr("Configure..."), this);
706
connect(d->m_configureAction, SIGNAL(triggered()), this, SLOT(openPreferences()));
698
708
// add the external tools menu
699
709
ActionContainer *mexternaltools = ActionManager::createMenu(Id(Constants::M_TOOLS_EXTERNAL));
700
mexternaltools->menu()->setTitle(tr("&External"));
710
mexternaltools->menu()->setTitle(ExternalToolManager::tr("&External"));
701
711
ActionContainer *mtools = ActionManager::actionContainer(Constants::M_TOOLS);
702
712
mtools->addMenu(mexternaltools, Constants::G_DEFAULT_THREE);
723
733
setToolsByCategory(categoryMap);
726
void ExternalToolManager::parseDirectory(const QString &directory,
727
QMap<QString, QMultiMap<int, Internal::ExternalTool*> > *categoryMenus,
728
QMap<QString, ExternalTool *> *tools,
736
ExternalToolManager::~ExternalToolManager()
739
// TODO kill running tools
740
qDeleteAll(d->m_tools);
744
QObject *ExternalToolManager::instance()
749
static void parseDirectory(const QString &directory,
750
QMap<QString, QMultiMap<int, ExternalTool*> > *categoryMenus,
751
QMap<QString, ExternalTool *> *tools,
731
754
QTC_ASSERT(categoryMenus, return);
732
755
QTC_ASSERT(tools, return);
764
787
QAction *action = qobject_cast<QAction *>(sender());
765
788
QTC_ASSERT(action, return);
766
ExternalTool *tool = m_tools.value(action->data().toString());
789
ExternalTool *tool = d->m_tools.value(action->data().toString());
767
790
QTC_ASSERT(tool, return);
768
791
ExternalToolRunner *runner = new ExternalToolRunner(tool);
769
792
if (runner->hasError())
770
ICore::messageManager()->printToOutputPane(runner->errorString(), MessageManager::NoModeSwitch);
773
QMap<QString, QList<Internal::ExternalTool *> > ExternalToolManager::toolsByCategory() const
775
return m_categoryMap;
778
QMap<QString, ExternalTool *> ExternalToolManager::toolsById() const
783
void ExternalToolManager::setToolsByCategory(const QMap<QString, QList<Internal::ExternalTool *> > &tools)
793
MessageManager::write(runner->errorString());
796
QMap<QString, QList<ExternalTool *> > ExternalToolManager::toolsByCategory()
798
return d->m_categoryMap;
801
QMap<QString, ExternalTool *> ExternalToolManager::toolsById()
806
void ExternalToolManager::setToolsByCategory(const QMap<QString, QList<ExternalTool *> > &tools)
786
809
ActionContainer *mexternaltools = ActionManager::actionContainer(Id(Constants::M_TOOLS_EXTERNAL));
793
816
while (it.hasNext()) {
795
818
foreach (ExternalTool *tool, it.value()) {
796
const QString &id = tool->id();
797
if (m_tools.value(id) == tool) {
798
newActions.insert(id, m_actions.value(id));
819
const QString id = tool->id();
820
if (d->m_tools.value(id) == tool) {
821
newActions.insert(id, d->m_actions.value(id));
799
822
// remove from list to prevent deletion
801
m_actions.remove(id);
823
d->m_tools.remove(id);
824
d->m_actions.remove(id);
803
826
newTools.insert(id, tool);
807
QMapIterator<QString, QAction *> remainingActions(m_actions);
808
const Id externalToolsPrefix = Id("Tools.External.");
829
qDeleteAll(d->m_tools);
830
QMapIterator<QString, QAction *> remainingActions(d->m_actions);
831
const Id externalToolsPrefix = "Tools.External.";
809
832
while (remainingActions.hasNext()) {
810
833
remainingActions.next();
811
834
ActionManager::unregisterAction(remainingActions.value(),
812
835
externalToolsPrefix.withSuffix(remainingActions.key()));
813
836
delete remainingActions.value();
838
d->m_actions.clear();
816
839
// assign the new stuff
818
m_actions = newActions;
819
m_categoryMap = tools;
840
d->m_tools = newTools;
841
d->m_actions = newActions;
842
d->m_categoryMap = tools;
820
843
// create menu structure and remove no-longer used containers
821
844
// add all the category menus, QMap is nicely sorted
822
845
QMap<QString, ActionContainer *> newContainers;
828
851
if (containerName.isEmpty()) { // no displayCategory, so put into external tools menu directly
829
852
container = mexternaltools;
831
if (m_containers.contains(containerName))
832
container = m_containers.take(containerName); // remove to avoid deletion below
854
if (d->m_containers.contains(containerName))
855
container = d->m_containers.take(containerName); // remove to avoid deletion below
834
857
container = ActionManager::createMenu(Id("Tools.External.Category.").withSuffix(containerName));
835
858
newContainers.insert(containerName, container);
841
864
// tool action and command
842
865
QAction *action = 0;
843
866
Command *command = 0;
844
if (m_actions.contains(toolId)) {
845
action = m_actions.value(toolId);
867
if (d->m_actions.contains(toolId)) {
868
action = d->m_actions.value(toolId);
846
869
command = ActionManager::command(externalToolsPrefix.withSuffix(toolId));
848
action = new QAction(tool->displayName(), this);
871
action = new QAction(tool->displayName(), m_instance);
849
872
action->setData(toolId);
850
m_actions.insert(toolId, action);
851
connect(action, SIGNAL(triggered()), this, SLOT(menuActivated()));
873
d->m_actions.insert(toolId, action);
874
connect(action, SIGNAL(triggered()), m_instance, SLOT(menuActivated()));
852
875
command = ActionManager::registerAction(action, externalToolsPrefix.withSuffix(toolId), Context(Constants::C_GLOBAL));
853
876
command->setAttribute(Command::CA_UpdateText);
862
885
// delete the unused containers
863
qDeleteAll(m_containers);
886
qDeleteAll(d->m_containers);
864
887
// remember the new containers
865
m_containers = newContainers;
888
d->m_containers = newContainers;
867
890
// (re)add the configure menu item
868
mexternaltools->menu()->addAction(m_configureSeparator);
869
mexternaltools->menu()->addAction(m_configureAction);
891
mexternaltools->menu()->addAction(d->m_configureSeparator);
892
mexternaltools->menu()->addAction(d->m_configureAction);
872
void ExternalToolManager::readSettings(const QMap<QString, ExternalTool *> &tools,
895
static void readSettings(const QMap<QString, ExternalTool *> &tools,
873
896
QMap<QString, QList<ExternalTool *> > *categoryMap)
875
898
QSettings *settings = ICore::settings();
903
926
settings->endGroup();
906
void ExternalToolManager::writeSettings()
929
static void writeSettings()
908
931
QSettings *settings = ICore::settings();
909
932
settings->beginGroup(QLatin1String("ExternalTools"));
910
933
settings->remove(QLatin1String(""));
912
935
settings->beginGroup(QLatin1String("OverrideCategories"));
913
QMapIterator<QString, QList<ExternalTool *> > it(m_categoryMap);
936
QMapIterator<QString, QList<ExternalTool *> > it(d->m_categoryMap);
914
937
while (it.hasNext()) {
916
939
QString category = it.key();