Commit 4143a8ef authored by Kåre Särs's avatar Kåre Särs
Browse files

Build-plugin: Rework build target selection/execution

- Remove "default target", execute first command in target-set in stead
- Remove the check-box for "default target"
- Add sorting buttons to move commands/target-sets up or down
- Move "default targets" from old configs to be first in the target-set
- Fix flags for run column: select-able and same background as the rest
- Fix copyright header
parent b23d0b67
/***************************************************************************
* This file is part of Kate search plugin *
* SPDX-FileCopyrightText: 2014 Kåre Särs <kare.sars@iki.fi> *
* SPDX-FileCopyrightText: 2014 Kåre Särs <kare.sars@iki.fi> *
* *
* SPDX-License-Identifier: LGPL-2.0-or-later
* SPDX-License-Identifier: LGPL-2.0-or-later *
***************************************************************************/
#include "TargetHtmlDelegate.h"
......@@ -72,9 +72,6 @@ void TargetHtmlDelegate::paint(QPainter *painter, const QStyleOptionViewItem &op
// draw text
painter->translate(option.rect.x(), option.rect.y());
if (index.column() == 0 && index.internalId() != TargetModel::InvalidIndex) {
painter->translate(25, 0);
}
doc.drawContents(painter);
painter->restore();
......@@ -85,9 +82,6 @@ QSize TargetHtmlDelegate::sizeHint(const QStyleOptionViewItem & /* option */, co
QTextDocument doc;
doc.setHtml(index.data().toString().toHtmlEscaped());
doc.setDocumentMargin(2);
if (index.column() == 0 && index.internalId() != TargetModel::InvalidIndex) {
return doc.size().toSize() + QSize(30, 0); // add margin for the check-box;
}
if (index.column() == 1 && !index.parent().isValid()) {
return doc.size().toSize() + QSize(38, 0); // add space for "Dir"
}
......@@ -151,15 +145,12 @@ void TargetHtmlDelegate::setModelData(QWidget *editor, QAbstractItemModel *model
model->setData(index, value, Qt::EditRole);
}
void TargetHtmlDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
void TargetHtmlDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &) const
{
QRect rect = option.rect;
int heightDiff = QToolButton().sizeHint().height() - rect.height();
int half = heightDiff / 2;
rect.adjust(0, -half, 0, heightDiff - half);
if (index.column() == 0 && index.internalId() != TargetModel::InvalidIndex) {
rect.adjust(25, 0, 0, 0);
}
editor->setGeometry(rect);
}
......
/***************************************************************************
* This file is part of Kate build plugin *
* SPDX-FileCopyrightText: 2014 Kåre Särs <kare.sars@iki.fi> *
* SPDX-FileCopyrightText: 2014 Kåre Särs <kare.sars@iki.fi> *
* *
* SPDX-License-Identifier: LGPL-2.0-or-later
* SPDX-License-Identifier: LGPL-2.0-or-later *
***************************************************************************/
#ifndef TargetHtmlDelegate_H
......
/***************************************************************************
* This file is part of Kate build plugin *
* SPDX-FileCopyrightText: 2014 Kåre Särs <kare.sars@iki.fi> *
* SPDX-FileCopyrightText: 2014 Kåre Särs <kare.sars@iki.fi> *
* *
* SPDX-License-Identifier: LGPL-2.0-or-later
* SPDX-License-Identifier: LGPL-2.0-or-later *
***************************************************************************/
#include "TargetModel.h"
......@@ -37,21 +37,6 @@ void TargetModel::clear()
endResetModel();
}
void TargetModel::setDefaultCmd(int rootRow, const QString &defCmd)
{
if (rootRow < 0 || rootRow >= m_targets.size()) {
qDebug() << "rootRow not valid";
return;
}
for (int i = 0; i < m_targets[rootRow].commands.size(); i++) {
if (defCmd == m_targets[rootRow].commands[i].name) {
m_targets[rootRow].defaultCmd = defCmd;
return;
}
}
}
QModelIndex TargetModel::addTargetSet(const QString &setName, const QString &workDir)
{
// make the name unique
......@@ -151,35 +136,6 @@ QModelIndex TargetModel::copyTargetOrSet(const QModelIndex &index)
return createIndex(m_targets[rootRow].commands.count() - 1, 0, rootRow);
}
QModelIndex TargetModel::defaultTarget(const QModelIndex &targetSet)
{
QModelIndex root = targetSet.sibling(targetSet.row(), 0);
if (root.parent().isValid()) {
// go to the parent so we know where we start
root = root.parent();
}
// This is the target-set root
auto model = root.model();
if (!model) {
qDebug() << "No model found";
return QModelIndex();
}
QModelIndex defaultIndex;
for (int i = 0; i < model->rowCount(root); ++i) {
QModelIndex childIndex = model->index(i, 0, root);
if (i == 0) {
defaultIndex = childIndex;
}
if (childIndex.data(Qt::CheckStateRole) == Qt::Checked) {
defaultIndex = childIndex;
break;
}
}
return defaultIndex;
}
void TargetModel::deleteItem(const QModelIndex &index)
{
if (!index.isValid()) {
......@@ -223,6 +179,56 @@ void TargetModel::deleteTargetSet(const QString &targetSet)
}
}
void TargetModel::moveRowUp(const QModelIndex &itemIndex)
{
if (!itemIndex.isValid() || !hasIndex(itemIndex.row(), itemIndex.column(), itemIndex.parent())) {
return;
}
QModelIndex parent = itemIndex.parent();
int row = itemIndex.row();
if (row < 1) {
return;
}
beginMoveRows(parent, row, row, parent, row - 1);
if (!parent.isValid()) {
m_targets.move(row, row - 1);
} else {
int rootRow = itemIndex.internalId();
if (rootRow < 0 || rootRow >= m_targets.size()) {
qWarning() << "Bad root row index" << rootRow << m_targets.size();
return;
}
m_targets[rootRow].commands.move(row, row - 1);
}
endMoveRows();
}
void TargetModel::moveRowDown(const QModelIndex &itemIndex)
{
if (!itemIndex.isValid() || !hasIndex(itemIndex.row(), itemIndex.column(), itemIndex.parent())) {
return;
}
QModelIndex parent = itemIndex.parent();
int row = itemIndex.row();
if (row > m_targets.size() - 2) {
return;
}
beginMoveRows(parent, row, row, parent, row + 2);
if (!parent.isValid()) {
m_targets.move(row, row + 1);
} else {
int rootRow = itemIndex.internalId();
if (rootRow < 0 || rootRow >= m_targets.size()) {
qWarning() << "Bad root row index" << rootRow << m_targets.size();
return;
}
m_targets[rootRow].commands.move(row, row + 1);
}
endMoveRows();
}
const QString TargetModel::command(const QModelIndex &itemIndex)
{
if (!itemIndex.isValid()) {
......@@ -351,12 +357,7 @@ QVariant TargetModel::data(const QModelIndex &index, int role) const
return QVariant();
}
if (role == Qt::CheckStateRole) {
if (index.column() != 0) {
return QVariant();
}
return m_targets[rootIndex].commands[row].buildCmd == m_targets[rootIndex].defaultCmd ? Qt::Checked : Qt::Unchecked;
} else {
if (role == Qt::DisplayRole || role == Qt::EditRole) {
switch (index.column()) {
case 0:
return m_targets[rootIndex].commands[row].name;
......@@ -395,8 +396,7 @@ QVariant TargetModel::headerData(int section, Qt::Orientation orientation, int r
bool TargetModel::setData(const QModelIndex &itemIndex, const QVariant &value, int role)
{
// FIXME
if (role != Qt::EditRole && role != Qt::CheckStateRole) {
if (role != Qt::EditRole) {
return false;
}
if (!itemIndex.isValid() || !hasIndex(itemIndex.row(), itemIndex.column(), itemIndex.parent())) {
......@@ -427,45 +427,34 @@ bool TargetModel::setData(const QModelIndex &itemIndex, const QVariant &value, i
return false;
}
if (role == Qt::CheckStateRole) {
if (itemIndex.column() == 0) {
m_targets[rootRow].defaultCmd = m_targets[rootRow].commands[row].buildCmd;
Q_EMIT dataChanged(createIndex(0, 0, rootRow), createIndex(m_targets[rootRow].commands.size() - 1, 0, rootRow));
}
} else {
QModelIndex rootIndex = createIndex(rootRow, 0);
switch (itemIndex.column()) {
case 0:
m_targets[rootRow].commands[row].name = value.toString();
Q_EMIT dataChanged(index(row, 0, rootIndex), index(row, 0, rootIndex));
return true;
case 1:
m_targets[rootRow].commands[row].buildCmd = value.toString();
Q_EMIT dataChanged(index(row, 1, rootIndex), index(row, 1, rootIndex));
return true;
case 2:
m_targets[rootRow].commands[row].runCmd = value.toString();
Q_EMIT dataChanged(index(row, 2, rootIndex), index(row, 2, rootIndex));
return true;
}
QModelIndex rootIndex = createIndex(rootRow, 0);
switch (itemIndex.column()) {
case 0:
m_targets[rootRow].commands[row].name = value.toString();
Q_EMIT dataChanged(index(row, 0, rootIndex), index(row, 0, rootIndex));
return true;
case 1:
m_targets[rootRow].commands[row].buildCmd = value.toString();
Q_EMIT dataChanged(index(row, 1, rootIndex), index(row, 1, rootIndex));
return true;
case 2:
m_targets[rootRow].commands[row].runCmd = value.toString();
Q_EMIT dataChanged(index(row, 2, rootIndex), index(row, 2, rootIndex));
return true;
}
}
return false;
}
Qt::ItemFlags TargetModel::flags(const QModelIndex &index) const
Qt::ItemFlags TargetModel::flags(const QModelIndex &itemIndex) const
{
if (!index.isValid()) {
if (!itemIndex.isValid()) {
return Qt::NoItemFlags;
}
// run command column for target set row
if (index.column() == 2 && !index.parent().isValid()) {
return Qt::NoItemFlags;
}
if (index.internalId() != InvalidIndex && index.column() == 0) {
return Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable;
if (itemIndex.column() == 2 && !itemIndex.parent().isValid()) {
return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
}
return Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
......@@ -504,24 +493,24 @@ QModelIndex TargetModel::index(int row, int column, const QModelIndex &parent) c
return QModelIndex();
}
quint32 rootIndex = InvalidIndex;
quint32 rootRow = InvalidIndex;
if (parent.isValid() && parent.internalId() == InvalidIndex) {
// This is a command (child of a root element)
if (parent.column() != 0) {
// Only root item column 0 can have children
return QModelIndex();
}
rootIndex = parent.row();
rootRow = parent.row();
if (parent.row() >= m_targets.size() || row >= m_targets.at(parent.row()).commands.size()) {
return QModelIndex();
}
return createIndex(row, column, rootIndex);
return createIndex(row, column, rootRow);
}
// This is a root item
if (row >= m_targets.size()) {
return QModelIndex();
}
return createIndex(row, column, rootIndex);
return createIndex(row, column, rootRow);
}
QModelIndex TargetModel::parent(const QModelIndex &child) const
......
......@@ -2,7 +2,7 @@
* This file is part of Kate build plugin *
* SPDX-FileCopyrightText: 2014 Kåre Särs <kare.sars@iki.fi> *
* *
* SPDX-License-Identifier: LGPL-2.0-or-later
* SPDX-License-Identifier: LGPL-2.0-or-later *
***************************************************************************/
#ifndef TargetModel_h
......@@ -24,16 +24,12 @@ public:
TargetSet(const QString &_name, const QString &_workDir);
QString name;
QString workDir;
QString defaultCmd;
QList<Command> commands;
};
TargetModel(QObject *parent = nullptr);
~TargetModel() override;
/** This function sets the default command for a target set */
void setDefaultCmd(int rootRow, const QString &defCmd);
public Q_SLOTS:
/** This function clears all the target-sets */
......@@ -56,13 +52,15 @@ public Q_SLOTS:
/** This function deletes the target-set with the same name */
void deleteTargetSet(const QString &targetSet);
void moveRowUp(const QModelIndex &index);
void moveRowDown(const QModelIndex &index);
const QList<TargetSet> targetSets() const
{
return m_targets;
}
/** Static functions that could be in a different file */
static QModelIndex defaultTarget(const QModelIndex &targetSetIndex);
static const QString command(const QModelIndex &itemIndex);
static const QString cmdName(const QModelIndex &itemIndex);
static const QString workDir(const QModelIndex &itemIndex);
......
/***************************************************************************
* This file is part of Kate search plugin *
* SPDX-FileCopyrightText: 2014 Kåre Särs <kare.sars@iki.fi> *
* SPDX-FileCopyrightText: 2014 Kåre Särs <kare.sars@iki.fi> *
* *
* SPDX-License-Identifier: LGPL-2.0-or-later
* SPDX-License-Identifier: LGPL-2.0-or-later *
***************************************************************************/
#include "UrlInserter.h"
......
/***************************************************************************
* This file is part of Kate search plugin *
* SPDX-FileCopyrightText: 2014 Kåre Särs <kare.sars@iki.fi> *
* SPDX-FileCopyrightText: 2014 Kåre Särs <kare.sars@iki.fi> *
* *
* SPDX-License-Identifier: LGPL-2.0-or-later
* SPDX-License-Identifier: LGPL-2.0-or-later *
***************************************************************************/
#ifndef UrlInserter_H
......
......@@ -139,18 +139,15 @@ KateBuildView::KateBuildView(KTextEditor::Plugin *plugin, KTextEditor::MainWindo
a->setText(i18n("Select Target..."));
a->setIcon(QIcon::fromTheme(QStringLiteral("select")));
connect(a, &QAction::triggered, this, &KateBuildView::slotSelectTarget);
a = actionCollection()->addAction(QStringLiteral("build_default_target"));
a->setText(i18n("Build Default Target"));
connect(a, &QAction::triggered, this, &KateBuildView::slotBuildDefaultTarget);
a = actionCollection()->addAction(QStringLiteral("build_and_run_default_target"));
a->setText(i18n("Build and Run Default Target"));
connect(a, &QAction::triggered, this, &KateBuildView::slotBuildAndRunDefaultTarget);
a = actionCollection()->addAction(QStringLiteral("build_previous_target"));
a->setText(i18n("Build Previous Target"));
a = actionCollection()->addAction(QStringLiteral("build_selected_target"));
a->setText(i18n("Build Selected Target"));
connect(a, &QAction::triggered, this, &KateBuildView::slotBuildPreviousTarget);
a = actionCollection()->addAction(QStringLiteral("build_and_run_selected_target"));
a->setText(i18n("Build and Run Selected Target"));
connect(a, &QAction::triggered, this, &KateBuildView::slotBuildAndRunSelectedTarget);
a = actionCollection()->addAction(QStringLiteral("stop"));
a->setText(i18n("Stop"));
a->setIcon(QIcon::fromTheme(QStringLiteral("edit-delete")));
......@@ -227,12 +224,9 @@ KateBuildView::KateBuildView(KTextEditor::Plugin *plugin, KTextEditor::MainWindo
connect(m_targetsUi->deleteTarget, &QToolButton::clicked, this, &KateBuildView::targetDelete);
connect(m_targetsUi->addButton, &QToolButton::clicked, this, &KateBuildView::slotAddTargetClicked);
connect(m_targetsUi->buildButton, &QToolButton::clicked, this, &KateBuildView::slotBuildActiveTarget);
connect(m_targetsUi->runButton, &QToolButton::clicked, this, [this] {
m_runAfterBuild = true;
slotBuildActiveTarget();
});
connect(m_targetsUi, &TargetsUi::enterPressed, this, &KateBuildView::slotBuildActiveTarget);
connect(m_targetsUi->buildButton, &QToolButton::clicked, this, &KateBuildView::slotBuildSelectedTarget);
connect(m_targetsUi->runButton, &QToolButton::clicked, this, &KateBuildView::slotBuildAndRunSelectedTarget);
connect(m_targetsUi, &TargetsUi::enterPressed, this, &KateBuildView::slotBuildSelectedTarget);
m_proc.setOutputChannelMode(KProcess::SeparateChannels);
connect(&m_proc, static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished), this, &KateBuildView::slotProcExited);
......@@ -271,8 +265,6 @@ void KateBuildView::readSessionConfig(const KConfigGroup &cg)
{
int numTargets = cg.readEntry(QStringLiteral("NumTargets"), 0);
m_targetsUi->targetsModel.clear();
int tmpIndex;
int tmpCmd;
for (int i = 0; i < numTargets; i++) {
QStringList targetNames = cg.readEntry(QStringLiteral("%1 Target Names").arg(i), QStringList());
......@@ -281,22 +273,19 @@ void KateBuildView::readSessionConfig(const KConfigGroup &cg)
QModelIndex index = m_targetsUi->targetsModel.addTargetSet(targetSetName, buildDir);
// Keep a bit of backwards compatibility by ensuring that the "default" target is the first in the list
QString defCmd = cg.readEntry(QStringLiteral("%1 Target Default").arg(i), QString());
int defIndex = targetNames.indexOf(defCmd);
if (defIndex > 0) {
targetNames.move(defIndex, 0);
}
for (int tn = 0; tn < targetNames.size(); ++tn) {
const QString &targetName = targetNames.at(tn);
const QString &buildCmd = cg.readEntry(QStringLiteral("%1 BuildCmd %2").arg(i).arg(targetName));
const QString &runCmd = cg.readEntry(QStringLiteral("%1 RunCmd %2").arg(i).arg(targetName));
m_targetsUi->targetsModel.addCommand(index, targetName, buildCmd, runCmd);
}
QString defCmd = cg.readEntry(QStringLiteral("%1 Target Default").arg(i), QString());
m_targetsUi->targetsModel.setDefaultCmd(i, defCmd);
}
tmpIndex = cg.readEntry(QStringLiteral("Active Target Index"), 0);
tmpCmd = cg.readEntry(QStringLiteral("Active Target Command"), 0);
QModelIndex root = m_targetsUi->targetsModel.index(tmpIndex);
QModelIndex cmdIndex = m_targetsUi->targetsModel.index(tmpCmd, 0, root);
cmdIndex = m_targetsUi->proxyModel.mapFromSource(cmdIndex);
m_targetsUi->targetsView->setCurrentIndex(cmdIndex);
auto showMarks = cg.readEntry(QStringLiteral("Show Marks"), false);
m_showMarks->setChecked(showMarks);
......@@ -307,6 +296,7 @@ void KateBuildView::readSessionConfig(const KConfigGroup &cg)
m_targetsUi->targetsView->expandAll();
m_targetsUi->targetsView->resizeColumnToContents(0);
m_targetsUi->targetsView->resizeColumnToContents(1);
m_targetsUi->updateBuildRunButtonStates();
}
/******************************************************************/
......@@ -333,24 +323,7 @@ void KateBuildView::writeSessionConfig(KConfigGroup &cg)
cg.writeEntry(QStringLiteral("%1 RunCmd %2").arg(i).arg(cmdName), runCmd);
}
cg.writeEntry(QStringLiteral("%1 Target Names").arg(i), cmdNames);
cg.writeEntry(QStringLiteral("%1 Target Default").arg(i), targets[i].defaultCmd);
}
int setRow = 0;
int set = 0;
QModelIndex ind = m_targetsUi->targetsView->currentIndex();
ind = m_targetsUi->proxyModel.mapToSource(ind);
if (ind.internalId() == TargetModel::InvalidIndex) {
set = ind.row();
} else {
set = ind.internalId();
setRow = ind.row();
}
if (setRow < 0) {
setRow = 0;
}
cg.writeEntry(QStringLiteral("Active Target Index"), set);
cg.writeEntry(QStringLiteral("Active Target Command"), setRow);
cg.writeEntry(QStringLiteral("Show Marks"), m_showMarks->isChecked());
// Restore project targets, if any
......@@ -832,23 +805,49 @@ bool KateBuildView::slotStop()
}
/******************************************************************/
void KateBuildView::slotBuildActiveTarget()
void KateBuildView::slotBuildSelectedTarget()
{
if (!m_targetsUi->targetsView->currentIndex().isValid()) {
QModelIndex currentIndex = m_targetsUi->targetsView->currentIndex();
if (!currentIndex.isValid()) {
slotSelectTarget();
} else {
buildCurrentTarget();
return;
}
if (!currentIndex.parent().isValid()) {
// This is a root item, try to build the first command
currentIndex = m_targetsUi->targetsView->model()->index(0, 0, currentIndex.siblingAtColumn(0));
if (currentIndex.isValid()) {
m_targetsUi->targetsView->setCurrentIndex(currentIndex);
} else {
slotSelectTarget();
return;
}
}
buildCurrentTarget();
}
void KateBuildView::slotBuildAndRunDefaultTarget()
/******************************************************************/
void KateBuildView::slotBuildAndRunSelectedTarget()
{
if (!m_targetsUi->targetsView->currentIndex().isValid()) {
QModelIndex currentIndex = m_targetsUi->targetsView->currentIndex();
if (!currentIndex.isValid()) {
slotSelectTarget();
} else {
m_runAfterBuild = true;
slotBuildDefaultTarget();
return;
}
if (!currentIndex.parent().isValid()) {
// This is a root item, try to build the first command
currentIndex = m_targetsUi->targetsView->model()->index(0, 0, currentIndex.siblingAtColumn(0));
if (currentIndex.isValid()) {
m_targetsUi->targetsView->setCurrentIndex(currentIndex);
} else {
slotSelectTarget();
return;
}
}
m_runAfterBuild = true;
buildCurrentTarget();
}
/******************************************************************/
......@@ -862,25 +861,19 @@ void KateBuildView::slotBuildPreviousTarget()
}
}
/******************************************************************/
void KateBuildView::slotBuildDefaultTarget()
{
QModelIndex defaultTarget = TargetModel::defaultTarget(m_targetsUi->targetsView->currentIndex());
m_targetsUi->targetsView->setCurrentIndex(defaultTarget);
buildCurrentTarget();
}
/******************************************************************/
void KateBuildView::slotSelectTarget()
{
m_buildUi.u_tabWidget->setCurrentIndex(0);
m_win->showToolView(m_toolView);
QPersistentModelIndex selected = m_targetsUi->targetsView->currentIndex();
m_targetsUi->targetFilterEdit->setText(QString());
m_targetsUi->targetFilterEdit->setFocus();
if (m_previousIndex.isValid()) {
m_targetsUi->targetsView->setCurrentIndex(m_previousIndex);
}
m_targetsUi->targetsView->expandAll();
if (selected.isValid()) {
m_targetsUi->targetsView->setCurrentIndex(selected);
}
m_targetsUi->targetsView->scrollTo(selected);
}
/******************************************************************/
......
......@@ -72,10 +72,9 @@ private Q_SLOTS:
// Building
void slotSelectTarget();
void slotBuildAndRunDefaultTarget();
void slotBuildActiveTarget();
void slotBuildSelectedTarget();
void slotBuildAndRunSelectedTarget();
void slotBuildPreviousTarget();
void slotBuildDefaultTarget();
bool slotStop();
// Parse output
......@@ -152,7 +151,6 @@ private:
QRegularExpression m_newDirDetector;
unsigned int m_numErrors = 0;
unsigned int m_numWarnings = 0;
QString m_prevItemContent;
QPersistentModelIndex m_previousIndex;
QPointer<KTextEditor::Message> m_infoMessage;
QPointer<QAction> m_showMarks;
......
//
// Description: Widget for configuring build targets
//
// SPDX-FileCopyrightText: 2011-2014 Kåre Särs <kare.sars@iki.fi>
// SPDX-FileCopyrightText: 2011-2022 Kåre Särs <kare.sars@iki.fi>
//
// SPDX-License-Identifier: LGPL-2.0-only