2012-10-02 09:12:39 +02:00
|
|
|
/****************************************************************************
|
2008-12-02 12:01:29 +01:00
|
|
|
**
|
2016-01-15 14:57:40 +01:00
|
|
|
** Copyright (C) 2016 The Qt Company Ltd.
|
|
|
|
|
** Contact: https://www.qt.io/licensing/
|
2008-12-02 12:01:29 +01:00
|
|
|
**
|
2012-10-02 09:12:39 +02:00
|
|
|
** This file is part of Qt Creator.
|
2008-12-02 12:01:29 +01:00
|
|
|
**
|
2012-10-02 09:12:39 +02:00
|
|
|
** Commercial License Usage
|
|
|
|
|
** Licensees holding valid commercial Qt licenses may use this file in
|
|
|
|
|
** accordance with the commercial license agreement provided with the
|
|
|
|
|
** Software or, alternatively, in accordance with the terms contained in
|
2016-01-15 14:57:40 +01:00
|
|
|
** a written agreement between you and The Qt Company. For licensing terms
|
|
|
|
|
** and conditions see https://www.qt.io/terms-conditions. For further
|
|
|
|
|
** information use the contact form at https://www.qt.io/contact-us.
|
2008-12-02 14:17:16 +01:00
|
|
|
**
|
2016-01-15 14:57:40 +01:00
|
|
|
** GNU General Public License Usage
|
|
|
|
|
** Alternatively, this file may be used under the terms of the GNU
|
|
|
|
|
** General Public License version 3 as published by the Free Software
|
|
|
|
|
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
|
|
|
|
** included in the packaging of this file. Please review the following
|
|
|
|
|
** information to ensure the GNU General Public License requirements will
|
|
|
|
|
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
2010-12-17 16:01:08 +01:00
|
|
|
**
|
2012-10-02 09:12:39 +02:00
|
|
|
****************************************************************************/
|
2008-12-02 16:19:05 +01:00
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
#include "vcsbasesubmiteditor.h"
|
2010-04-12 16:34:21 +02:00
|
|
|
|
|
|
|
|
#include "commonvcssettings.h"
|
2009-03-19 17:40:01 +01:00
|
|
|
#include "nicknamedialog.h"
|
2008-12-02 12:01:29 +01:00
|
|
|
#include "submiteditorfile.h"
|
2013-01-02 22:12:06 +02:00
|
|
|
#include "submiteditorwidget.h"
|
|
|
|
|
#include "submitfieldwidget.h"
|
2013-01-02 22:19:04 +02:00
|
|
|
#include "submitfilemodel.h"
|
2014-08-26 00:02:47 +02:00
|
|
|
#include "vcsoutputwindow.h"
|
2013-01-02 22:12:06 +02:00
|
|
|
#include "vcsplugin.h"
|
2015-02-20 11:35:36 +01:00
|
|
|
#include "vcsprojectcache.h"
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2009-03-04 09:38:01 +01:00
|
|
|
#include <aggregation/aggregate.h>
|
2014-09-15 00:12:27 +02:00
|
|
|
#include <cpptools/cppmodelmanager.h>
|
2009-03-19 17:40:01 +01:00
|
|
|
#include <coreplugin/icore.h>
|
2012-12-25 18:27:38 +02:00
|
|
|
#include <coreplugin/editormanager/editormanager.h>
|
2009-06-19 16:34:38 +02:00
|
|
|
#include <utils/checkablemessagebox.h>
|
2015-02-26 09:33:24 +01:00
|
|
|
#include <utils/completingtextedit.h>
|
2010-03-01 10:06:05 +01:00
|
|
|
#include <utils/synchronousprocess.h>
|
2011-03-30 13:45:16 +02:00
|
|
|
#include <utils/fileutils.h>
|
2017-10-06 17:58:08 +02:00
|
|
|
#include <utils/icon.h>
|
|
|
|
|
#include <utils/theme/theme.h>
|
2013-01-07 22:15:03 +02:00
|
|
|
#include <utils/qtcassert.h>
|
2017-01-19 16:44:22 +01:00
|
|
|
#include <utils/temporarydirectory.h>
|
2014-01-13 16:17:34 +01:00
|
|
|
#include <coreplugin/find/basetextfind.h>
|
2009-03-25 08:52:39 +01:00
|
|
|
#include <texteditor/fontsettings.h>
|
|
|
|
|
#include <texteditor/texteditorsettings.h>
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2009-09-25 11:35:44 +02:00
|
|
|
#include <projectexplorer/project.h>
|
2017-06-14 16:38:42 +03:00
|
|
|
#include <projectexplorer/session.h>
|
2009-01-09 17:52:41 +01:00
|
|
|
|
2012-02-15 10:42:41 +01:00
|
|
|
#include <QDir>
|
|
|
|
|
#include <QFileInfo>
|
|
|
|
|
#include <QPointer>
|
2015-02-20 11:35:36 +01:00
|
|
|
#include <QProcess>
|
|
|
|
|
#include <QSet>
|
2012-02-15 10:42:41 +01:00
|
|
|
#include <QStringListModel>
|
|
|
|
|
#include <QStyle>
|
|
|
|
|
#include <QToolBar>
|
|
|
|
|
#include <QAction>
|
|
|
|
|
#include <QApplication>
|
|
|
|
|
#include <QMessageBox>
|
|
|
|
|
#include <QCompleter>
|
2013-03-25 11:36:51 +01:00
|
|
|
|
2011-12-12 19:35:06 +01:00
|
|
|
#include <cstring>
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
|
enum { debug = 0 };
|
2008-12-02 17:05:53 +01:00
|
|
|
enum { wantToolBar = 0 };
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2011-12-05 15:37:19 +01:00
|
|
|
// Return true if word is meaningful and can be added to a completion model
|
|
|
|
|
static bool acceptsWordForCompletion(const char *word)
|
|
|
|
|
{
|
2018-09-20 01:32:36 +03:00
|
|
|
if (!word)
|
2011-12-12 19:35:06 +01:00
|
|
|
return false;
|
|
|
|
|
static const std::size_t minWordLength = 7;
|
|
|
|
|
return std::strlen(word) >= minWordLength;
|
2011-12-05 15:37:19 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Return the class name which function belongs to
|
|
|
|
|
static const char *belongingClassName(const CPlusPlus::Function *function)
|
|
|
|
|
{
|
2018-09-20 01:32:36 +03:00
|
|
|
if (!function)
|
|
|
|
|
return nullptr;
|
2011-12-05 15:37:19 +01:00
|
|
|
|
2018-09-20 01:32:36 +03:00
|
|
|
if (auto funcName = function->name()) {
|
|
|
|
|
if (auto qualifiedNameId = funcName->asQualifiedNameId()) {
|
|
|
|
|
if (const CPlusPlus::Name *funcBaseName = qualifiedNameId->base()) {
|
|
|
|
|
if (auto identifier = funcBaseName->identifier())
|
|
|
|
|
return identifier->chars();
|
|
|
|
|
}
|
|
|
|
|
}
|
2011-12-05 15:37:19 +01:00
|
|
|
}
|
|
|
|
|
|
2018-09-20 01:32:36 +03:00
|
|
|
return nullptr;
|
2011-12-05 15:37:19 +01:00
|
|
|
}
|
|
|
|
|
|
2011-03-28 14:19:17 +02:00
|
|
|
/*!
|
2013-06-05 14:29:24 +02:00
|
|
|
\class VcsBase::VcsBaseSubmitEditorParameters
|
2011-03-28 14:19:17 +02:00
|
|
|
|
2013-06-05 14:29:24 +02:00
|
|
|
\brief The VcsBaseSubmitEditorParameters class is a utility class
|
|
|
|
|
to parametrize a VcsBaseSubmitEditor.
|
2011-03-28 14:19:17 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/*!
|
2012-01-07 12:31:48 +01:00
|
|
|
\class VcsBase::VcsBaseSubmitEditor
|
2011-03-28 14:19:17 +02:00
|
|
|
|
2013-06-05 14:29:24 +02:00
|
|
|
\brief The VcsBaseSubmitEditor class is the base class for a submit editor
|
|
|
|
|
based on the SubmitEditorWidget.
|
2011-03-28 14:19:17 +02:00
|
|
|
|
|
|
|
|
Presents the commit message in a text editor and an
|
|
|
|
|
checkable list of modified files in a list window. The user can delete
|
|
|
|
|
files from the list by pressing unchecking them or diff the selection
|
|
|
|
|
by doubleclicking.
|
|
|
|
|
|
2014-03-04 00:12:11 +01:00
|
|
|
The action matching the ids (unless 0) of the parameter struct will be
|
2011-03-28 14:19:17 +02:00
|
|
|
registered with the EditorWidget and submit/diff actions will be added to
|
|
|
|
|
a toolbar.
|
|
|
|
|
|
|
|
|
|
For the given context, there must be only one instance of the editor
|
|
|
|
|
active.
|
|
|
|
|
To start a submit, set the submit template on the editor and the output
|
|
|
|
|
of the VCS status command listing the modified files as fileList and open
|
|
|
|
|
it.
|
|
|
|
|
|
|
|
|
|
The submit process is started by listening on the editor close
|
2012-02-14 16:43:51 +01:00
|
|
|
signal and then asking the IDocument interface of the editor to save the file
|
|
|
|
|
within a DocumentManager::blockFileChange() section
|
2011-03-28 14:19:17 +02:00
|
|
|
and to launch the submit process. In addition, the action registered
|
|
|
|
|
for submit should be connected to a slot triggering the close of the
|
|
|
|
|
current editor in the editor manager.
|
|
|
|
|
*/
|
|
|
|
|
|
2012-01-07 12:31:48 +01:00
|
|
|
namespace VcsBase {
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2012-01-07 03:35:54 +01:00
|
|
|
using namespace Internal;
|
|
|
|
|
using namespace Utils;
|
|
|
|
|
|
2009-03-19 17:40:01 +01:00
|
|
|
static inline QString submitMessageCheckScript()
|
|
|
|
|
{
|
2012-01-07 12:31:48 +01:00
|
|
|
return VcsPlugin::instance()->settings().submitMessageCheckScript;
|
2009-03-19 17:40:01 +01:00
|
|
|
}
|
|
|
|
|
|
2015-02-20 11:35:36 +01:00
|
|
|
class VcsBaseSubmitEditorPrivate
|
2009-01-20 11:52:04 +01:00
|
|
|
{
|
2015-02-20 11:35:36 +01:00
|
|
|
public:
|
2012-01-07 12:31:48 +01:00
|
|
|
VcsBaseSubmitEditorPrivate(const VcsBaseSubmitEditorParameters *parameters,
|
2012-01-07 03:35:54 +01:00
|
|
|
SubmitEditorWidget *editorWidget,
|
2013-07-15 10:35:10 +02:00
|
|
|
VcsBaseSubmitEditor *q);
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2012-01-07 03:35:54 +01:00
|
|
|
SubmitEditorWidget *m_widget;
|
2018-09-20 01:32:36 +03:00
|
|
|
QToolBar *m_toolWidget = nullptr;
|
2012-01-07 12:31:48 +01:00
|
|
|
const VcsBaseSubmitEditorParameters *m_parameters;
|
2008-12-02 12:01:29 +01:00
|
|
|
QString m_displayName;
|
2009-12-14 10:56:50 +01:00
|
|
|
QString m_checkScriptWorkingDirectory;
|
2012-01-07 03:35:54 +01:00
|
|
|
SubmitEditorFile *m_file;
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
|
QPointer<QAction> m_diffAction;
|
2009-01-13 14:06:42 +01:00
|
|
|
QPointer<QAction> m_submitAction;
|
2009-03-19 17:40:01 +01:00
|
|
|
|
2018-09-20 01:32:36 +03:00
|
|
|
NickNameDialog *m_nickNameDialog = nullptr;
|
2008-12-02 12:01:29 +01:00
|
|
|
};
|
|
|
|
|
|
2012-01-07 12:31:48 +01:00
|
|
|
VcsBaseSubmitEditorPrivate::VcsBaseSubmitEditorPrivate(const VcsBaseSubmitEditorParameters *parameters,
|
2012-01-07 03:35:54 +01:00
|
|
|
SubmitEditorWidget *editorWidget,
|
2013-07-15 10:35:10 +02:00
|
|
|
VcsBaseSubmitEditor *q) :
|
2008-12-02 12:01:29 +01:00
|
|
|
m_widget(editorWidget),
|
|
|
|
|
m_parameters(parameters),
|
2018-09-20 01:32:36 +03:00
|
|
|
m_file(new SubmitEditorFile(parameters, q))
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2015-01-22 13:54:05 +01:00
|
|
|
auto completer = new QCompleter(q);
|
2011-12-12 19:35:06 +01:00
|
|
|
completer->setCaseSensitivity(Qt::CaseSensitive);
|
2011-12-05 15:37:19 +01:00
|
|
|
completer->setModelSorting(QCompleter::CaseSensitivelySortedModel);
|
|
|
|
|
m_widget->descriptionEdit()->setCompleter(completer);
|
2011-12-12 19:35:06 +01:00
|
|
|
m_widget->descriptionEdit()->setCompletionLengthThreshold(4);
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2012-01-07 12:31:48 +01:00
|
|
|
VcsBaseSubmitEditor::VcsBaseSubmitEditor(const VcsBaseSubmitEditorParameters *parameters,
|
2012-01-07 03:35:54 +01:00
|
|
|
SubmitEditorWidget *editorWidget) :
|
2012-01-07 12:31:48 +01:00
|
|
|
d(new VcsBaseSubmitEditorPrivate(parameters, editorWidget, this))
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2011-09-15 13:42:38 +02:00
|
|
|
setWidget(d->m_widget);
|
2015-02-25 14:36:03 +02:00
|
|
|
document()->setPreferredDisplayName(QCoreApplication::translate("VCS", d->m_parameters->displayName));
|
2011-04-13 13:00:30 +02:00
|
|
|
|
2009-03-25 16:16:34 +01:00
|
|
|
// Message font according to settings
|
2015-02-03 23:52:10 +02:00
|
|
|
CompletingTextEdit *descriptionEdit = editorWidget->descriptionEdit();
|
2013-09-19 17:59:27 +02:00
|
|
|
const TextEditor::FontSettings fs = TextEditor::TextEditorSettings::fontSettings();
|
2013-08-09 15:09:47 +03:00
|
|
|
const QTextCharFormat tf = fs.toTextCharFormat(TextEditor::C_TEXT);
|
|
|
|
|
descriptionEdit->setFont(tf.font());
|
|
|
|
|
const QTextCharFormat selectionFormat = fs.toTextCharFormat(TextEditor::C_SELECTION);
|
2014-01-07 20:38:32 +01:00
|
|
|
QPalette pal;
|
2013-08-09 15:09:47 +03:00
|
|
|
pal.setColor(QPalette::Base, tf.background().color());
|
|
|
|
|
pal.setColor(QPalette::Text, tf.foreground().color());
|
|
|
|
|
pal.setColor(QPalette::Foreground, tf.foreground().color());
|
|
|
|
|
if (selectionFormat.background().style() != Qt::NoBrush)
|
|
|
|
|
pal.setColor(QPalette::Highlight, selectionFormat.background().color());
|
|
|
|
|
pal.setBrush(QPalette::HighlightedText, selectionFormat.foreground());
|
|
|
|
|
descriptionEdit->setPalette(pal);
|
2009-03-25 08:52:39 +01:00
|
|
|
|
2011-09-15 13:42:38 +02:00
|
|
|
d->m_file->setModified(false);
|
2008-12-02 12:01:29 +01:00
|
|
|
// We are always clean to prevent the editor manager from asking to save.
|
|
|
|
|
|
2015-02-16 14:44:29 +01:00
|
|
|
connect(d->m_widget, &SubmitEditorWidget::diffSelected,
|
|
|
|
|
this, &VcsBaseSubmitEditor::slotDiffSelectedVcsFiles);
|
|
|
|
|
connect(descriptionEdit, &QTextEdit::textChanged,
|
2016-01-15 15:35:17 +01:00
|
|
|
this, &VcsBaseSubmitEditor::fileContentsChanged);
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2012-01-07 12:31:48 +01:00
|
|
|
const CommonVcsSettings settings = VcsPlugin::instance()->settings();
|
2009-03-19 17:40:01 +01:00
|
|
|
// Add additional context menu settings
|
2009-03-20 10:16:18 +01:00
|
|
|
if (!settings.submitMessageCheckScript.isEmpty() || !settings.nickNameMailMap.isEmpty()) {
|
2015-01-22 13:54:05 +01:00
|
|
|
auto sep = new QAction(this);
|
2009-03-19 17:40:01 +01:00
|
|
|
sep->setSeparator(true);
|
2011-09-15 13:42:38 +02:00
|
|
|
d->m_widget->addDescriptionEditContextMenuAction(sep);
|
2009-03-19 17:40:01 +01:00
|
|
|
// Run check action
|
|
|
|
|
if (!settings.submitMessageCheckScript.isEmpty()) {
|
2015-01-22 13:54:05 +01:00
|
|
|
auto checkAction = new QAction(tr("Check Message"), this);
|
2015-02-16 14:44:29 +01:00
|
|
|
connect(checkAction, &QAction::triggered,
|
|
|
|
|
this, &VcsBaseSubmitEditor::slotCheckSubmitMessage);
|
2011-09-15 13:42:38 +02:00
|
|
|
d->m_widget->addDescriptionEditContextMenuAction(checkAction);
|
2009-03-19 17:40:01 +01:00
|
|
|
}
|
|
|
|
|
// Insert nick
|
2009-03-20 10:16:18 +01:00
|
|
|
if (!settings.nickNameMailMap.isEmpty()) {
|
2015-01-22 13:54:05 +01:00
|
|
|
auto insertAction = new QAction(tr("Insert Name..."), this);
|
2015-02-16 14:44:29 +01:00
|
|
|
connect(insertAction, &QAction::triggered, this, &VcsBaseSubmitEditor::slotInsertNickName);
|
2011-09-15 13:42:38 +02:00
|
|
|
d->m_widget->addDescriptionEditContextMenuAction(insertAction);
|
2009-03-19 17:40:01 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// Do we have user fields?
|
|
|
|
|
if (!settings.nickNameFieldListFile.isEmpty())
|
|
|
|
|
createUserFields(settings.nickNameFieldListFile);
|
2009-03-20 14:22:20 +01:00
|
|
|
|
|
|
|
|
// wrapping. etc
|
|
|
|
|
slotUpdateEditorSettings(settings);
|
2015-02-16 14:44:29 +01:00
|
|
|
connect(VcsPlugin::instance(), &VcsPlugin::settingsChanged,
|
|
|
|
|
this, &VcsBaseSubmitEditor::slotUpdateEditorSettings);
|
|
|
|
|
connect(Core::EditorManager::instance(), &Core::EditorManager::currentEditorChanged,
|
|
|
|
|
this, [this]() {
|
|
|
|
|
if (Core::EditorManager::currentEditor() == this)
|
|
|
|
|
updateFileModel();
|
2015-02-24 12:51:17 +01:00
|
|
|
});
|
2015-02-16 14:44:29 +01:00
|
|
|
connect(qApp, &QApplication::applicationStateChanged,
|
|
|
|
|
this, [this](Qt::ApplicationState state) {
|
|
|
|
|
if (state == Qt::ApplicationActive)
|
|
|
|
|
updateFileModel();
|
2015-02-24 12:51:17 +01:00
|
|
|
});
|
2009-03-20 14:22:20 +01:00
|
|
|
|
2015-01-22 13:54:05 +01:00
|
|
|
auto aggregate = new Aggregation::Aggregate;
|
2014-01-13 16:17:34 +01:00
|
|
|
aggregate->add(new Core::BaseTextFind(descriptionEdit));
|
2008-12-02 12:01:29 +01:00
|
|
|
aggregate->add(this);
|
|
|
|
|
}
|
|
|
|
|
|
2012-01-07 12:31:48 +01:00
|
|
|
VcsBaseSubmitEditor::~VcsBaseSubmitEditor()
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2011-09-15 13:42:38 +02:00
|
|
|
delete d->m_toolWidget;
|
|
|
|
|
delete d->m_widget;
|
|
|
|
|
delete d;
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2012-01-07 12:31:48 +01:00
|
|
|
void VcsBaseSubmitEditor::slotUpdateEditorSettings(const CommonVcsSettings &s)
|
2009-03-20 14:22:20 +01:00
|
|
|
{
|
|
|
|
|
setLineWrapWidth(s.lineWrapWidth);
|
|
|
|
|
setLineWrap(s.lineWrap);
|
|
|
|
|
}
|
|
|
|
|
|
2009-03-23 12:03:20 +01:00
|
|
|
// Return a trimmed list of non-empty field texts
|
|
|
|
|
static inline QStringList fieldTexts(const QString &fileContents)
|
|
|
|
|
{
|
|
|
|
|
QStringList rc;
|
|
|
|
|
const QStringList rawFields = fileContents.trimmed().split(QLatin1Char('\n'));
|
2012-01-07 03:35:54 +01:00
|
|
|
foreach (const QString &field, rawFields) {
|
2009-03-23 12:03:20 +01:00
|
|
|
const QString trimmedField = field.trimmed();
|
|
|
|
|
if (!trimmedField.isEmpty())
|
|
|
|
|
rc.push_back(trimmedField);
|
|
|
|
|
}
|
|
|
|
|
return rc;
|
|
|
|
|
}
|
|
|
|
|
|
2012-01-07 12:31:48 +01:00
|
|
|
void VcsBaseSubmitEditor::createUserFields(const QString &fieldConfigFile)
|
2009-03-19 17:40:01 +01:00
|
|
|
{
|
2015-02-03 23:52:10 +02:00
|
|
|
FileReader reader;
|
2012-01-24 15:36:40 +01:00
|
|
|
if (!reader.fetch(fieldConfigFile, QIODevice::Text, Core::ICore::mainWindow()))
|
2009-03-19 17:40:01 +01:00
|
|
|
return;
|
|
|
|
|
// Parse into fields
|
2011-03-30 15:15:15 +02:00
|
|
|
const QStringList fields = fieldTexts(QString::fromUtf8(reader.data()));
|
2009-03-19 17:40:01 +01:00
|
|
|
if (fields.empty())
|
|
|
|
|
return;
|
|
|
|
|
// Create a completer on user names
|
2012-01-07 12:31:48 +01:00
|
|
|
const QStandardItemModel *nickNameModel = VcsPlugin::instance()->nickNameModel();
|
2015-01-22 13:54:05 +01:00
|
|
|
auto completer = new QCompleter(NickNameDialog::nickNameList(nickNameModel), this);
|
2009-03-23 12:03:20 +01:00
|
|
|
|
2015-01-22 13:54:05 +01:00
|
|
|
auto fieldWidget = new SubmitFieldWidget;
|
2015-02-16 14:44:29 +01:00
|
|
|
connect(fieldWidget, &SubmitFieldWidget::browseButtonClicked,
|
|
|
|
|
this, &VcsBaseSubmitEditor::slotSetFieldNickName);
|
2009-03-23 12:03:20 +01:00
|
|
|
fieldWidget->setCompleter(completer);
|
|
|
|
|
fieldWidget->setAllowDuplicateFields(true);
|
|
|
|
|
fieldWidget->setHasBrowseButton(true);
|
|
|
|
|
fieldWidget->setFields(fields);
|
2011-09-15 13:42:38 +02:00
|
|
|
d->m_widget->addSubmitFieldWidget(fieldWidget);
|
2009-03-19 17:40:01 +01:00
|
|
|
}
|
|
|
|
|
|
2012-01-07 12:31:48 +01:00
|
|
|
void VcsBaseSubmitEditor::registerActions(QAction *editorUndoAction, QAction *editorRedoAction,
|
2012-01-07 03:35:54 +01:00
|
|
|
QAction *submitAction, QAction *diffAction)
|
2009-01-13 14:06:42 +01:00
|
|
|
{
|
2011-09-15 13:42:38 +02:00
|
|
|
d->m_widget->registerActions(editorUndoAction, editorRedoAction, submitAction, diffAction);
|
|
|
|
|
d->m_diffAction = diffAction;
|
|
|
|
|
d->m_submitAction = submitAction;
|
2009-01-13 14:06:42 +01:00
|
|
|
}
|
|
|
|
|
|
2012-01-07 12:31:48 +01:00
|
|
|
QAbstractItemView::SelectionMode VcsBaseSubmitEditor::fileListSelectionMode() const
|
2009-01-13 10:06:06 +01:00
|
|
|
{
|
2011-09-15 13:42:38 +02:00
|
|
|
return d->m_widget->fileListSelectionMode();
|
2009-01-13 10:06:06 +01:00
|
|
|
}
|
|
|
|
|
|
2012-01-07 12:31:48 +01:00
|
|
|
void VcsBaseSubmitEditor::setFileListSelectionMode(QAbstractItemView::SelectionMode sm)
|
2009-01-13 10:06:06 +01:00
|
|
|
{
|
2011-09-15 13:42:38 +02:00
|
|
|
d->m_widget->setFileListSelectionMode(sm);
|
2009-01-13 10:06:06 +01:00
|
|
|
}
|
|
|
|
|
|
2012-01-07 12:31:48 +01:00
|
|
|
bool VcsBaseSubmitEditor::isEmptyFileListEnabled() const
|
2010-08-23 12:15:48 +02:00
|
|
|
{
|
2011-09-15 13:42:38 +02:00
|
|
|
return d->m_widget->isEmptyFileListEnabled();
|
2010-08-23 12:15:48 +02:00
|
|
|
}
|
|
|
|
|
|
2012-01-07 12:31:48 +01:00
|
|
|
void VcsBaseSubmitEditor::setEmptyFileListEnabled(bool e)
|
2010-08-23 12:15:48 +02:00
|
|
|
{
|
2011-09-15 13:42:38 +02:00
|
|
|
d->m_widget->setEmptyFileListEnabled(e);
|
2010-08-23 12:15:48 +02:00
|
|
|
}
|
|
|
|
|
|
2012-01-07 12:31:48 +01:00
|
|
|
bool VcsBaseSubmitEditor::lineWrap() const
|
2009-03-20 14:22:20 +01:00
|
|
|
{
|
2011-09-15 13:42:38 +02:00
|
|
|
return d->m_widget->lineWrap();
|
2009-03-20 14:22:20 +01:00
|
|
|
}
|
|
|
|
|
|
2012-01-07 12:31:48 +01:00
|
|
|
void VcsBaseSubmitEditor::setLineWrap(bool w)
|
2009-03-20 14:22:20 +01:00
|
|
|
{
|
2011-09-15 13:42:38 +02:00
|
|
|
d->m_widget->setLineWrap(w);
|
2009-03-20 14:22:20 +01:00
|
|
|
}
|
|
|
|
|
|
2012-01-07 12:31:48 +01:00
|
|
|
int VcsBaseSubmitEditor::lineWrapWidth() const
|
2009-03-20 14:22:20 +01:00
|
|
|
{
|
2011-09-15 13:42:38 +02:00
|
|
|
return d->m_widget->lineWrapWidth();
|
2009-03-20 14:22:20 +01:00
|
|
|
}
|
|
|
|
|
|
2012-01-07 12:31:48 +01:00
|
|
|
void VcsBaseSubmitEditor::setLineWrapWidth(int w)
|
2009-03-20 14:22:20 +01:00
|
|
|
{
|
2011-09-15 13:42:38 +02:00
|
|
|
d->m_widget->setLineWrapWidth(w);
|
2009-03-20 14:22:20 +01:00
|
|
|
}
|
|
|
|
|
|
2018-09-25 20:47:14 +03:00
|
|
|
Core::IDocument *VcsBaseSubmitEditor::document() const
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2011-09-15 13:42:38 +02:00
|
|
|
return d->m_file;
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2012-01-07 12:31:48 +01:00
|
|
|
QString VcsBaseSubmitEditor::checkScriptWorkingDirectory() const
|
2009-12-14 10:56:50 +01:00
|
|
|
{
|
2011-09-15 13:42:38 +02:00
|
|
|
return d->m_checkScriptWorkingDirectory;
|
2009-12-14 10:56:50 +01:00
|
|
|
}
|
|
|
|
|
|
2012-01-07 12:31:48 +01:00
|
|
|
void VcsBaseSubmitEditor::setCheckScriptWorkingDirectory(const QString &s)
|
2009-12-14 10:56:50 +01:00
|
|
|
{
|
2011-09-15 13:42:38 +02:00
|
|
|
d->m_checkScriptWorkingDirectory = s;
|
2009-12-14 10:56:50 +01:00
|
|
|
}
|
|
|
|
|
|
2008-12-02 17:05:53 +01:00
|
|
|
static QToolBar *createToolBar(const QWidget *someWidget, QAction *submitAction, QAction *diffAction)
|
|
|
|
|
{
|
|
|
|
|
// Create
|
2015-01-22 13:54:05 +01:00
|
|
|
auto toolBar = new QToolBar;
|
2008-12-02 17:05:53 +01:00
|
|
|
toolBar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
|
|
|
|
|
const int size = someWidget->style()->pixelMetric(QStyle::PM_SmallIconSize);
|
|
|
|
|
toolBar->setIconSize(QSize(size, size));
|
|
|
|
|
toolBar->addSeparator();
|
|
|
|
|
|
|
|
|
|
if (submitAction)
|
|
|
|
|
toolBar->addAction(submitAction);
|
|
|
|
|
if (diffAction)
|
|
|
|
|
toolBar->addAction(diffAction);
|
|
|
|
|
return toolBar;
|
|
|
|
|
}
|
|
|
|
|
|
2012-01-07 12:31:48 +01:00
|
|
|
QWidget *VcsBaseSubmitEditor::toolBar()
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2008-12-02 17:05:53 +01:00
|
|
|
if (!wantToolBar)
|
2018-09-20 01:32:36 +03:00
|
|
|
return nullptr;
|
2008-12-02 17:05:53 +01:00
|
|
|
|
2011-09-15 13:42:38 +02:00
|
|
|
if (d->m_toolWidget)
|
|
|
|
|
return d->m_toolWidget;
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2011-09-15 13:42:38 +02:00
|
|
|
if (!d->m_diffAction && !d->m_submitAction)
|
2018-09-20 01:32:36 +03:00
|
|
|
return nullptr;
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
|
// Create
|
2011-09-15 13:42:38 +02:00
|
|
|
d->m_toolWidget = createToolBar(d->m_widget, d->m_submitAction, d->m_diffAction);
|
|
|
|
|
return d->m_toolWidget;
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2012-01-07 12:31:48 +01:00
|
|
|
QStringList VcsBaseSubmitEditor::checkedFiles() const
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2011-09-15 13:42:38 +02:00
|
|
|
return d->m_widget->checkedFiles();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2015-03-09 17:10:25 +01:00
|
|
|
void VcsBaseSubmitEditor::setFileModel(SubmitFileModel *model)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2013-01-07 22:15:03 +02:00
|
|
|
QTC_ASSERT(model, return);
|
2016-01-05 23:40:21 +02:00
|
|
|
SubmitFileModel *oldModel = d->m_widget->fileModel();
|
2017-06-29 23:55:02 +03:00
|
|
|
QList<int> selected;
|
|
|
|
|
if (oldModel) {
|
2013-01-07 22:15:03 +02:00
|
|
|
model->updateSelections(oldModel);
|
2017-06-29 23:55:02 +03:00
|
|
|
selected = d->m_widget->selectedRows();
|
|
|
|
|
}
|
2013-01-07 22:15:03 +02:00
|
|
|
d->m_widget->setFileModel(model);
|
2016-01-05 23:40:21 +02:00
|
|
|
delete oldModel;
|
2017-06-29 23:55:02 +03:00
|
|
|
if (!selected.isEmpty())
|
|
|
|
|
d->m_widget->setSelectedRows(selected);
|
2011-12-05 15:37:19 +01:00
|
|
|
|
|
|
|
|
QSet<QString> uniqueSymbols;
|
2014-09-15 00:12:27 +02:00
|
|
|
const CPlusPlus::Snapshot cppSnapShot = CppTools::CppModelManager::instance()->snapshot();
|
2011-12-05 15:37:19 +01:00
|
|
|
|
|
|
|
|
// Iterate over the files and get interesting symbols
|
2013-01-07 22:15:03 +02:00
|
|
|
for (int row = 0; row < model->rowCount(); ++row) {
|
2015-03-09 17:10:25 +01:00
|
|
|
const QFileInfo fileInfo(model->repositoryRoot(), model->file(row));
|
2011-12-05 15:37:19 +01:00
|
|
|
|
|
|
|
|
// Add file name
|
|
|
|
|
uniqueSymbols.insert(fileInfo.fileName());
|
|
|
|
|
|
|
|
|
|
const QString filePath = fileInfo.absoluteFilePath();
|
|
|
|
|
// Add symbols from the C++ code model
|
|
|
|
|
const CPlusPlus::Document::Ptr doc = cppSnapShot.document(filePath);
|
2018-09-20 01:32:36 +03:00
|
|
|
if (!doc.isNull() && doc->control()) {
|
2011-12-05 15:37:19 +01:00
|
|
|
const CPlusPlus::Control *ctrl = doc->control();
|
|
|
|
|
CPlusPlus::Symbol **symPtr = ctrl->firstSymbol(); // Read-only
|
|
|
|
|
while (symPtr != ctrl->lastSymbol()) {
|
|
|
|
|
const CPlusPlus::Symbol *sym = *symPtr;
|
|
|
|
|
|
2011-12-12 19:35:06 +01:00
|
|
|
const CPlusPlus::Identifier *symId = sym->identifier();
|
|
|
|
|
// Add any class, function or namespace identifiers
|
|
|
|
|
if ((sym->isClass() || sym->isFunction() || sym->isNamespace())
|
2018-09-20 01:32:36 +03:00
|
|
|
&& (symId && acceptsWordForCompletion(symId->chars())))
|
2011-12-12 19:35:06 +01:00
|
|
|
{
|
2012-01-31 10:57:10 +01:00
|
|
|
uniqueSymbols.insert(QString::fromUtf8(symId->chars()));
|
2011-12-05 15:37:19 +01:00
|
|
|
}
|
2011-12-12 19:35:06 +01:00
|
|
|
|
|
|
|
|
// Handle specific case : get "Foo" in "void Foo::function() {}"
|
|
|
|
|
if (sym->isFunction() && !sym->asFunction()->isDeclaration()) {
|
|
|
|
|
const char *className = belongingClassName(sym->asFunction());
|
|
|
|
|
if (acceptsWordForCompletion(className))
|
2012-01-31 10:57:10 +01:00
|
|
|
uniqueSymbols.insert(QString::fromUtf8(className));
|
2011-12-05 15:37:19 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
++symPtr;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Populate completer with symbols
|
|
|
|
|
if (!uniqueSymbols.isEmpty()) {
|
|
|
|
|
QCompleter *completer = d->m_widget->descriptionEdit()->completer();
|
|
|
|
|
QStringList symbolsList = uniqueSymbols.toList();
|
|
|
|
|
symbolsList.sort();
|
|
|
|
|
completer->setModel(new QStringListModel(symbolsList, completer));
|
|
|
|
|
}
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2013-01-02 22:19:04 +02:00
|
|
|
SubmitFileModel *VcsBaseSubmitEditor::fileModel() const
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2011-09-15 13:42:38 +02:00
|
|
|
return d->m_widget->fileModel();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2013-01-11 10:45:00 +02:00
|
|
|
QStringList VcsBaseSubmitEditor::rowsToFiles(const QList<int> &rows) const
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2013-01-11 10:45:00 +02:00
|
|
|
if (rows.empty())
|
|
|
|
|
return QStringList();
|
|
|
|
|
|
|
|
|
|
QStringList rc;
|
|
|
|
|
const SubmitFileModel *model = fileModel();
|
|
|
|
|
const int count = rows.size();
|
|
|
|
|
for (int i = 0; i < count; i++)
|
|
|
|
|
rc.push_back(model->file(rows.at(i)));
|
|
|
|
|
return rc;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VcsBaseSubmitEditor::slotDiffSelectedVcsFiles(const QList<int> &rawList)
|
|
|
|
|
{
|
|
|
|
|
if (d->m_parameters->diffType == VcsBaseSubmitEditorParameters::DiffRows)
|
2015-03-04 14:56:56 +01:00
|
|
|
emit diffSelectedRows(rawList);
|
2013-01-11 10:45:00 +02:00
|
|
|
else
|
|
|
|
|
emit diffSelectedFiles(rowsToFiles(rawList));
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2012-01-07 12:31:48 +01:00
|
|
|
QByteArray VcsBaseSubmitEditor::fileContents() const
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2015-02-20 09:54:49 +01:00
|
|
|
return description().toLocal8Bit();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2013-07-15 15:14:10 +02:00
|
|
|
bool VcsBaseSubmitEditor::setFileContents(const QByteArray &contents)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2015-02-20 09:54:49 +01:00
|
|
|
setDescription(QString::fromUtf8(contents));
|
2008-12-02 12:01:29 +01:00
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-20 09:54:49 +01:00
|
|
|
QString VcsBaseSubmitEditor::description() const
|
|
|
|
|
{
|
|
|
|
|
return d->m_widget->descriptionText();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VcsBaseSubmitEditor::setDescription(const QString &text)
|
|
|
|
|
{
|
|
|
|
|
d->m_widget->setDescriptionText(text);
|
|
|
|
|
}
|
|
|
|
|
|
2012-06-15 07:43:09 +03:00
|
|
|
bool VcsBaseSubmitEditor::isDescriptionMandatory() const
|
|
|
|
|
{
|
|
|
|
|
return d->m_widget->isDescriptionMandatory();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VcsBaseSubmitEditor::setDescriptionMandatory(bool v)
|
|
|
|
|
{
|
|
|
|
|
d->m_widget->setDescriptionMandatory(v);
|
|
|
|
|
}
|
|
|
|
|
|
2009-03-19 17:40:01 +01:00
|
|
|
enum { checkDialogMinimumWidth = 500 };
|
|
|
|
|
|
2012-01-07 12:31:48 +01:00
|
|
|
VcsBaseSubmitEditor::PromptSubmitResult
|
|
|
|
|
VcsBaseSubmitEditor::promptSubmit(const QString &title,
|
2009-03-20 10:16:18 +01:00
|
|
|
const QString &question,
|
|
|
|
|
const QString &checkFailureQuestion,
|
2009-06-19 16:34:38 +02:00
|
|
|
bool *promptSetting,
|
2010-11-23 14:40:52 +01:00
|
|
|
bool forcePrompt,
|
2013-04-18 12:06:43 +02:00
|
|
|
bool canCommitOnFailure)
|
2009-03-19 17:40:01 +01:00
|
|
|
{
|
2018-09-20 01:32:36 +03:00
|
|
|
auto submitWidget = static_cast<SubmitEditorWidget *>(this->widget());
|
2010-11-23 14:40:52 +01:00
|
|
|
|
2013-05-31 12:52:53 +02:00
|
|
|
Core::EditorManager::activateEditor(this, Core::EditorManager::IgnoreNavigationHistory);
|
2010-10-06 18:08:30 +02:00
|
|
|
|
2014-06-22 12:55:14 +03:00
|
|
|
if (!submitWidget->isEnabled())
|
|
|
|
|
return SubmitDiscarded;
|
|
|
|
|
|
2009-03-19 17:40:01 +01:00
|
|
|
QString errorMessage;
|
|
|
|
|
QMessageBox::StandardButton answer = QMessageBox::Yes;
|
|
|
|
|
|
2009-06-19 16:34:38 +02:00
|
|
|
const bool prompt = forcePrompt || *promptSetting;
|
2009-03-20 10:16:18 +01:00
|
|
|
|
2012-01-24 15:36:40 +01:00
|
|
|
QWidget *parent = Core::ICore::mainWindow();
|
2009-03-19 17:40:01 +01:00
|
|
|
// Pop up a message depending on whether the check succeeded and the
|
|
|
|
|
// user wants to be prompted
|
2010-11-23 14:40:52 +01:00
|
|
|
bool canCommit = checkSubmitMessage(&errorMessage) && submitWidget->canSubmit();
|
|
|
|
|
if (canCommit) {
|
2009-03-19 17:40:01 +01:00
|
|
|
// Check ok, do prompt?
|
2009-03-20 10:16:18 +01:00
|
|
|
if (prompt) {
|
2009-06-19 16:34:38 +02:00
|
|
|
// Provide check box to turn off prompt ONLY if it was not forced
|
|
|
|
|
if (*promptSetting && !forcePrompt) {
|
|
|
|
|
const QDialogButtonBox::StandardButton danswer =
|
2015-02-03 23:52:10 +02:00
|
|
|
CheckableMessageBox::question(parent, title, question,
|
2009-06-19 16:34:38 +02:00
|
|
|
tr("Prompt to submit"), promptSetting,
|
2010-10-05 17:57:50 +02:00
|
|
|
QDialogButtonBox::Yes|QDialogButtonBox::No|
|
|
|
|
|
QDialogButtonBox::Cancel,
|
2009-06-19 16:34:38 +02:00
|
|
|
QDialogButtonBox::Yes);
|
2015-02-03 23:52:10 +02:00
|
|
|
answer = CheckableMessageBox::dialogButtonBoxToMessageBoxButton(danswer);
|
2009-06-19 16:34:38 +02:00
|
|
|
} else {
|
|
|
|
|
answer = QMessageBox::question(parent, title, question,
|
|
|
|
|
QMessageBox::Yes|QMessageBox::No|QMessageBox::Cancel,
|
|
|
|
|
QMessageBox::Yes);
|
|
|
|
|
}
|
2009-03-19 17:40:01 +01:00
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
// Check failed.
|
2014-08-07 16:45:41 +02:00
|
|
|
QMessageBox::StandardButtons buttons;
|
|
|
|
|
if (canCommitOnFailure)
|
|
|
|
|
buttons = QMessageBox::Yes|QMessageBox::No|QMessageBox::Cancel;
|
|
|
|
|
else
|
|
|
|
|
buttons = QMessageBox::Yes|QMessageBox::No;
|
2009-03-19 17:40:01 +01:00
|
|
|
QMessageBox msgBox(QMessageBox::Question, title, checkFailureQuestion,
|
2014-08-07 16:45:41 +02:00
|
|
|
buttons, parent);
|
2009-03-19 17:40:01 +01:00
|
|
|
msgBox.setDefaultButton(QMessageBox::Cancel);
|
|
|
|
|
msgBox.setInformativeText(errorMessage);
|
|
|
|
|
msgBox.setMinimumWidth(checkDialogMinimumWidth);
|
|
|
|
|
answer = static_cast<QMessageBox::StandardButton>(msgBox.exec());
|
|
|
|
|
}
|
2010-11-23 14:40:52 +01:00
|
|
|
if (!canCommit && !canCommitOnFailure) {
|
|
|
|
|
switch (answer) {
|
|
|
|
|
case QMessageBox::No:
|
2012-01-07 03:35:54 +01:00
|
|
|
return SubmitDiscarded;
|
2010-11-23 14:40:52 +01:00
|
|
|
case QMessageBox::Yes:
|
2012-01-07 03:35:54 +01:00
|
|
|
return SubmitCanceled;
|
2010-11-23 14:40:52 +01:00
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
switch (answer) {
|
|
|
|
|
case QMessageBox::No:
|
|
|
|
|
return SubmitDiscarded;
|
|
|
|
|
case QMessageBox::Yes:
|
|
|
|
|
return SubmitConfirmed;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
2009-03-19 17:40:01 +01:00
|
|
|
}
|
2010-11-23 14:40:52 +01:00
|
|
|
|
2010-10-05 17:57:50 +02:00
|
|
|
return SubmitCanceled;
|
2009-03-19 17:40:01 +01:00
|
|
|
}
|
|
|
|
|
|
2012-01-07 12:31:48 +01:00
|
|
|
QString VcsBaseSubmitEditor::promptForNickName()
|
2009-03-19 17:40:01 +01:00
|
|
|
{
|
2011-09-15 13:42:38 +02:00
|
|
|
if (!d->m_nickNameDialog)
|
2012-01-07 12:31:48 +01:00
|
|
|
d->m_nickNameDialog = new NickNameDialog(VcsPlugin::instance()->nickNameModel(), d->m_widget);
|
2011-09-15 13:42:38 +02:00
|
|
|
if (d->m_nickNameDialog->exec() == QDialog::Accepted)
|
|
|
|
|
return d->m_nickNameDialog->nickName();
|
2009-03-19 17:40:01 +01:00
|
|
|
return QString();
|
|
|
|
|
}
|
|
|
|
|
|
2012-01-07 12:31:48 +01:00
|
|
|
void VcsBaseSubmitEditor::slotInsertNickName()
|
2009-03-19 17:40:01 +01:00
|
|
|
{
|
|
|
|
|
const QString nick = promptForNickName();
|
|
|
|
|
if (!nick.isEmpty())
|
2011-09-15 13:42:38 +02:00
|
|
|
d->m_widget->descriptionEdit()->textCursor().insertText(nick);
|
2009-03-19 17:40:01 +01:00
|
|
|
}
|
|
|
|
|
|
2012-01-07 12:31:48 +01:00
|
|
|
void VcsBaseSubmitEditor::slotSetFieldNickName(int i)
|
2009-03-19 17:40:01 +01:00
|
|
|
{
|
2012-01-07 03:35:54 +01:00
|
|
|
if (SubmitFieldWidget *sfw = d->m_widget->submitFieldWidgets().front()) {
|
2009-03-23 12:03:20 +01:00
|
|
|
const QString nick = promptForNickName();
|
|
|
|
|
if (!nick.isEmpty())
|
|
|
|
|
sfw->setFieldValue(i, nick);
|
|
|
|
|
}
|
2009-03-19 17:40:01 +01:00
|
|
|
}
|
|
|
|
|
|
2012-01-07 12:31:48 +01:00
|
|
|
void VcsBaseSubmitEditor::slotCheckSubmitMessage()
|
2009-03-19 17:40:01 +01:00
|
|
|
{
|
|
|
|
|
QString errorMessage;
|
|
|
|
|
if (!checkSubmitMessage(&errorMessage)) {
|
2010-09-21 17:17:54 +02:00
|
|
|
QMessageBox msgBox(QMessageBox::Warning, tr("Submit Message Check Failed"),
|
2011-09-15 13:42:38 +02:00
|
|
|
errorMessage, QMessageBox::Ok, d->m_widget);
|
2009-03-19 17:40:01 +01:00
|
|
|
msgBox.setMinimumWidth(checkDialogMinimumWidth);
|
|
|
|
|
msgBox.exec();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-01-07 12:31:48 +01:00
|
|
|
bool VcsBaseSubmitEditor::checkSubmitMessage(QString *errorMessage) const
|
2009-03-19 17:40:01 +01:00
|
|
|
{
|
|
|
|
|
const QString checkScript = submitMessageCheckScript();
|
|
|
|
|
if (checkScript.isEmpty())
|
|
|
|
|
return true;
|
2009-03-20 10:16:18 +01:00
|
|
|
QApplication::setOverrideCursor(Qt::WaitCursor);
|
|
|
|
|
const bool rc = runSubmitMessageCheckScript(checkScript, errorMessage);
|
|
|
|
|
QApplication::restoreOverrideCursor();
|
|
|
|
|
return rc;
|
|
|
|
|
}
|
|
|
|
|
|
2009-12-14 10:56:50 +01:00
|
|
|
static inline QString msgCheckScript(const QString &workingDir, const QString &cmd)
|
|
|
|
|
{
|
2010-07-05 09:52:32 +02:00
|
|
|
const QString nativeCmd = QDir::toNativeSeparators(cmd);
|
2009-12-14 10:56:50 +01:00
|
|
|
return workingDir.isEmpty() ?
|
2012-01-07 12:31:48 +01:00
|
|
|
VcsBaseSubmitEditor::tr("Executing %1").arg(nativeCmd) :
|
|
|
|
|
VcsBaseSubmitEditor::tr("Executing [%1] %2").
|
2010-07-05 09:52:32 +02:00
|
|
|
arg(QDir::toNativeSeparators(workingDir), nativeCmd);
|
2009-12-14 10:56:50 +01:00
|
|
|
}
|
|
|
|
|
|
2012-01-07 12:31:48 +01:00
|
|
|
bool VcsBaseSubmitEditor::runSubmitMessageCheckScript(const QString &checkScript, QString *errorMessage) const
|
2009-03-20 10:16:18 +01:00
|
|
|
{
|
2009-03-19 17:40:01 +01:00
|
|
|
// Write out message
|
2017-01-19 16:44:22 +01:00
|
|
|
TempFileSaver saver(Utils::TemporaryDirectory::masterDirectoryPath() + "/msgXXXXXX.txt");
|
2011-10-21 09:30:56 +00:00
|
|
|
saver.write(fileContents());
|
2011-03-30 15:15:15 +02:00
|
|
|
if (!saver.finalize(errorMessage))
|
2009-03-19 17:40:01 +01:00
|
|
|
return false;
|
|
|
|
|
// Run check process
|
2015-01-19 13:22:20 +01:00
|
|
|
VcsOutputWindow::appendShellCommandLine(msgCheckScript(d->m_checkScriptWorkingDirectory,
|
|
|
|
|
checkScript));
|
2009-03-19 17:40:01 +01:00
|
|
|
QProcess checkProcess;
|
2011-09-15 13:42:38 +02:00
|
|
|
if (!d->m_checkScriptWorkingDirectory.isEmpty())
|
|
|
|
|
checkProcess.setWorkingDirectory(d->m_checkScriptWorkingDirectory);
|
2011-03-30 15:15:15 +02:00
|
|
|
checkProcess.start(checkScript, QStringList(saver.fileName()));
|
2009-12-14 10:56:50 +01:00
|
|
|
checkProcess.closeWriteChannel();
|
2009-03-19 17:40:01 +01:00
|
|
|
if (!checkProcess.waitForStarted()) {
|
2014-04-17 14:09:47 +02:00
|
|
|
*errorMessage = tr("The check script \"%1\" could not be started: %2").arg(checkScript, checkProcess.errorString());
|
2009-03-19 17:40:01 +01:00
|
|
|
return false;
|
|
|
|
|
}
|
2010-03-01 10:06:05 +01:00
|
|
|
QByteArray stdOutData;
|
|
|
|
|
QByteArray stdErrData;
|
2015-04-14 22:30:46 +03:00
|
|
|
if (!SynchronousProcess::readDataFromProcess(checkProcess, 30, &stdOutData, &stdErrData, false)) {
|
2012-01-07 03:35:54 +01:00
|
|
|
SynchronousProcess::stopProcess(checkProcess);
|
2014-04-17 14:09:47 +02:00
|
|
|
*errorMessage = tr("The check script \"%1\" timed out.").
|
2010-07-05 09:52:32 +02:00
|
|
|
arg(QDir::toNativeSeparators(checkScript));
|
2009-03-19 17:40:01 +01:00
|
|
|
return false;
|
2009-12-11 16:43:39 +01:00
|
|
|
}
|
2009-12-14 10:56:50 +01:00
|
|
|
if (checkProcess.exitStatus() != QProcess::NormalExit) {
|
2014-04-17 14:09:47 +02:00
|
|
|
*errorMessage = tr("The check script \"%1\" crashed.").
|
2010-07-05 09:52:32 +02:00
|
|
|
arg(QDir::toNativeSeparators(checkScript));
|
2009-12-14 10:56:50 +01:00
|
|
|
return false;
|
|
|
|
|
}
|
2010-03-01 10:06:05 +01:00
|
|
|
if (!stdOutData.isEmpty())
|
2014-08-26 00:02:47 +02:00
|
|
|
VcsOutputWindow::appendSilently(QString::fromLocal8Bit(stdOutData));
|
2010-03-01 10:06:05 +01:00
|
|
|
const QString stdErr = QString::fromLocal8Bit(stdErrData);
|
2009-12-14 10:56:50 +01:00
|
|
|
if (!stdErr.isEmpty())
|
2014-08-26 00:02:47 +02:00
|
|
|
VcsOutputWindow::appendSilently(stdErr);
|
2009-03-19 17:40:01 +01:00
|
|
|
const int exitCode = checkProcess.exitCode();
|
|
|
|
|
if (exitCode != 0) {
|
2010-07-05 09:52:32 +02:00
|
|
|
const QString exMessage = tr("The check script returned exit code %1.").
|
|
|
|
|
arg(exitCode);
|
2014-08-26 00:02:47 +02:00
|
|
|
VcsOutputWindow::appendError(exMessage);
|
2009-12-14 10:56:50 +01:00
|
|
|
*errorMessage = stdErr;
|
2009-03-19 17:40:01 +01:00
|
|
|
if (errorMessage->isEmpty())
|
2009-12-14 10:56:50 +01:00
|
|
|
*errorMessage = exMessage;
|
2009-03-19 17:40:01 +01:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2012-01-07 12:31:48 +01:00
|
|
|
QIcon VcsBaseSubmitEditor::diffIcon()
|
2008-12-02 17:05:53 +01:00
|
|
|
{
|
2017-10-06 17:58:08 +02:00
|
|
|
using namespace Utils;
|
|
|
|
|
return Icon({
|
|
|
|
|
{":/vcsbase/images/diff_documents.png", Theme::PanelTextColorDark},
|
|
|
|
|
{":/vcsbase/images/diff_arrows.png", Theme::IconsStopColor}
|
|
|
|
|
}, Icon::Tint).icon();
|
2008-12-02 17:05:53 +01:00
|
|
|
}
|
|
|
|
|
|
2012-01-07 12:31:48 +01:00
|
|
|
QIcon VcsBaseSubmitEditor::submitIcon()
|
2008-12-02 17:05:53 +01:00
|
|
|
{
|
2017-10-06 17:58:08 +02:00
|
|
|
using namespace Utils;
|
|
|
|
|
return Icon({
|
|
|
|
|
{":/vcsbase/images/submit_db.png", Theme::PanelTextColorDark},
|
|
|
|
|
{":/vcsbase/images/submit_arrow.png", Theme::IconsRunColor}
|
|
|
|
|
}, Icon::Tint | Icon::PunchEdges).icon();
|
2008-12-02 17:05:53 +01:00
|
|
|
}
|
|
|
|
|
|
2009-07-21 11:14:48 +02:00
|
|
|
// Reduce a list of untracked files reported by a VCS down to the files
|
|
|
|
|
// that are actually part of the current project(s).
|
2015-02-20 11:35:36 +01:00
|
|
|
void VcsBaseSubmitEditor::filterUntrackedFilesOfProject(const QString &repositoryDirectory,
|
|
|
|
|
QStringList *untrackedFiles)
|
2009-07-21 11:14:48 +02:00
|
|
|
{
|
|
|
|
|
const QDir repoDir(repositoryDirectory);
|
|
|
|
|
for (QStringList::iterator it = untrackedFiles->begin(); it != untrackedFiles->end(); ) {
|
2015-02-20 11:35:36 +01:00
|
|
|
const QString path = repoDir.absoluteFilePath(*it);
|
2017-06-14 16:38:42 +03:00
|
|
|
if (ProjectExplorer::SessionManager::projectForFile(FileName::fromString(path)))
|
2009-07-21 11:14:48 +02:00
|
|
|
++it;
|
Remove braces for single lines of conditions
#!/usr/bin/env ruby
Dir.glob('**/*.cpp') { |file|
# skip ast (excluding paste, astpath, and canv'ast'imer)
next if file =~ /ast[^eip]|keywords\.|qualifiers|preprocessor|names.cpp/i
s = File.read(file)
next if s.include?('qlalr')
orig = s.dup
s.gsub!(/\n *if [^\n]*{\n[^\n]*\n\s+}(\s+else if [^\n]* {\n[^\n]*\n\s+})*(\s+else {\n[^\n]*\n\s+})?\n/m) { |m|
res = $&
if res =~ /^\s*(\/\/|[A-Z_]{3,})/ # C++ comment or macro (Q_UNUSED, SDEBUG), do not touch braces
res
else
res.gsub!('} else', 'else')
res.gsub!(/\n +} *\n/m, "\n")
res.gsub(/ *{$/, '')
end
}
s.gsub!(/ *$/, '')
File.open(file, 'wb').write(s) if s != orig
}
Change-Id: I3b30ee60df0986f66c02132c65fc38a3fbb6bbdc
Reviewed-by: hjk <qthjk@ovi.com>
2013-01-08 03:32:53 +02:00
|
|
|
else
|
2009-07-21 11:14:48 +02:00
|
|
|
it = untrackedFiles->erase(it);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-01-07 12:31:48 +01:00
|
|
|
} // namespace VcsBase
|