Commit 8cda869a authored by con's avatar con
Browse files

Make adding user tools possible.

Adding new categories is not there yet though, neither is moving tools
through the categories.
parent 8cb7e30a
......@@ -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);
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment