forked from qt-creator/qt-creator
Implement renaming of tools and categories.
Not possible to reset them yet. Saves the change in the settings instead of writing new tools xml files. This probably needs to be adapted for tools that are "local" from the beginning.
This commit is contained in:
@@ -268,10 +268,32 @@ void ActionContainerPrivate::addMenu(ActionContainer *menu, const QString &group
|
||||
QAction *beforeAction = insertLocation(groupIt);
|
||||
m_groups[groupIt-m_groups.constBegin()].items.append(menu);
|
||||
|
||||
connect(menu, SIGNAL(destroyed()), this, SLOT(itemDestroyed()));
|
||||
insertMenu(beforeAction, container->menu());
|
||||
scheduleUpdate();
|
||||
}
|
||||
|
||||
void ActionContainerPrivate::clear()
|
||||
{
|
||||
QMutableListIterator<Group> it(m_groups);
|
||||
while (it.hasNext()) {
|
||||
Group &group = it.next();
|
||||
foreach (QObject *item, group.items) {
|
||||
if (Command *command = qobject_cast<Command *>(item)) {
|
||||
removeAction(command->action());
|
||||
disconnect(command, SIGNAL(activeStateChanged()), this, SLOT(scheduleUpdate()));
|
||||
disconnect(command, SIGNAL(destroyed()), this, SLOT(itemDestroyed()));
|
||||
} else if (ActionContainer *container = qobject_cast<ActionContainer *>(item)) {
|
||||
container->clear();
|
||||
disconnect(container, SIGNAL(destroyed()), this, SLOT(itemDestroyed()));
|
||||
removeMenu(container->menu());
|
||||
}
|
||||
}
|
||||
group.items.clear();
|
||||
}
|
||||
scheduleUpdate();
|
||||
}
|
||||
|
||||
void ActionContainerPrivate::itemDestroyed()
|
||||
{
|
||||
QObject *obj = sender();
|
||||
@@ -350,6 +372,16 @@ void MenuActionContainer::insertMenu(QAction *before, QMenu *menu)
|
||||
m_menu->insertMenu(before, menu);
|
||||
}
|
||||
|
||||
void MenuActionContainer::removeAction(QAction *action)
|
||||
{
|
||||
m_menu->removeAction(action);
|
||||
}
|
||||
|
||||
void MenuActionContainer::removeMenu(QMenu *menu)
|
||||
{
|
||||
m_menu->removeAction(menu->menuAction());
|
||||
}
|
||||
|
||||
bool MenuActionContainer::updateInternal()
|
||||
{
|
||||
if (onAllDisabledBehavior() == Show)
|
||||
@@ -442,6 +474,16 @@ void MenuBarActionContainer::insertMenu(QAction *before, QMenu *menu)
|
||||
m_menuBar->insertMenu(before, menu);
|
||||
}
|
||||
|
||||
void MenuBarActionContainer::removeAction(QAction *action)
|
||||
{
|
||||
m_menuBar->removeAction(action);
|
||||
}
|
||||
|
||||
void MenuBarActionContainer::removeMenu(QMenu *menu)
|
||||
{
|
||||
m_menuBar->removeAction(menu->menuAction());
|
||||
}
|
||||
|
||||
bool MenuBarActionContainer::updateInternal()
|
||||
{
|
||||
if (onAllDisabledBehavior() == Show)
|
||||
|
||||
@@ -70,6 +70,9 @@ public:
|
||||
virtual void addAction(Core::Command *action, const QString &group = QString()) = 0;
|
||||
virtual void addMenu(Core::ActionContainer *menu, const QString &group = QString()) = 0;
|
||||
|
||||
// clears this menu and submenus from all actions and submenus
|
||||
// doesn't destroy the submenus and commands, just removes them from their parents
|
||||
virtual void clear() = 0;
|
||||
virtual ~ActionContainer() {}
|
||||
};
|
||||
|
||||
|
||||
@@ -63,6 +63,7 @@ public:
|
||||
void appendGroup(const QString &id);
|
||||
void addAction(Command *action, const QString &group = QString());
|
||||
void addMenu(ActionContainer *menu, const QString &group = QString());
|
||||
virtual void clear();
|
||||
|
||||
int id() const;
|
||||
|
||||
@@ -72,6 +73,9 @@ public:
|
||||
virtual void insertAction(QAction *before, QAction *action) = 0;
|
||||
virtual void insertMenu(QAction *before, QMenu *menu) = 0;
|
||||
|
||||
virtual void removeAction(QAction *action) = 0;
|
||||
virtual void removeMenu(QMenu *menu) = 0;
|
||||
|
||||
virtual bool updateInternal() = 0;
|
||||
|
||||
protected:
|
||||
@@ -107,6 +111,9 @@ public:
|
||||
void insertAction(QAction *before, QAction *action);
|
||||
void insertMenu(QAction *before, QMenu *menu);
|
||||
|
||||
void removeAction(QAction *action);
|
||||
void removeMenu(QMenu *menu);
|
||||
|
||||
protected:
|
||||
bool canBeAddedToMenu() const;
|
||||
bool updateInternal();
|
||||
@@ -126,6 +133,9 @@ public:
|
||||
void insertAction(QAction *before, QAction *action);
|
||||
void insertMenu(QAction *before, QMenu *menu);
|
||||
|
||||
void removeAction(QAction *action);
|
||||
void removeMenu(QMenu *menu);
|
||||
|
||||
protected:
|
||||
bool canBeAddedToMenu() const;
|
||||
bool updateInternal();
|
||||
|
||||
@@ -248,6 +248,8 @@ ActionManagerPrivate::ActionManagerPrivate(MainWindow *mainWnd)
|
||||
ActionManagerPrivate::~ActionManagerPrivate()
|
||||
{
|
||||
// first delete containers to avoid them reacting to command deletion
|
||||
foreach (ActionContainerPrivate *container, m_idContainerMap)
|
||||
disconnect(container, SIGNAL(destroyed()), this, SLOT(containerDestroyed()));
|
||||
qDeleteAll(m_idContainerMap.values());
|
||||
qDeleteAll(m_idCmdMap.values());
|
||||
}
|
||||
@@ -314,6 +316,7 @@ ActionContainer *ActionManagerPrivate::createMenu(const Id &id)
|
||||
mc->setMenu(m);
|
||||
|
||||
m_idContainerMap.insert(uid, mc);
|
||||
connect(mc, SIGNAL(destroyed()), this, SLOT(containerDestroyed()));
|
||||
|
||||
return mc;
|
||||
}
|
||||
@@ -332,10 +335,17 @@ ActionContainer *ActionManagerPrivate::createMenuBar(const Id &id)
|
||||
mbc->setMenuBar(mb);
|
||||
|
||||
m_idContainerMap.insert(uid, mbc);
|
||||
connect(mbc, SIGNAL(destroyed()), this, SLOT(containerDestroyed()));
|
||||
|
||||
return mbc;
|
||||
}
|
||||
|
||||
void ActionManagerPrivate::containerDestroyed()
|
||||
{
|
||||
ActionContainerPrivate *container = static_cast<ActionContainerPrivate *>(sender());
|
||||
m_idContainerMap.remove(m_idContainerMap.key(container));
|
||||
}
|
||||
|
||||
Command *ActionManagerPrivate::registerAction(QAction *action, const Id &id, const Context &context, bool scriptable)
|
||||
{
|
||||
Action *a = overridableAction(id);
|
||||
|
||||
@@ -93,6 +93,8 @@ public:
|
||||
void unregisterAction(QAction *action, const Id &id);
|
||||
void unregisterShortcut(const Id &id);
|
||||
|
||||
private slots:
|
||||
void containerDestroyed();
|
||||
private:
|
||||
bool hasContext(const Context &context) const;
|
||||
Action *overridableAction(const Id &id);
|
||||
|
||||
@@ -34,6 +34,8 @@
|
||||
#include "externaltoolconfig.h"
|
||||
#include "ui_externaltoolconfig.h"
|
||||
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
#include <QtCore/QTextStream>
|
||||
|
||||
using namespace Core::Internal;
|
||||
@@ -43,13 +45,21 @@ ExternalToolConfig::ExternalToolConfig(QWidget *parent) :
|
||||
ui(new Ui::ExternalToolConfig)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->toolTree->setEditTriggers(QAbstractItemView::DoubleClicked | QAbstractItemView::EditKeyPressed);
|
||||
connect(ui->toolTree, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)),
|
||||
this, SLOT(showInfoForItem(QTreeWidgetItem*)));
|
||||
connect(ui->toolTree, SIGNAL(itemChanged(QTreeWidgetItem*,int)),
|
||||
this, SLOT(updateItem(QTreeWidgetItem *)));
|
||||
showInfoForItem(0);
|
||||
}
|
||||
|
||||
ExternalToolConfig::~ExternalToolConfig()
|
||||
{
|
||||
QMapIterator<QString, QList<ExternalTool *> > it(m_tools);
|
||||
while (it.hasNext()) {
|
||||
it.next();
|
||||
qDeleteAll(it.value());
|
||||
}
|
||||
delete ui;
|
||||
}
|
||||
|
||||
@@ -69,19 +79,32 @@ QString ExternalToolConfig::searchKeywords() const
|
||||
|
||||
void ExternalToolConfig::setTools(const QMap<QString, QList<ExternalTool *> > &tools)
|
||||
{
|
||||
// TODO make copy of tools
|
||||
QMapIterator<QString, QList<ExternalTool *> > it(tools);
|
||||
while (it.hasNext()) {
|
||||
it.next();
|
||||
QList<ExternalTool *> itemCopy;
|
||||
foreach (ExternalTool *tool, it.value())
|
||||
itemCopy.append(new ExternalTool(tool));
|
||||
m_tools.insert(it.key(), itemCopy);
|
||||
}
|
||||
|
||||
QMapIterator<QString, QList<ExternalTool *> > categories(tools);
|
||||
bool blocked = ui->toolTree->blockSignals(true); // block itemChanged
|
||||
Qt::ItemFlags flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | Qt::ItemIsEditable;
|
||||
QMapIterator<QString, QList<ExternalTool *> > categories(m_tools);
|
||||
while (categories.hasNext()) {
|
||||
categories.next();
|
||||
QString name = (categories.key().isEmpty() ? tr("External Tools Menu") : categories.key());
|
||||
QTreeWidgetItem *category = new QTreeWidgetItem(ui->toolTree, QStringList() << name);
|
||||
category->setFlags(flags);
|
||||
category->setData(0, Qt::UserRole, name); // save the name in case of category being renamed by user
|
||||
foreach (ExternalTool *tool, categories.value()) {
|
||||
QTreeWidgetItem *item = new QTreeWidgetItem(category, QStringList() << tool->displayName());
|
||||
item->setFlags(flags);
|
||||
item->setData(0, Qt::UserRole, qVariantFromValue(tool));
|
||||
}
|
||||
}
|
||||
ui->toolTree->expandAll();
|
||||
ui->toolTree->blockSignals(blocked); // unblock itemChanged
|
||||
}
|
||||
|
||||
void ExternalToolConfig::showInfoForItem(QTreeWidgetItem *item)
|
||||
@@ -110,3 +133,51 @@ void ExternalToolConfig::showInfoForItem(QTreeWidgetItem *item)
|
||||
ui->description->setCursorPosition(0);
|
||||
ui->arguments->setCursorPosition(0);
|
||||
}
|
||||
|
||||
void ExternalToolConfig::updateItem(QTreeWidgetItem *item)
|
||||
{
|
||||
ExternalTool *tool = 0;
|
||||
if (item)
|
||||
tool = item->data(0, Qt::UserRole).value<ExternalTool *>();
|
||||
if (tool) {
|
||||
// tool was renamed
|
||||
const QString &newName = item->data(0, Qt::DisplayRole).toString();
|
||||
if (newName == tool->displayName())
|
||||
return;
|
||||
if (newName.isEmpty()) {
|
||||
// prevent empty names
|
||||
bool blocked = ui->toolTree->blockSignals(true); // block itemChanged
|
||||
item->setData(0, Qt::DisplayRole, tool->displayName());
|
||||
ui->toolTree->blockSignals(blocked); // unblock itemChanged
|
||||
return;
|
||||
}
|
||||
tool->setDisplayName(item->data(0, Qt::DisplayRole).toString());
|
||||
} else {
|
||||
// category was renamed
|
||||
const QString &oldName = item->data(0, Qt::UserRole).toString();
|
||||
const QString &newName = item->data(0, Qt::DisplayRole).toString();
|
||||
if (oldName == newName)
|
||||
return;
|
||||
if (newName.isEmpty() && m_tools.contains(newName)) {
|
||||
// prevent empty or duplicate names
|
||||
bool blocked = ui->toolTree->blockSignals(true); // block itemChanged
|
||||
item->setData(0, Qt::DisplayRole, oldName);
|
||||
ui->toolTree->blockSignals(blocked); // unblock itemChanged
|
||||
return;
|
||||
}
|
||||
QTC_ASSERT(m_tools.contains(oldName), return);
|
||||
m_tools.insert(newName, m_tools.value(oldName));
|
||||
m_tools.remove(oldName);
|
||||
|
||||
bool blocked = ui->toolTree->blockSignals(true); // block itemChanged
|
||||
item->setData(0, Qt::UserRole, newName);
|
||||
int currentIndex = ui->toolTree->indexOfTopLevelItem(item);
|
||||
bool wasExpanded = ui->toolTree->isExpanded(ui->toolTree->model()->index(currentIndex, 0));
|
||||
ui->toolTree->takeTopLevelItem(currentIndex);
|
||||
int newIndex = m_tools.keys().indexOf(newName);
|
||||
ui->toolTree->insertTopLevelItem(newIndex, item);
|
||||
if (wasExpanded)
|
||||
ui->toolTree->expand(ui->toolTree->model()->index(newIndex, 0));
|
||||
ui->toolTree->blockSignals(blocked); // unblock itemChanged
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,14 +55,17 @@ public:
|
||||
~ExternalToolConfig();
|
||||
|
||||
void setTools(const QMap<QString, QList<ExternalTool *> > &tools);
|
||||
QMap<QString, QList<ExternalTool *> > tools() const { return m_tools; }
|
||||
|
||||
QString searchKeywords() const;
|
||||
|
||||
private slots:
|
||||
void showInfoForItem(QTreeWidgetItem *item);
|
||||
void updateItem(QTreeWidgetItem *item);
|
||||
|
||||
private:
|
||||
Ui::ExternalToolConfig *ui;
|
||||
QMap<QString, QList<ExternalTool *> > m_tools;
|
||||
};
|
||||
|
||||
} // Internal
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
|
||||
#include "externaltool.h"
|
||||
#include "actionmanager/actionmanager.h"
|
||||
#include "actionmanager/actioncontainer.h"
|
||||
#include "coreconstants.h"
|
||||
#include "variablemanager.h"
|
||||
|
||||
@@ -80,7 +79,8 @@ namespace {
|
||||
ExternalTool::ExternalTool() :
|
||||
m_order(-1),
|
||||
m_outputHandling(ShowInPane),
|
||||
m_errorHandling(ShowInPane)
|
||||
m_errorHandling(ShowInPane),
|
||||
m_isDisplayNameChanged(false)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -95,7 +95,8 @@ ExternalTool::ExternalTool(const ExternalTool *other)
|
||||
m_input(other->m_input),
|
||||
m_workingDirectory(other->m_workingDirectory),
|
||||
m_outputHandling(other->m_outputHandling),
|
||||
m_errorHandling(other->m_errorHandling)
|
||||
m_errorHandling(other->m_errorHandling),
|
||||
m_isDisplayNameChanged(other->m_isDisplayNameChanged)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -118,6 +119,14 @@ QString ExternalTool::displayName() const
|
||||
return m_displayName;
|
||||
}
|
||||
|
||||
void ExternalTool::setDisplayName(const QString &name)
|
||||
{
|
||||
if (name == m_displayName)
|
||||
return;
|
||||
m_isDisplayNameChanged = true;
|
||||
m_displayName = name;
|
||||
}
|
||||
|
||||
QString ExternalTool::displayCategory() const
|
||||
{
|
||||
return m_displayCategory;
|
||||
@@ -298,16 +307,37 @@ ExternalTool * ExternalTool::createFromXml(const QByteArray &xml, QString *error
|
||||
return tool;
|
||||
}
|
||||
|
||||
bool ExternalTool::operator==(const ExternalTool &other)
|
||||
{
|
||||
return m_id == other.m_id
|
||||
&& m_description == other.m_description
|
||||
&& m_displayName == other.m_displayName
|
||||
&& m_displayCategory == other.m_displayCategory
|
||||
&& m_order == other.m_order
|
||||
&& m_executables == other.m_executables
|
||||
&& m_arguments == other.m_arguments
|
||||
&& m_input == other.m_input
|
||||
&& m_workingDirectory == other.m_workingDirectory
|
||||
&& m_outputHandling == other.m_outputHandling
|
||||
&& m_errorHandling == other.m_errorHandling;
|
||||
}
|
||||
|
||||
// #pragma mark -- ExternalToolRunner
|
||||
|
||||
ExternalToolRunner::ExternalToolRunner(const ExternalTool *tool)
|
||||
: m_tool(tool),
|
||||
: m_tool(new ExternalTool(tool)),
|
||||
m_process(0),
|
||||
m_outputCodec(QTextCodec::codecForLocale())
|
||||
{
|
||||
run();
|
||||
}
|
||||
|
||||
ExternalToolRunner::~ExternalToolRunner()
|
||||
{
|
||||
if (m_tool)
|
||||
delete m_tool;
|
||||
}
|
||||
|
||||
bool ExternalToolRunner::resolve()
|
||||
{
|
||||
if (!m_tool)
|
||||
@@ -450,60 +480,50 @@ ExternalToolManager::ExternalToolManager(Core::ICore *core)
|
||||
|
||||
ExternalToolManager::~ExternalToolManager()
|
||||
{
|
||||
writeSettings();
|
||||
// TODO kill running tools
|
||||
qDeleteAll(m_tools);
|
||||
}
|
||||
|
||||
void ExternalToolManager::initialize()
|
||||
{
|
||||
// add the external tools menu
|
||||
ActionManager *am = m_core->actionManager();
|
||||
ActionContainer *mexternaltools = am->createMenu(Id(Constants::M_TOOLS_EXTERNAL));
|
||||
mexternaltools->menu()->setTitle(tr("External"));
|
||||
ActionContainer *mtools = am->actionContainer(Constants::M_TOOLS);
|
||||
|
||||
mtools->addMenu(mexternaltools, Constants::G_DEFAULT_THREE);
|
||||
|
||||
QMap<QString, QMultiMap<int, ExternalTool*> > categoryMap;
|
||||
QMap<QString, QMultiMap<int, ExternalTool*> > categoryPriorityMap;
|
||||
QMap<QString, ExternalTool *> tools;
|
||||
parseDirectory(m_core->userResourcePath() + QLatin1String("/externaltools"),
|
||||
&categoryMap);
|
||||
&categoryPriorityMap,
|
||||
&tools);
|
||||
parseDirectory(m_core->resourcePath() + QLatin1String("/externaltools"),
|
||||
&categoryMap, true);
|
||||
&categoryPriorityMap,
|
||||
&tools,
|
||||
true);
|
||||
|
||||
QMapIterator<QString, QMultiMap<int, ExternalTool*> > it(categoryMap);
|
||||
// adapt overridden names and categories etc
|
||||
readSettings(tools, &categoryPriorityMap);
|
||||
|
||||
QMap<QString, QList<Internal::ExternalTool *> > categoryMap;
|
||||
QMapIterator<QString, QMultiMap<int, ExternalTool*> > it(categoryPriorityMap);
|
||||
while (it.hasNext()) {
|
||||
it.next();
|
||||
m_categoryMap.insert(it.key(), it.value().values());
|
||||
categoryMap.insert(it.key(), it.value().values());
|
||||
}
|
||||
|
||||
// add all the category menus, QMap is nicely sorted
|
||||
it.toFront();
|
||||
while (it.hasNext()) {
|
||||
it.next();
|
||||
ActionContainer *container = 0;
|
||||
if (it.key() == QString()) { // no displayCategory, so put into external tools menu directly
|
||||
container = mexternaltools;
|
||||
} else {
|
||||
container = am->createMenu(Id("Tools.External.Category." + it.key()));
|
||||
mexternaltools->addMenu(container, Constants::G_DEFAULT_ONE);
|
||||
container->menu()->setTitle(it.key());
|
||||
}
|
||||
foreach (ExternalTool *tool, it.value().values()) {
|
||||
// tool action and command
|
||||
QAction *action = new QAction(tool->displayName(), this);
|
||||
action->setToolTip(tool->description());
|
||||
action->setWhatsThis(tool->description());
|
||||
action->setData(tool->id());
|
||||
Command *cmd = am->registerAction(action, Id("Tools.External." + tool->id()), Context(Constants::C_GLOBAL));
|
||||
connect(action, SIGNAL(triggered()), this, SLOT(menuActivated()));
|
||||
container->addAction(cmd, Constants::G_DEFAULT_TWO);
|
||||
}
|
||||
}
|
||||
setToolsByCategory(categoryMap);
|
||||
}
|
||||
|
||||
void ExternalToolManager::parseDirectory(const QString &directory, QMap<QString, QMultiMap<int, ExternalTool*> > *categoryMenus,
|
||||
void ExternalToolManager::parseDirectory(const QString &directory,
|
||||
QMap<QString, QMultiMap<int, Internal::ExternalTool*> > *categoryMenus,
|
||||
QMap<QString, ExternalTool *> *tools,
|
||||
bool ignoreDuplicates)
|
||||
{
|
||||
QTC_ASSERT(categoryMenus, return);
|
||||
QTC_ASSERT(tools, return);
|
||||
QDir dir(directory, QLatin1String("*.xml"), QDir::Unsorted, QDir::Files | QDir::Readable);
|
||||
foreach (const QFileInfo &info, dir.entryInfoList()) {
|
||||
QFile file(info.absoluteFilePath());
|
||||
@@ -517,14 +537,14 @@ void ExternalToolManager::parseDirectory(const QString &directory, QMap<QString,
|
||||
qDebug() << tr("Error while parsing external tool %1: %2").arg(file.fileName(), error);
|
||||
continue;
|
||||
}
|
||||
if (m_tools.contains(tool->id())) {
|
||||
if (tools->contains(tool->id())) {
|
||||
// TODO error handling
|
||||
if (!ignoreDuplicates)
|
||||
qDebug() << tr("Error: External tool in %1 has duplicate id").arg(file.fileName());
|
||||
delete tool;
|
||||
continue;
|
||||
}
|
||||
m_tools.insert(tool->id(), tool);
|
||||
tools->insert(tool->id(), tool);
|
||||
(*categoryMenus)[tool->displayCategory()].insert(tool->order(), tool);
|
||||
}
|
||||
}
|
||||
@@ -539,8 +559,162 @@ void ExternalToolManager::menuActivated()
|
||||
new ExternalToolRunner(tool);
|
||||
}
|
||||
|
||||
QMap<QString, QList<Internal::ExternalTool *> > ExternalToolManager::tools() const
|
||||
QMap<QString, QList<Internal::ExternalTool *> > ExternalToolManager::toolsByCategory() const
|
||||
{
|
||||
return m_categoryMap;
|
||||
}
|
||||
|
||||
QMap<QString, ExternalTool *> ExternalToolManager::toolsById() const
|
||||
{
|
||||
return m_tools;
|
||||
}
|
||||
|
||||
void ExternalToolManager::setToolsByCategory(const QMap<QString, QList<Internal::ExternalTool *> > &tools)
|
||||
{
|
||||
// clear menu
|
||||
ActionManager *am = m_core->actionManager();
|
||||
ActionContainer *mexternaltools = am->actionContainer(Id(Constants::M_TOOLS_EXTERNAL));
|
||||
mexternaltools->clear();
|
||||
|
||||
// delete old tools and create list of new ones
|
||||
QMap<QString, ExternalTool *> newTools;
|
||||
QMap<QString, QAction *> newActions;
|
||||
QMapIterator<QString, QList<ExternalTool *> > it(tools);
|
||||
while (it.hasNext()) {
|
||||
it.next();
|
||||
foreach (ExternalTool *tool, it.value()) {
|
||||
const QString &id = tool->id();
|
||||
if (m_tools.value(id) == tool) {
|
||||
newActions.insert(id, m_actions.value(id));
|
||||
// remove from list to prevent deletion
|
||||
m_tools.remove(id);
|
||||
m_actions.remove(id);
|
||||
}
|
||||
newTools.insert(id, tool);
|
||||
}
|
||||
}
|
||||
qDeleteAll(m_tools);
|
||||
QMapIterator<QString, QAction *> remainingActions(m_actions);
|
||||
while (remainingActions.hasNext()) {
|
||||
remainingActions.next();
|
||||
am->unregisterAction(remainingActions.value(), Id("Tools.External." + remainingActions.key()));
|
||||
delete remainingActions.value();
|
||||
}
|
||||
m_actions.clear();
|
||||
// assign the new stuff
|
||||
m_tools = newTools;
|
||||
m_actions = newActions;
|
||||
m_categoryMap = tools;
|
||||
// create menu structure and remove no-longer used containers
|
||||
// add all the category menus, QMap is nicely sorted
|
||||
QMap<QString, ActionContainer *> newContainers;
|
||||
it.toFront();
|
||||
while (it.hasNext()) {
|
||||
it.next();
|
||||
ActionContainer *container = 0;
|
||||
const QString &containerName = it.key();
|
||||
if (containerName == QString()) { // no displayCategory, so put into external tools menu directly
|
||||
container = mexternaltools;
|
||||
} else {
|
||||
if (m_containers.contains(containerName)) {
|
||||
container = m_containers.take(containerName); // remove to avoid deletion below
|
||||
} else {
|
||||
container = am->createMenu(Id("Tools.External.Category." + containerName));
|
||||
}
|
||||
newContainers.insert(containerName, container);
|
||||
mexternaltools->addMenu(container, Constants::G_DEFAULT_ONE);
|
||||
container->menu()->setTitle(containerName);
|
||||
}
|
||||
foreach (ExternalTool *tool, it.value()) {
|
||||
const QString &toolId = tool->id();
|
||||
// tool action and command
|
||||
QAction *action = 0;
|
||||
Command *command = 0;
|
||||
if (m_actions.contains(toolId)) {
|
||||
action = m_actions.value(toolId);
|
||||
command = am->command(Id("Tools.External." + toolId));
|
||||
} else {
|
||||
action = new QAction(tool->displayName(), this);
|
||||
action->setData(toolId);
|
||||
m_actions.insert(toolId, action);
|
||||
connect(action, SIGNAL(triggered()), this, SLOT(menuActivated()));
|
||||
command = am->registerAction(action, Id("Tools.External." + toolId), Context(Constants::C_GLOBAL));
|
||||
command->setAttribute(Command::CA_UpdateText);
|
||||
}
|
||||
action->setText(tool->displayName());
|
||||
action->setToolTip(tool->description());
|
||||
action->setWhatsThis(tool->description());
|
||||
container->addAction(command, Constants::G_DEFAULT_TWO);
|
||||
}
|
||||
}
|
||||
|
||||
// delete the unused containers
|
||||
qDeleteAll(m_containers);
|
||||
// remember the new containers
|
||||
m_containers = newContainers;
|
||||
}
|
||||
|
||||
void ExternalToolManager::readSettings(const QMap<QString, ExternalTool *> &tools,
|
||||
QMap<QString, QMultiMap<int, Internal::ExternalTool*> > *categoryPriorityMap)
|
||||
{
|
||||
QSettings *settings = m_core->settings();
|
||||
settings->beginGroup(QLatin1String("ExternalTools"));
|
||||
|
||||
settings->beginGroup(QLatin1String("OverrideDisplayNames"));
|
||||
foreach (const QString &id, settings->allKeys()) {
|
||||
if (tools.contains(id)) {
|
||||
const QString &newName = settings->value(id).toString();
|
||||
if (tools.value(id)->displayName() != newName)
|
||||
tools.value(id)->setDisplayName(newName);
|
||||
}
|
||||
}
|
||||
settings->endGroup();
|
||||
|
||||
if (categoryPriorityMap) {
|
||||
settings->beginGroup(QLatin1String("OverrideCategories"));
|
||||
foreach (const QString &id, settings->allKeys()) {
|
||||
if (tools.contains(id)) {
|
||||
const QString &newCategory = settings->value(id).toString();
|
||||
ExternalTool *tool = tools.value(id);
|
||||
if (tool->displayCategory() != newCategory) {
|
||||
(*categoryPriorityMap)[tool->displayCategory()].remove(tool->order(), tool);
|
||||
(*categoryPriorityMap)[newCategory].insert(tool->order(), tool);
|
||||
if (categoryPriorityMap->value(tool->displayCategory()).isEmpty())
|
||||
categoryPriorityMap->remove(tool->displayCategory());
|
||||
}
|
||||
}
|
||||
}
|
||||
settings->endGroup();
|
||||
}
|
||||
|
||||
settings->endGroup();
|
||||
}
|
||||
|
||||
void ExternalToolManager::writeSettings()
|
||||
{
|
||||
QSettings *settings = m_core->settings();
|
||||
settings->beginGroup(QLatin1String("ExternalTools"));
|
||||
settings->remove(QLatin1String(""));
|
||||
|
||||
settings->beginGroup(QLatin1String("OverrideDisplayNames"));
|
||||
foreach (ExternalTool *tool, m_tools) {
|
||||
if (tool->isDisplayNameChanged()) {
|
||||
settings->setValue(tool->id(), tool->displayName());
|
||||
}
|
||||
}
|
||||
settings->endGroup();
|
||||
|
||||
settings->beginGroup(QLatin1String("OverrideCategories"));
|
||||
QMapIterator<QString, QList<ExternalTool *> > it(m_categoryMap);
|
||||
while (it.hasNext()) {
|
||||
it.next();
|
||||
const QString &category = it.key();
|
||||
foreach (ExternalTool *tool, it.value()) {
|
||||
if (tool->displayCategory() != category)
|
||||
settings->setValue(tool->id(), category);
|
||||
}
|
||||
}
|
||||
settings->endGroup();
|
||||
|
||||
settings->endGroup();
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include "icore.h"
|
||||
#include "core_global.h"
|
||||
#include "actionmanager/command.h"
|
||||
#include "actionmanager/actioncontainer.h"
|
||||
|
||||
#include <utils/qtcprocess.h>
|
||||
|
||||
@@ -58,12 +59,13 @@ public:
|
||||
};
|
||||
|
||||
ExternalTool();
|
||||
ExternalTool(const ExternalTool *other);
|
||||
explicit ExternalTool(const ExternalTool *other);
|
||||
~ExternalTool();
|
||||
|
||||
QString id() const;
|
||||
QString description() const;
|
||||
QString displayName() const;
|
||||
void setDisplayName(const QString &name);
|
||||
QString displayCategory() const;
|
||||
int order() const;
|
||||
OutputHandling outputHandling() const;
|
||||
@@ -76,6 +78,11 @@ public:
|
||||
|
||||
static ExternalTool *createFromXml(const QByteArray &xml, QString *errorMessage = 0, const QString &locale = QString());
|
||||
|
||||
// if the display name is different from the one in the original xml
|
||||
bool isDisplayNameChanged() const { return m_isDisplayNameChanged; }
|
||||
|
||||
// ignores changed state
|
||||
bool operator==(const ExternalTool &other);
|
||||
private:
|
||||
QString m_id;
|
||||
QString m_description;
|
||||
@@ -88,6 +95,7 @@ private:
|
||||
QString m_workingDirectory;
|
||||
OutputHandling m_outputHandling;
|
||||
OutputHandling m_errorHandling;
|
||||
bool m_isDisplayNameChanged;
|
||||
};
|
||||
|
||||
class ExternalToolRunner : public QObject
|
||||
@@ -95,6 +103,7 @@ class ExternalToolRunner : public QObject
|
||||
Q_OBJECT
|
||||
public:
|
||||
ExternalToolRunner(const ExternalTool *tool);
|
||||
~ExternalToolRunner();
|
||||
|
||||
private slots:
|
||||
void started();
|
||||
@@ -107,7 +116,7 @@ private:
|
||||
void run();
|
||||
bool resolve();
|
||||
|
||||
const ExternalTool *m_tool;
|
||||
const ExternalTool *m_tool; // is a copy of the tool that was passed in
|
||||
QString m_resolvedExecutable;
|
||||
QString m_resolvedArguments;
|
||||
QString m_resolvedInput;
|
||||
@@ -132,7 +141,10 @@ public:
|
||||
ExternalToolManager(Core::ICore *core);
|
||||
~ExternalToolManager();
|
||||
|
||||
QMap<QString, QList<Internal::ExternalTool *> > tools() const;
|
||||
QMap<QString, QList<Internal::ExternalTool *> > toolsByCategory() const;
|
||||
QMap<QString, Internal::ExternalTool *> toolsById() const;
|
||||
|
||||
void setToolsByCategory(const QMap<QString, QList<Internal::ExternalTool *> > &tools);
|
||||
|
||||
signals:
|
||||
void replaceSelectionRequested(const QString &text);
|
||||
@@ -142,13 +154,20 @@ private slots:
|
||||
|
||||
private:
|
||||
void initialize();
|
||||
void parseDirectory(const QString &directory, QMap<QString, QMultiMap<int, Internal::ExternalTool*> > *categoryMenus,
|
||||
void parseDirectory(const QString &directory,
|
||||
QMap<QString, QMultiMap<int, Internal::ExternalTool*> > *categoryMenus,
|
||||
QMap<QString, Internal::ExternalTool *> *tools,
|
||||
bool ignoreDuplicates = false);
|
||||
void readSettings(const QMap<QString, Internal::ExternalTool *> &tools,
|
||||
QMap<QString, QMultiMap<int, Internal::ExternalTool*> > *categoryPriorityMap);
|
||||
void writeSettings();
|
||||
|
||||
static ExternalToolManager *m_instance;
|
||||
Core::ICore *m_core;
|
||||
QMap<QString, Internal::ExternalTool *> m_tools;
|
||||
QMap<QString, QList<Internal::ExternalTool *> > m_categoryMap;
|
||||
QMap<QString, QAction *> m_actions;
|
||||
QMap<QString, ActionContainer *> m_containers;
|
||||
|
||||
// for sending the replaceSelectionRequested signal
|
||||
friend class Core::Internal::ExternalToolRunner;
|
||||
|
||||
@@ -134,6 +134,7 @@ MainWindow::MainWindow() :
|
||||
m_printer(0),
|
||||
m_actionManager(new ActionManagerPrivate(this)),
|
||||
m_editorManager(0),
|
||||
m_externalToolManager(0),
|
||||
m_fileManager(new FileManager(this)),
|
||||
m_progressManager(new ProgressManagerPrivate()),
|
||||
m_scriptManager(new ScriptManagerPrivate(this)),
|
||||
@@ -208,7 +209,7 @@ MainWindow::MainWindow() :
|
||||
m_messageManager = new MessageManager;
|
||||
m_editorManager = new EditorManager(m_coreImpl, this);
|
||||
m_editorManager->hide();
|
||||
new ExternalToolManager(m_coreImpl);
|
||||
m_externalToolManager = new ExternalToolManager(m_coreImpl);
|
||||
setCentralWidget(m_modeStack);
|
||||
|
||||
connect(QApplication::instance(), SIGNAL(focusChanged(QWidget*,QWidget*)),
|
||||
@@ -255,6 +256,8 @@ MainWindow::~MainWindow()
|
||||
pm->removeObject(m_generalSettings);
|
||||
pm->removeObject(m_toolSettings);
|
||||
pm->removeObject(m_systemEditor);
|
||||
delete m_externalToolManager;
|
||||
m_externalToolManager = 0;
|
||||
delete m_messageManager;
|
||||
m_messageManager = 0;
|
||||
delete m_shortcutSettings;
|
||||
|
||||
@@ -53,6 +53,7 @@ namespace Core {
|
||||
class ActionManager;
|
||||
class StatusBarWidget;
|
||||
class EditorManager;
|
||||
class ExternalToolManager;
|
||||
class FileManager;
|
||||
class HelpManager;
|
||||
class IWizard;
|
||||
@@ -189,6 +190,7 @@ private:
|
||||
mutable QPrinter *m_printer;
|
||||
ActionManagerPrivate *m_actionManager;
|
||||
EditorManager *m_editorManager;
|
||||
ExternalToolManager *m_externalToolManager;
|
||||
FileManager *m_fileManager;
|
||||
MessageManager *m_messageManager;
|
||||
ProgressManagerPrivate *m_progressManager;
|
||||
|
||||
@@ -80,7 +80,7 @@ bool ToolSettings::matches(const QString & searchKeyWord) const
|
||||
QWidget *ToolSettings::createPage(QWidget *parent)
|
||||
{
|
||||
m_widget = new ExternalToolConfig(parent);
|
||||
m_widget->setTools(ExternalToolManager::instance()->tools());
|
||||
m_widget->setTools(ExternalToolManager::instance()->toolsByCategory());
|
||||
if (m_searchKeywords.isEmpty()) {
|
||||
m_searchKeywords = m_widget->searchKeywords();
|
||||
}
|
||||
@@ -90,6 +90,30 @@ QWidget *ToolSettings::createPage(QWidget *parent)
|
||||
|
||||
void ToolSettings::apply()
|
||||
{
|
||||
if (!m_widget)
|
||||
return;
|
||||
QMap<QString, ExternalTool *> originalTools = ExternalToolManager::instance()->toolsById();
|
||||
QMap<QString, QList<ExternalTool *> > newToolsMap = m_widget->tools();
|
||||
QMap<QString, QList<ExternalTool *> > resultMap;
|
||||
QMapIterator<QString, QList<ExternalTool *> > it(newToolsMap);
|
||||
while (it.hasNext()) {
|
||||
it.next();
|
||||
QList<ExternalTool *> items;
|
||||
foreach (ExternalTool *tool, it.value()) {
|
||||
ExternalTool *toolToAdd = 0;
|
||||
if (ExternalTool *originalTool = originalTools.take(tool->id())) {
|
||||
// check if the tool has changed
|
||||
if ((*originalTool) == (*tool)) {
|
||||
toolToAdd = originalTool;
|
||||
} else {
|
||||
toolToAdd = new ExternalTool(tool);
|
||||
}
|
||||
}
|
||||
items.append(toolToAdd);
|
||||
}
|
||||
resultMap.insert(it.key(), items);
|
||||
}
|
||||
ExternalToolManager::instance()->setToolsByCategory(resultMap);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user