forked from qt-creator/qt-creator
Find: Remember the find flags per completer entry
Replace the QStringListModel used by the completer by a special model storing a struct of the text and find flags. On activating the completer, the flags are applied. Change-Id: I05031641647692196ce60dcad36fc8970131f516 Reviewed-by: Eike Ziller <eike.ziller@qt.io>
This commit is contained in:
@@ -48,6 +48,7 @@
|
|||||||
|
|
||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
#include <QStringListModel>
|
#include <QStringListModel>
|
||||||
|
#include <QVector>
|
||||||
#include <QAction>
|
#include <QAction>
|
||||||
|
|
||||||
#include <QtPlugin>
|
#include <QtPlugin>
|
||||||
@@ -70,6 +71,103 @@ namespace {
|
|||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
|
|
||||||
|
struct CompletionEntry
|
||||||
|
{
|
||||||
|
QString text;
|
||||||
|
FindFlags findFlags;
|
||||||
|
};
|
||||||
|
|
||||||
|
QDebug operator<<(QDebug d, const CompletionEntry &e)
|
||||||
|
{
|
||||||
|
QDebugStateSaver saver(d);
|
||||||
|
d.noquote();
|
||||||
|
d.nospace();
|
||||||
|
d << "CompletionEntry(\"" << e.text << "\", flags=" << hex
|
||||||
|
<< showbase << int(e.findFlags) << dec << noshowbase << ')';
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
|
||||||
|
class CompletionModel : public QAbstractListModel
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit CompletionModel(QObject *p = nullptr) : QAbstractListModel(p) {}
|
||||||
|
|
||||||
|
int rowCount(const QModelIndex & = QModelIndex()) const override { return m_entries.size(); }
|
||||||
|
|
||||||
|
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||||
|
|
||||||
|
void writeSettings(QSettings *settings) const;
|
||||||
|
void readSettings(QSettings *settings);
|
||||||
|
|
||||||
|
void updateCompletion(const QString &text, FindFlags f);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QVector<CompletionEntry> m_entries;
|
||||||
|
};
|
||||||
|
|
||||||
|
QVariant CompletionModel::data(const QModelIndex &index, int role) const
|
||||||
|
{
|
||||||
|
if (index.isValid()) {
|
||||||
|
const CompletionEntry &entry = m_entries.at(index.row());
|
||||||
|
switch (role) {
|
||||||
|
case Qt::DisplayRole:
|
||||||
|
case Qt::EditRole:
|
||||||
|
return QVariant(entry.text);
|
||||||
|
case Find::CompletionModelFindFlagsRole:
|
||||||
|
return QVariant(int(entry.findFlags));
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline QString completionSettingsArrayPrefix() { return QStringLiteral("FindCompletions"); }
|
||||||
|
static inline QString completionSettingsTextKey() { return QStringLiteral("Text"); }
|
||||||
|
static inline QString completionSettingsFlagsKey() { return QStringLiteral("Flags"); }
|
||||||
|
|
||||||
|
void CompletionModel::writeSettings(QSettings *settings) const
|
||||||
|
{
|
||||||
|
const int size = m_entries.size();
|
||||||
|
settings->beginWriteArray(completionSettingsArrayPrefix(), size);
|
||||||
|
for (int i = 0; i < size; ++i) {
|
||||||
|
settings->setArrayIndex(i);
|
||||||
|
settings->setValue(completionSettingsTextKey(), m_entries.at(i).text);
|
||||||
|
settings->setValue(completionSettingsFlagsKey(), int(m_entries.at(i).findFlags));
|
||||||
|
}
|
||||||
|
settings->endArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CompletionModel::readSettings(QSettings *settings)
|
||||||
|
{
|
||||||
|
beginResetModel();
|
||||||
|
const int size = settings->beginReadArray(completionSettingsArrayPrefix());
|
||||||
|
m_entries.clear();
|
||||||
|
m_entries.reserve(size);
|
||||||
|
for (int i = 0; i < size; ++i) {
|
||||||
|
settings->setArrayIndex(i);
|
||||||
|
CompletionEntry entry;
|
||||||
|
entry.text = settings->value(completionSettingsTextKey()).toString();
|
||||||
|
entry.findFlags = FindFlags(settings->value(completionSettingsFlagsKey(), 0).toInt());
|
||||||
|
if (!entry.text.isEmpty())
|
||||||
|
m_entries.append(entry);
|
||||||
|
}
|
||||||
|
settings->endArray();
|
||||||
|
endResetModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CompletionModel::updateCompletion(const QString &text, FindFlags f)
|
||||||
|
{
|
||||||
|
if (text.isEmpty())
|
||||||
|
return;
|
||||||
|
beginResetModel();
|
||||||
|
Utils::erase(m_entries, Utils::equal(&CompletionEntry::text, text));
|
||||||
|
m_entries.prepend({text, f});
|
||||||
|
while (m_entries.size() > MAX_COMPLETIONS)
|
||||||
|
m_entries.removeLast();
|
||||||
|
endResetModel();
|
||||||
|
}
|
||||||
|
|
||||||
class FindPrivate : public QObject
|
class FindPrivate : public QObject
|
||||||
{
|
{
|
||||||
Q_DECLARE_TR_FUNCTIONS(Core::Find)
|
Q_DECLARE_TR_FUNCTIONS(Core::Find)
|
||||||
@@ -88,9 +186,8 @@ public:
|
|||||||
Internal::FindToolWindow *m_findDialog = 0;
|
Internal::FindToolWindow *m_findDialog = 0;
|
||||||
SearchResultWindow *m_searchResultWindow = 0;
|
SearchResultWindow *m_searchResultWindow = 0;
|
||||||
FindFlags m_findFlags;
|
FindFlags m_findFlags;
|
||||||
QStringListModel m_findCompletionModel;
|
CompletionModel m_findCompletionModel;
|
||||||
QStringListModel m_replaceCompletionModel;
|
QStringListModel m_replaceCompletionModel;
|
||||||
QStringList m_findCompletions;
|
|
||||||
QStringList m_replaceCompletions;
|
QStringList m_replaceCompletions;
|
||||||
QAction *m_openFindDialog = 0;
|
QAction *m_openFindDialog = 0;
|
||||||
};
|
};
|
||||||
@@ -288,7 +385,7 @@ void FindPrivate::writeSettings()
|
|||||||
settings->setValue(QLatin1String("WholeWords"), bool(m_findFlags & FindWholeWords));
|
settings->setValue(QLatin1String("WholeWords"), bool(m_findFlags & FindWholeWords));
|
||||||
settings->setValue(QLatin1String("RegularExpression"), bool(m_findFlags & FindRegularExpression));
|
settings->setValue(QLatin1String("RegularExpression"), bool(m_findFlags & FindRegularExpression));
|
||||||
settings->setValue(QLatin1String("PreserveCase"), bool(m_findFlags & FindPreserveCase));
|
settings->setValue(QLatin1String("PreserveCase"), bool(m_findFlags & FindPreserveCase));
|
||||||
settings->setValue(QLatin1String("FindStrings"), m_findCompletions);
|
m_findCompletionModel.writeSettings(settings);
|
||||||
settings->setValue(QLatin1String("ReplaceStrings"), m_replaceCompletions);
|
settings->setValue(QLatin1String("ReplaceStrings"), m_replaceCompletions);
|
||||||
settings->endGroup();
|
settings->endGroup();
|
||||||
m_findToolBar->writeSettings();
|
m_findToolBar->writeSettings();
|
||||||
@@ -308,9 +405,8 @@ void FindPrivate::readSettings()
|
|||||||
Find::setRegularExpression(settings->value(QLatin1String("RegularExpression"), false).toBool());
|
Find::setRegularExpression(settings->value(QLatin1String("RegularExpression"), false).toBool());
|
||||||
Find::setPreserveCase(settings->value(QLatin1String("PreserveCase"), false).toBool());
|
Find::setPreserveCase(settings->value(QLatin1String("PreserveCase"), false).toBool());
|
||||||
}
|
}
|
||||||
m_findCompletions = settings->value(QLatin1String("FindStrings")).toStringList();
|
m_findCompletionModel.readSettings(settings);
|
||||||
m_replaceCompletions = settings->value(QLatin1String("ReplaceStrings")).toStringList();
|
m_replaceCompletions = settings->value(QLatin1String("ReplaceStrings")).toStringList();
|
||||||
m_findCompletionModel.setStringList(m_findCompletions);
|
|
||||||
m_replaceCompletionModel.setStringList(m_replaceCompletions);
|
m_replaceCompletionModel.setStringList(m_replaceCompletions);
|
||||||
settings->endGroup();
|
settings->endGroup();
|
||||||
m_findToolBar->readSettings();
|
m_findToolBar->readSettings();
|
||||||
@@ -318,9 +414,9 @@ void FindPrivate::readSettings()
|
|||||||
emit m_instance->findFlagsChanged(); // would have been done in the setXXX methods above
|
emit m_instance->findFlagsChanged(); // would have been done in the setXXX methods above
|
||||||
}
|
}
|
||||||
|
|
||||||
void Find::updateFindCompletion(const QString &text)
|
void Find::updateFindCompletion(const QString &text, FindFlags flags)
|
||||||
{
|
{
|
||||||
d->updateCompletion(text, d->m_findCompletions, &d->m_findCompletionModel);
|
d->m_findCompletionModel.updateCompletion(text, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Find::updateReplaceCompletion(const QString &text)
|
void Find::updateReplaceCompletion(const QString &text)
|
||||||
@@ -353,7 +449,7 @@ void Find::openFindToolBar(FindDirection direction)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringListModel *Find::findCompletionModel()
|
QAbstractListModel *Find::findCompletionModel()
|
||||||
{
|
{
|
||||||
return &(d->m_findCompletionModel);
|
return &(d->m_findCompletionModel);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,6 +30,7 @@
|
|||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
class QAbstractListModel;
|
||||||
class QStringListModel;
|
class QStringListModel;
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
@@ -49,11 +50,13 @@ public:
|
|||||||
FindBackwardDirection
|
FindBackwardDirection
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum { CompletionModelFindFlagsRole = Qt::UserRole + 1 };
|
||||||
|
|
||||||
static FindFlags findFlags();
|
static FindFlags findFlags();
|
||||||
static bool hasFindFlag(FindFlag flag);
|
static bool hasFindFlag(FindFlag flag);
|
||||||
static void updateFindCompletion(const QString &text);
|
static void updateFindCompletion(const QString &text, FindFlags flags = 0);
|
||||||
static void updateReplaceCompletion(const QString &text);
|
static void updateReplaceCompletion(const QString &text);
|
||||||
static QStringListModel *findCompletionModel();
|
static QAbstractListModel *findCompletionModel();
|
||||||
static QStringListModel *replaceCompletionModel();
|
static QStringListModel *replaceCompletionModel();
|
||||||
static void setUseFakeVim(bool on);
|
static void setUseFakeVim(bool on);
|
||||||
static void openFindToolBar(FindDirection direction);
|
static void openFindToolBar(FindDirection direction);
|
||||||
|
|||||||
@@ -116,6 +116,9 @@ FindToolBar::FindToolBar(CurrentDocumentFind *currentDocumentFind)
|
|||||||
this, &FindToolBar::invokeFindEnter, Qt::QueuedConnection);
|
this, &FindToolBar::invokeFindEnter, Qt::QueuedConnection);
|
||||||
connect(m_ui.replaceEdit, &Utils::FancyLineEdit::returnPressed,
|
connect(m_ui.replaceEdit, &Utils::FancyLineEdit::returnPressed,
|
||||||
this, &FindToolBar::invokeReplaceEnter, Qt::QueuedConnection);
|
this, &FindToolBar::invokeReplaceEnter, Qt::QueuedConnection);
|
||||||
|
connect(m_findCompleter,
|
||||||
|
static_cast<void (QCompleter::*)(const QModelIndex &)>(&QCompleter::activated),
|
||||||
|
this, &FindToolBar::findCompleterActivated);
|
||||||
|
|
||||||
QAction *shiftEnterAction = new QAction(m_ui.findEdit);
|
QAction *shiftEnterAction = new QAction(m_ui.findEdit);
|
||||||
shiftEnterAction->setShortcut(QKeySequence(tr("Shift+Enter")));
|
shiftEnterAction->setShortcut(QKeySequence(tr("Shift+Enter")));
|
||||||
@@ -313,6 +316,17 @@ FindToolBar::~FindToolBar()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FindToolBar::findCompleterActivated(const QModelIndex &index)
|
||||||
|
{
|
||||||
|
const int findFlagsI = index.data(Find::CompletionModelFindFlagsRole).toInt();
|
||||||
|
const FindFlags findFlags(findFlagsI);
|
||||||
|
setFindFlag(FindCaseSensitively, findFlags.testFlag(FindCaseSensitively));
|
||||||
|
setFindFlag(FindBackward, findFlags.testFlag(FindBackward));
|
||||||
|
setFindFlag(FindWholeWords, findFlags.testFlag(FindWholeWords));
|
||||||
|
setFindFlag(FindRegularExpression, findFlags.testFlag(FindRegularExpression));
|
||||||
|
setFindFlag(FindPreserveCase, findFlags.testFlag(FindPreserveCase));
|
||||||
|
}
|
||||||
|
|
||||||
void FindToolBar::installEventFilters()
|
void FindToolBar::installEventFilters()
|
||||||
{
|
{
|
||||||
if (!m_eventFiltersInstalled) {
|
if (!m_eventFiltersInstalled) {
|
||||||
@@ -527,9 +541,10 @@ void FindToolBar::invokeFindStep()
|
|||||||
m_findStepTimer.stop();
|
m_findStepTimer.stop();
|
||||||
m_findIncrementalTimer.stop();
|
m_findIncrementalTimer.stop();
|
||||||
if (m_currentDocumentFind->isEnabled()) {
|
if (m_currentDocumentFind->isEnabled()) {
|
||||||
Find::updateFindCompletion(getFindText());
|
const FindFlags ef = effectiveFindFlags();
|
||||||
|
Find::updateFindCompletion(getFindText(), ef);
|
||||||
IFindSupport::Result result =
|
IFindSupport::Result result =
|
||||||
m_currentDocumentFind->findStep(getFindText(), effectiveFindFlags());
|
m_currentDocumentFind->findStep(getFindText(), ef);
|
||||||
indicateSearchState(result);
|
indicateSearchState(result);
|
||||||
if (result == IFindSupport::NotYetFound)
|
if (result == IFindSupport::NotYetFound)
|
||||||
m_findStepTimer.start(50);
|
m_findStepTimer.start(50);
|
||||||
@@ -556,9 +571,10 @@ void FindToolBar::invokeReplace()
|
|||||||
{
|
{
|
||||||
setFindFlag(FindBackward, false);
|
setFindFlag(FindBackward, false);
|
||||||
if (m_currentDocumentFind->isEnabled() && m_currentDocumentFind->supportsReplace()) {
|
if (m_currentDocumentFind->isEnabled() && m_currentDocumentFind->supportsReplace()) {
|
||||||
Find::updateFindCompletion(getFindText());
|
const FindFlags ef = effectiveFindFlags();
|
||||||
|
Find::updateFindCompletion(getFindText(), ef);
|
||||||
Find::updateReplaceCompletion(getReplaceText());
|
Find::updateReplaceCompletion(getReplaceText());
|
||||||
m_currentDocumentFind->replace(getFindText(), getReplaceText(), effectiveFindFlags());
|
m_currentDocumentFind->replace(getFindText(), getReplaceText(), ef);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -595,18 +611,20 @@ void FindToolBar::invokeGlobalReplacePrevious()
|
|||||||
void FindToolBar::invokeReplaceStep()
|
void FindToolBar::invokeReplaceStep()
|
||||||
{
|
{
|
||||||
if (m_currentDocumentFind->isEnabled() && m_currentDocumentFind->supportsReplace()) {
|
if (m_currentDocumentFind->isEnabled() && m_currentDocumentFind->supportsReplace()) {
|
||||||
Find::updateFindCompletion(getFindText());
|
const FindFlags ef = effectiveFindFlags();
|
||||||
|
Find::updateFindCompletion(getFindText(), ef);
|
||||||
Find::updateReplaceCompletion(getReplaceText());
|
Find::updateReplaceCompletion(getReplaceText());
|
||||||
m_currentDocumentFind->replaceStep(getFindText(), getReplaceText(), effectiveFindFlags());
|
m_currentDocumentFind->replaceStep(getFindText(), getReplaceText(), ef);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FindToolBar::invokeReplaceAll()
|
void FindToolBar::invokeReplaceAll()
|
||||||
{
|
{
|
||||||
Find::updateFindCompletion(getFindText());
|
const FindFlags ef = effectiveFindFlags();
|
||||||
|
Find::updateFindCompletion(getFindText(), ef);
|
||||||
Find::updateReplaceCompletion(getReplaceText());
|
Find::updateReplaceCompletion(getReplaceText());
|
||||||
if (m_currentDocumentFind->isEnabled() && m_currentDocumentFind->supportsReplace())
|
if (m_currentDocumentFind->isEnabled() && m_currentDocumentFind->supportsReplace())
|
||||||
m_currentDocumentFind->replaceAll(getFindText(), getReplaceText(), effectiveFindFlags());
|
m_currentDocumentFind->replaceAll(getFindText(), getReplaceText(), ef);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FindToolBar::invokeGlobalReplaceAll()
|
void FindToolBar::invokeGlobalReplaceAll()
|
||||||
|
|||||||
@@ -125,6 +125,7 @@ private:
|
|||||||
void updateToolBar();
|
void updateToolBar();
|
||||||
void findFlagsChanged();
|
void findFlagsChanged();
|
||||||
void findEditButtonClicked();
|
void findEditButtonClicked();
|
||||||
|
void findCompleterActivated(const QModelIndex &);
|
||||||
|
|
||||||
void setCaseSensitive(bool sensitive);
|
void setCaseSensitive(bool sensitive);
|
||||||
void setWholeWord(bool wholeOnly);
|
void setWholeWord(bool wholeOnly);
|
||||||
|
|||||||
@@ -83,6 +83,9 @@ FindToolWindow::FindToolWindow(QWidget *parent)
|
|||||||
m_findCompleter->setModel(Find::findCompletionModel());
|
m_findCompleter->setModel(Find::findCompletionModel());
|
||||||
m_ui.searchTerm->setSpecialCompleter(m_findCompleter);
|
m_ui.searchTerm->setSpecialCompleter(m_findCompleter);
|
||||||
m_ui.searchTerm->installEventFilter(this);
|
m_ui.searchTerm->installEventFilter(this);
|
||||||
|
connect(m_findCompleter,
|
||||||
|
static_cast<void (QCompleter::*)(const QModelIndex &)>(&QCompleter::activated),
|
||||||
|
this, &FindToolWindow::findCompleterActivated);
|
||||||
|
|
||||||
m_ui.searchTerm->setValidationFunction(validateRegExp);
|
m_ui.searchTerm->setValidationFunction(validateRegExp);
|
||||||
connect(Find::instance(), &Find::findFlagsChanged,
|
connect(Find::instance(), &Find::findFlagsChanged,
|
||||||
@@ -318,3 +321,14 @@ void FindToolWindow::readSettings()
|
|||||||
}
|
}
|
||||||
settings->endGroup();
|
settings->endGroup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FindToolWindow::findCompleterActivated(const QModelIndex &index)
|
||||||
|
{
|
||||||
|
const int findFlagsI = index.data(Find::CompletionModelFindFlagsRole).toInt();
|
||||||
|
const FindFlags findFlags(findFlagsI);
|
||||||
|
Find::setCaseSensitive(findFlags.testFlag(FindCaseSensitively));
|
||||||
|
Find::setBackward(findFlags.testFlag(FindBackward));
|
||||||
|
Find::setWholeWord(findFlags.testFlag(FindWholeWords));
|
||||||
|
Find::setRegularExpression(findFlags.testFlag(FindRegularExpression));
|
||||||
|
Find::setPreserveCase(findFlags.testFlag(FindPreserveCase));
|
||||||
|
}
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ private:
|
|||||||
void updateButtonStates();
|
void updateButtonStates();
|
||||||
void updateFindFlags();
|
void updateFindFlags();
|
||||||
void updateFindFilterName(IFindFilter *filter);
|
void updateFindFilterName(IFindFilter *filter);
|
||||||
|
void findCompleterActivated(const QModelIndex &index);
|
||||||
|
|
||||||
void acceptAndGetParameters(QString *term, IFindFilter **filter);
|
void acceptAndGetParameters(QString *term, IFindFilter **filter);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user