forked from qt-creator/qt-creator
Make adding user tools possible.
Adding new categories is not there yet though, neither is moving tools through the categories.
This commit is contained in:
@@ -70,6 +70,7 @@ ExternalToolConfig::ExternalToolConfig(QWidget *parent) :
|
||||
ui->removeButton->setIcon(QIcon(QLatin1String(Constants::ICON_MINUS)));
|
||||
ui->revertButton->setIcon(QIcon(QLatin1String(Constants::ICON_RESET)));
|
||||
connect(ui->revertButton, SIGNAL(clicked()), this, SLOT(revertCurrentItem()));
|
||||
connect(ui->addButton, SIGNAL(clicked()), this, SLOT(addTool()));
|
||||
|
||||
showInfoForItem(0);
|
||||
updateButtons(ui->toolTree->currentItem());
|
||||
@@ -100,6 +101,9 @@ QString ExternalToolConfig::searchKeywords() const
|
||||
return keywords;
|
||||
}
|
||||
|
||||
static const Qt::ItemFlags TOOL_ITEM_FLAGS = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | Qt::ItemIsEditable;
|
||||
|
||||
|
||||
void ExternalToolConfig::setTools(const QMap<QString, QList<ExternalTool *> > &tools)
|
||||
{
|
||||
QMapIterator<QString, QList<ExternalTool *> > it(tools);
|
||||
@@ -112,17 +116,16 @@ void ExternalToolConfig::setTools(const QMap<QString, QList<ExternalTool *> > &t
|
||||
}
|
||||
|
||||
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->setFlags(TOOL_ITEM_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->setFlags(TOOL_ITEM_FLAGS);
|
||||
item->setData(0, Qt::UserRole, qVariantFromValue(tool));
|
||||
}
|
||||
}
|
||||
@@ -139,6 +142,7 @@ void ExternalToolConfig::handleCurrentItemChanged(QTreeWidgetItem *now, QTreeWid
|
||||
void ExternalToolConfig::updateButtons(QTreeWidgetItem *item)
|
||||
{
|
||||
ExternalTool *tool = 0;
|
||||
ui->addButton->setEnabled(item != 0);
|
||||
if (item)
|
||||
tool = item->data(0, Qt::UserRole).value<ExternalTool *>();
|
||||
if (!tool) {
|
||||
@@ -216,6 +220,8 @@ void ExternalToolConfig::showInfoForItem(QTreeWidgetItem *item)
|
||||
|
||||
void ExternalToolConfig::updateItemName(QTreeWidgetItem *item)
|
||||
{
|
||||
if (item != ui->toolTree->currentItem())
|
||||
return;
|
||||
ExternalTool *tool = 0;
|
||||
if (item)
|
||||
tool = item->data(0, Qt::UserRole).value<ExternalTool *>();
|
||||
@@ -258,6 +264,7 @@ void ExternalToolConfig::updateItemName(QTreeWidgetItem *item)
|
||||
ui->toolTree->insertTopLevelItem(newIndex, item);
|
||||
if (wasExpanded)
|
||||
ui->toolTree->expand(ui->toolTree->model()->index(newIndex, 0));
|
||||
ui->toolTree->setCurrentItem(item);
|
||||
ui->toolTree->blockSignals(blocked); // unblock itemChanged
|
||||
}
|
||||
updateButtons(item);
|
||||
@@ -299,3 +306,33 @@ void ExternalToolConfig::revertCurrentItem()
|
||||
}
|
||||
delete tool;
|
||||
}
|
||||
|
||||
void ExternalToolConfig::addTool()
|
||||
{
|
||||
// find category to use
|
||||
QTreeWidgetItem *currentItem = ui->toolTree->currentItem();
|
||||
QTC_ASSERT(currentItem, return);
|
||||
QString category;
|
||||
QTreeWidgetItem *parent;
|
||||
if (currentItem->parent()) {
|
||||
parent = currentItem->parent();
|
||||
} else {
|
||||
parent = currentItem;
|
||||
}
|
||||
category = parent->data(0, Qt::UserRole).toString();
|
||||
ExternalTool *tool = new ExternalTool;
|
||||
tool->setCategory(category);
|
||||
tool->setDisplayName(tr("New tool"));
|
||||
tool->setDescription(tr("This tool prints a line of useful text"));
|
||||
tool->setExecutables(QStringList() << "echo");
|
||||
tool->setArguments(tr("Useful text"));
|
||||
// todo ordering
|
||||
m_tools[category].append(tool);
|
||||
bool blocked = ui->toolTree->blockSignals(true); // block itemChanged
|
||||
QTreeWidgetItem *item = new QTreeWidgetItem(parent, QStringList() << tool->displayName());
|
||||
item->setFlags(TOOL_ITEM_FLAGS);
|
||||
item->setData(0, Qt::UserRole, qVariantFromValue(tool));
|
||||
ui->toolTree->blockSignals(blocked); // unblock itemChanged
|
||||
ui->toolTree->setCurrentItem(item);
|
||||
ui->toolTree->editItem(item);
|
||||
}
|
||||
|
||||
@@ -68,6 +68,7 @@ private slots:
|
||||
void revertCurrentItem();
|
||||
void updateButtons(QTreeWidgetItem *item);
|
||||
void updateCurrentItem();
|
||||
void addTool();
|
||||
|
||||
private:
|
||||
Ui::ExternalToolConfig *ui;
|
||||
|
||||
@@ -193,6 +193,16 @@ QSharedPointer<ExternalTool> ExternalTool::preset() const
|
||||
return m_presetTool;
|
||||
}
|
||||
|
||||
void ExternalTool::setId(const QString &id)
|
||||
{
|
||||
m_id = id;
|
||||
}
|
||||
|
||||
void ExternalTool::setCategory(const QString &category)
|
||||
{
|
||||
m_displayCategory = category;
|
||||
}
|
||||
|
||||
void ExternalTool::setDisplayName(const QString &name)
|
||||
{
|
||||
m_displayName = name;
|
||||
|
||||
@@ -91,7 +91,8 @@ public:
|
||||
bool operator==(const ExternalTool &other);
|
||||
bool operator!=(const ExternalTool &other) { return !((*this) == other); }
|
||||
|
||||
// display category and order are handled specially
|
||||
void setId(const QString &id);
|
||||
void setCategory(const QString &category);
|
||||
void setDisplayName(const QString &name);
|
||||
void setDescription(const QString &description);
|
||||
void setOutputHandling(OutputHandling handling);
|
||||
|
||||
@@ -35,6 +35,9 @@
|
||||
#include <QtCore/QCoreApplication>
|
||||
#include <QtCore/QFileInfo>
|
||||
#include <QtCore/QDir>
|
||||
#include <QtCore/QTime>
|
||||
|
||||
#include <QtDebug>
|
||||
|
||||
using namespace Core;
|
||||
using namespace Core::Internal;
|
||||
@@ -90,6 +93,67 @@ QWidget *ToolSettings::createPage(QWidget *parent)
|
||||
}
|
||||
|
||||
|
||||
static QString getUserFilePath(const QString &proposalFileName)
|
||||
{
|
||||
static bool seeded = false;
|
||||
QDir resourceDir(ICore::instance()->userResourcePath());
|
||||
if (!resourceDir.exists(QLatin1String("externaltools")))
|
||||
resourceDir.mkpath(QLatin1String("externaltools"));
|
||||
QFileInfo fi(proposalFileName);
|
||||
const QString &suffix = QLatin1String(".") + fi.completeSuffix();
|
||||
const QString &newFilePath = ICore::instance()->userResourcePath()
|
||||
+ QLatin1String("/externaltools/") + fi.baseName();
|
||||
int count = 0;
|
||||
QString tryPath = newFilePath + suffix;
|
||||
while (QFile::exists(tryPath)) {
|
||||
if (count > 15)
|
||||
return QString();
|
||||
// add random number
|
||||
if (!seeded) {
|
||||
seeded = true;
|
||||
qsrand(QTime::currentTime().msec());
|
||||
}
|
||||
int number = qrand() % 1000;
|
||||
tryPath = newFilePath + QString::number(number) + suffix;
|
||||
}
|
||||
return tryPath;
|
||||
}
|
||||
|
||||
static QString idFromDisplayName(const QString &displayName)
|
||||
{
|
||||
QString id = displayName;
|
||||
QChar *c = id.data();
|
||||
while (!c->isNull()) {
|
||||
if (!c->isLetterOrNumber())
|
||||
*c = QLatin1Char('_');
|
||||
++c;
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
static QString findUnusedId(const QString &proposal, const QMap<QString, QList<ExternalTool *> > &tools)
|
||||
{
|
||||
int number = 0;
|
||||
QString result;
|
||||
bool found = false;
|
||||
do {
|
||||
result = proposal + (number > 0 ? QString::number(number) : QString::fromLatin1(""));
|
||||
++number;
|
||||
found = false;
|
||||
QMapIterator<QString, QList<ExternalTool *> > it(tools);
|
||||
while (!found && it.hasNext()) {
|
||||
it.next();
|
||||
foreach (ExternalTool *tool, it.value()) {
|
||||
if (tool->id() == proposal) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (found);
|
||||
return result;
|
||||
}
|
||||
|
||||
void ToolSettings::apply()
|
||||
{
|
||||
if (!m_widget)
|
||||
@@ -113,13 +177,9 @@ void ToolSettings::apply()
|
||||
if (tool->preset() && (*tool) != (*(tool->preset()))) {
|
||||
// check if we need to choose a new file name
|
||||
if (tool->preset()->fileName() == tool->fileName()) {
|
||||
// TODO avoid overwriting a tool xml file of another existing tool?
|
||||
const QString &fileName = QFileInfo(tool->preset()->fileName()).fileName();
|
||||
QDir resourceDir(ICore::instance()->userResourcePath());
|
||||
if (!resourceDir.exists(QLatin1String("externaltools")))
|
||||
resourceDir.mkpath(QLatin1String("externaltools"));
|
||||
const QString &newFilePath = ICore::instance()->userResourcePath()
|
||||
+ QLatin1String("/externaltools/") + fileName;
|
||||
const QString &newFilePath = getUserFilePath(fileName);
|
||||
// TODO error handling if newFilePath.isEmpty() (i.e. failed to find a unused name)
|
||||
tool->setFileName(newFilePath);
|
||||
}
|
||||
// TODO error handling
|
||||
@@ -143,6 +203,16 @@ void ToolSettings::apply()
|
||||
// 'tool' is deleted by config page, 'originalTool' is deleted by setToolsByCategory
|
||||
toolToAdd = new ExternalTool(tool);
|
||||
}
|
||||
} else {
|
||||
// new tool. 'tool' is deleted by config page
|
||||
QString id = idFromDisplayName(tool->displayName());
|
||||
id = findUnusedId(id, newToolsMap);
|
||||
tool->setId(id);
|
||||
// TODO error handling if newFilePath.isEmpty() (i.e. failed to find a unused name)
|
||||
tool->setFileName(getUserFilePath(id + QLatin1String(".xml")));
|
||||
// TODO error handling
|
||||
tool->save();
|
||||
toolToAdd = new ExternalTool(tool);
|
||||
}
|
||||
items.append(toolToAdd);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user