forked from qt-creator/qt-creator
Output panes: Allow to invert the meaning of the filter field
That is, show only the non-matching lines. Task-number: QTCREATORBUG-19596 Change-Id: Iac06a7c4531688dbf97c7d5c4d0cdb80979b5f95 Reviewed-by: Eike Ziller <eike.ziller@qt.io>
This commit is contained in:
@@ -102,6 +102,7 @@ protected:
|
|||||||
void setupFilterUi(const QString &historyKey);
|
void setupFilterUi(const QString &historyKey);
|
||||||
QString filterText() const;
|
QString filterText() const;
|
||||||
bool filterUsesRegexp() const { return m_filterRegexp; }
|
bool filterUsesRegexp() const { return m_filterRegexp; }
|
||||||
|
bool filterIsInverted() const { return m_invertFilter; }
|
||||||
Qt::CaseSensitivity filterCaseSensitivity() const { return m_filterCaseSensitivity; }
|
Qt::CaseSensitivity filterCaseSensitivity() const { return m_filterCaseSensitivity; }
|
||||||
void setFilteringEnabled(bool enable);
|
void setFilteringEnabled(bool enable);
|
||||||
QWidget *filterWidget() const { return m_filterOutputLineEdit; }
|
QWidget *filterWidget() const { return m_filterOutputLineEdit; }
|
||||||
@@ -116,14 +117,17 @@ private:
|
|||||||
void setRegularExpressions(bool regularExpressions);
|
void setRegularExpressions(bool regularExpressions);
|
||||||
Id filterRegexpActionId() const;
|
Id filterRegexpActionId() const;
|
||||||
Id filterCaseSensitivityActionId() const;
|
Id filterCaseSensitivityActionId() const;
|
||||||
|
Id filterInvertedActionId() const;
|
||||||
|
|
||||||
Core::CommandButton * const m_zoomInButton;
|
Core::CommandButton * const m_zoomInButton;
|
||||||
Core::CommandButton * const m_zoomOutButton;
|
Core::CommandButton * const m_zoomOutButton;
|
||||||
QAction *m_filterActionRegexp = nullptr;
|
QAction *m_filterActionRegexp = nullptr;
|
||||||
QAction *m_filterActionCaseSensitive = nullptr;
|
QAction *m_filterActionCaseSensitive = nullptr;
|
||||||
|
QAction *m_invertFilterAction = nullptr;
|
||||||
Utils::FancyLineEdit *m_filterOutputLineEdit = nullptr;
|
Utils::FancyLineEdit *m_filterOutputLineEdit = nullptr;
|
||||||
IContext *m_context = nullptr;
|
IContext *m_context = nullptr;
|
||||||
bool m_filterRegexp = false;
|
bool m_filterRegexp = false;
|
||||||
|
bool m_invertFilter = false;
|
||||||
Qt::CaseSensitivity m_filterCaseSensitivity = Qt::CaseInsensitive;
|
Qt::CaseSensitivity m_filterCaseSensitivity = Qt::CaseInsensitive;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -146,7 +146,8 @@ bool MessageOutputWindow::canNavigate() const
|
|||||||
|
|
||||||
void MessageOutputWindow::updateFilter()
|
void MessageOutputWindow::updateFilter()
|
||||||
{
|
{
|
||||||
m_widget->updateFilterProperties(filterText(), filterCaseSensitivity(), filterUsesRegexp());
|
m_widget->updateFilterProperties(filterText(), filterCaseSensitivity(), filterUsesRegexp(),
|
||||||
|
filterIsInverted());
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
@@ -155,6 +155,15 @@ void IOutputPane::setupFilterUi(const QString &historyKey)
|
|||||||
Core::ActionManager::registerAction(m_filterActionCaseSensitive,
|
Core::ActionManager::registerAction(m_filterActionCaseSensitive,
|
||||||
filterCaseSensitivityActionId());
|
filterCaseSensitivityActionId());
|
||||||
|
|
||||||
|
m_invertFilterAction = new QAction(this);
|
||||||
|
m_invertFilterAction->setCheckable(true);
|
||||||
|
m_invertFilterAction->setText(tr("Show Non-matching Lines"));
|
||||||
|
connect(m_invertFilterAction, &QAction::toggled, this, [this] {
|
||||||
|
m_invertFilter = m_invertFilterAction->isChecked();
|
||||||
|
updateFilter();
|
||||||
|
});
|
||||||
|
Core::ActionManager::registerAction(m_invertFilterAction, filterInvertedActionId());
|
||||||
|
|
||||||
m_filterOutputLineEdit->setPlaceholderText(tr("Filter output..."));
|
m_filterOutputLineEdit->setPlaceholderText(tr("Filter output..."));
|
||||||
m_filterOutputLineEdit->setButtonVisible(FancyLineEdit::Left, true);
|
m_filterOutputLineEdit->setButtonVisible(FancyLineEdit::Left, true);
|
||||||
m_filterOutputLineEdit->setButtonIcon(FancyLineEdit::Left, Icons::MAGNIFIER.icon());
|
m_filterOutputLineEdit->setButtonIcon(FancyLineEdit::Left, Icons::MAGNIFIER.icon());
|
||||||
@@ -213,7 +222,7 @@ void IOutputPane::updateFilter()
|
|||||||
void IOutputPane::filterOutputButtonClicked()
|
void IOutputPane::filterOutputButtonClicked()
|
||||||
{
|
{
|
||||||
auto popup = new Core::OptionsPopup(m_filterOutputLineEdit,
|
auto popup = new Core::OptionsPopup(m_filterOutputLineEdit,
|
||||||
{filterRegexpActionId(), filterCaseSensitivityActionId()});
|
{filterRegexpActionId(), filterCaseSensitivityActionId(), filterInvertedActionId()});
|
||||||
popup->show();
|
popup->show();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -233,6 +242,11 @@ Id IOutputPane::filterCaseSensitivityActionId() const
|
|||||||
return Id("OutputFilter.CaseSensitive").withSuffix(metaObject()->className());
|
return Id("OutputFilter.CaseSensitive").withSuffix(metaObject()->className());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Id IOutputPane::filterInvertedActionId() const
|
||||||
|
{
|
||||||
|
return Id("OutputFilter.Invert").withSuffix(metaObject()->className());
|
||||||
|
}
|
||||||
|
|
||||||
void IOutputPane::setCaseSensitive(bool caseSensitive)
|
void IOutputPane::setCaseSensitive(bool caseSensitive)
|
||||||
{
|
{
|
||||||
m_filterCaseSensitivity = caseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive;
|
m_filterCaseSensitivity = caseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive;
|
||||||
|
@@ -280,12 +280,17 @@ void OutputWindow::setWheelZoomEnabled(bool enabled)
|
|||||||
d->zoomEnabled = enabled;
|
d->zoomEnabled = enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OutputWindow::updateFilterProperties(const QString &filterText,
|
void OutputWindow::updateFilterProperties(
|
||||||
Qt::CaseSensitivity caseSensitivity, bool isRegexp)
|
const QString &filterText,
|
||||||
|
Qt::CaseSensitivity caseSensitivity,
|
||||||
|
bool isRegexp,
|
||||||
|
bool isInverted
|
||||||
|
)
|
||||||
{
|
{
|
||||||
FilterModeFlags flags;
|
FilterModeFlags flags;
|
||||||
flags.setFlag(FilterModeFlag::CaseSensitive, caseSensitivity == Qt::CaseSensitive)
|
flags.setFlag(FilterModeFlag::CaseSensitive, caseSensitivity == Qt::CaseSensitive)
|
||||||
.setFlag(FilterModeFlag::RegExp, isRegexp);
|
.setFlag(FilterModeFlag::RegExp, isRegexp)
|
||||||
|
.setFlag(FilterModeFlag::Inverted, isInverted);
|
||||||
if (d->filterMode == flags && d->filterText == filterText)
|
if (d->filterMode == flags && d->filterText == filterText)
|
||||||
return;
|
return;
|
||||||
d->lastFilteredBlockNumber = -1;
|
d->lastFilteredBlockNumber = -1;
|
||||||
@@ -324,6 +329,7 @@ void OutputWindow::filterNewContent()
|
|||||||
if (!lastBlock.isValid())
|
if (!lastBlock.isValid())
|
||||||
lastBlock = document()->begin();
|
lastBlock = document()->begin();
|
||||||
|
|
||||||
|
const bool invert = d->filterMode.testFlag(FilterModeFlag::Inverted);
|
||||||
if (d->filterMode.testFlag(OutputWindow::FilterModeFlag::RegExp)) {
|
if (d->filterMode.testFlag(OutputWindow::FilterModeFlag::RegExp)) {
|
||||||
QRegularExpression regExp(d->filterText);
|
QRegularExpression regExp(d->filterText);
|
||||||
if (!d->filterMode.testFlag(OutputWindow::FilterModeFlag::CaseSensitive))
|
if (!d->filterMode.testFlag(OutputWindow::FilterModeFlag::CaseSensitive))
|
||||||
@@ -331,16 +337,17 @@ void OutputWindow::filterNewContent()
|
|||||||
|
|
||||||
for (; lastBlock != document()->end(); lastBlock = lastBlock.next())
|
for (; lastBlock != document()->end(); lastBlock = lastBlock.next())
|
||||||
lastBlock.setVisible(d->filterText.isEmpty()
|
lastBlock.setVisible(d->filterText.isEmpty()
|
||||||
|| regExp.match(lastBlock.text()).hasMatch());
|
|| regExp.match(lastBlock.text()).hasMatch() != invert);
|
||||||
} else {
|
} else {
|
||||||
if (d->filterMode.testFlag(OutputWindow::FilterModeFlag::CaseSensitive)) {
|
if (d->filterMode.testFlag(OutputWindow::FilterModeFlag::CaseSensitive)) {
|
||||||
for (; lastBlock != document()->end(); lastBlock = lastBlock.next())
|
for (; lastBlock != document()->end(); lastBlock = lastBlock.next())
|
||||||
lastBlock.setVisible(d->filterText.isEmpty()
|
lastBlock.setVisible(d->filterText.isEmpty()
|
||||||
|| lastBlock.text().contains(d->filterText));
|
|| lastBlock.text().contains(d->filterText) != invert);
|
||||||
} else {
|
} else {
|
||||||
for (; lastBlock != document()->end(); lastBlock = lastBlock.next())
|
for (; lastBlock != document()->end(); lastBlock = lastBlock.next()) {
|
||||||
lastBlock.setVisible(d->filterText.isEmpty()
|
lastBlock.setVisible(d->filterText.isEmpty() || lastBlock.text().toLower()
|
||||||
|| lastBlock.text().toLower().contains(d->filterText.toLower()));
|
.contains(d->filterText.toLower()) != invert);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -49,6 +49,7 @@ public:
|
|||||||
Default = 0x00, // Plain text, non case sensitive, for initialization
|
Default = 0x00, // Plain text, non case sensitive, for initialization
|
||||||
RegExp = 0x01,
|
RegExp = 0x01,
|
||||||
CaseSensitive = 0x02,
|
CaseSensitive = 0x02,
|
||||||
|
Inverted = 0x04,
|
||||||
};
|
};
|
||||||
Q_DECLARE_FLAGS(FilterModeFlags, FilterModeFlag)
|
Q_DECLARE_FLAGS(FilterModeFlags, FilterModeFlag)
|
||||||
|
|
||||||
@@ -78,7 +79,11 @@ public:
|
|||||||
void resetZoom() { setFontZoom(0); }
|
void resetZoom() { setFontZoom(0); }
|
||||||
void setWheelZoomEnabled(bool enabled);
|
void setWheelZoomEnabled(bool enabled);
|
||||||
|
|
||||||
void updateFilterProperties(const QString &filterText, Qt::CaseSensitivity caseSensitivity, bool regexp);
|
void updateFilterProperties(
|
||||||
|
const QString &filterText,
|
||||||
|
Qt::CaseSensitivity caseSensitivity,
|
||||||
|
bool regexp,
|
||||||
|
bool isInverted);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void wheelZoom();
|
void wheelZoom();
|
||||||
|
@@ -378,7 +378,7 @@ void AppOutputPane::updateFilter()
|
|||||||
const int index = currentIndex();
|
const int index = currentIndex();
|
||||||
if (index != -1) {
|
if (index != -1) {
|
||||||
m_runControlTabs.at(index).window->updateFilterProperties(
|
m_runControlTabs.at(index).window->updateFilterProperties(
|
||||||
filterText(), filterCaseSensitivity(), filterUsesRegexp());
|
filterText(), filterCaseSensitivity(), filterUsesRegexp(), filterIsInverted());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -724,7 +724,7 @@ void AppOutputPane::tabChanged(int i)
|
|||||||
if (i != -1 && index != -1) {
|
if (i != -1 && index != -1) {
|
||||||
const RunControlTab &controlTab = m_runControlTabs[index];
|
const RunControlTab &controlTab = m_runControlTabs[index];
|
||||||
controlTab.window->updateFilterProperties(filterText(), filterCaseSensitivity(),
|
controlTab.window->updateFilterProperties(filterText(), filterCaseSensitivity(),
|
||||||
filterUsesRegexp());
|
filterUsesRegexp(), filterIsInverted());
|
||||||
enableButtons(controlTab.runControl);
|
enableButtons(controlTab.runControl);
|
||||||
} else {
|
} else {
|
||||||
enableDefaultButtons();
|
enableDefaultButtons();
|
||||||
|
@@ -354,7 +354,7 @@ void CompileOutputWindow::setSettings(const CompileOutputSettings &settings)
|
|||||||
void CompileOutputWindow::updateFilter()
|
void CompileOutputWindow::updateFilter()
|
||||||
{
|
{
|
||||||
m_outputWindow->updateFilterProperties(filterText(), filterCaseSensitivity(),
|
m_outputWindow->updateFilterProperties(filterText(), filterCaseSensitivity(),
|
||||||
filterUsesRegexp());
|
filterUsesRegexp(), filterIsInverted());
|
||||||
}
|
}
|
||||||
|
|
||||||
void CompileOutputWindow::loadSettings()
|
void CompileOutputWindow::loadSettings()
|
||||||
|
@@ -351,16 +351,20 @@ int TaskFilterModel::issuesCount(int startRow, int endRow) const
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TaskFilterModel::updateFilterProperties(const QString &filterText,
|
void TaskFilterModel::updateFilterProperties(
|
||||||
Qt::CaseSensitivity caseSensitivity, bool isRegexp)
|
const QString &filterText,
|
||||||
|
Qt::CaseSensitivity caseSensitivity,
|
||||||
|
bool isRegexp,
|
||||||
|
bool isInverted)
|
||||||
{
|
{
|
||||||
if (filterText == m_filterText && m_filterCaseSensitivity == caseSensitivity
|
if (filterText == m_filterText && m_filterCaseSensitivity == caseSensitivity
|
||||||
&& m_filterStringIsRegexp == isRegexp) {
|
&& m_filterStringIsRegexp == isRegexp && m_filterIsInverted == isInverted) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_filterText = filterText;
|
m_filterText = filterText;
|
||||||
m_filterCaseSensitivity = caseSensitivity;
|
m_filterCaseSensitivity = caseSensitivity;
|
||||||
m_filterStringIsRegexp = isRegexp;
|
m_filterStringIsRegexp = isRegexp;
|
||||||
|
m_filterIsInverted = isInverted;
|
||||||
if (m_filterStringIsRegexp) {
|
if (m_filterStringIsRegexp) {
|
||||||
m_filterRegexp.setPattern(m_filterText);
|
m_filterRegexp.setPattern(m_filterText);
|
||||||
m_filterRegexp.setPatternOptions(m_filterCaseSensitivity == Qt::CaseInsensitive
|
m_filterRegexp.setPatternOptions(m_filterCaseSensitivity == Qt::CaseInsensitive
|
||||||
@@ -399,7 +403,7 @@ bool TaskFilterModel::filterAcceptsTask(const Task &task) const
|
|||||||
return m_filterStringIsRegexp ? m_filterRegexp.isValid() && s.contains(m_filterRegexp)
|
return m_filterStringIsRegexp ? m_filterRegexp.isValid() && s.contains(m_filterRegexp)
|
||||||
: s.contains(m_filterText, m_filterCaseSensitivity);
|
: s.contains(m_filterText, m_filterCaseSensitivity);
|
||||||
};
|
};
|
||||||
if (!accepts(task.file.toString()) && !accepts(task.description))
|
if ((accepts(task.file.toString()) || accepts(task.description)) == m_filterIsInverted)
|
||||||
accept = false;
|
accept = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -145,8 +145,11 @@ public:
|
|||||||
bool hasFile(const QModelIndex &index) const
|
bool hasFile(const QModelIndex &index) const
|
||||||
{ return taskModel()->hasFile(mapToSource(index)); }
|
{ return taskModel()->hasFile(mapToSource(index)); }
|
||||||
|
|
||||||
void updateFilterProperties(const QString &filterText, Qt::CaseSensitivity caseSensitivity,
|
void updateFilterProperties(
|
||||||
bool isRegex);
|
const QString &filterText,
|
||||||
|
Qt::CaseSensitivity caseSensitivity,
|
||||||
|
bool isRegex,
|
||||||
|
bool isInverted);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override;
|
bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override;
|
||||||
@@ -157,6 +160,7 @@ private:
|
|||||||
bool m_includeWarnings;
|
bool m_includeWarnings;
|
||||||
bool m_includeErrors;
|
bool m_includeErrors;
|
||||||
bool m_filterStringIsRegexp = false;
|
bool m_filterStringIsRegexp = false;
|
||||||
|
bool m_filterIsInverted = false;
|
||||||
Qt::CaseSensitivity m_filterCaseSensitivity = Qt::CaseInsensitive;
|
Qt::CaseSensitivity m_filterCaseSensitivity = Qt::CaseInsensitive;
|
||||||
QList<Core::Id> m_categoryIds;
|
QList<Core::Id> m_categoryIds;
|
||||||
QString m_filterText;
|
QString m_filterText;
|
||||||
|
@@ -678,7 +678,8 @@ void TaskWindow::goToPrev()
|
|||||||
|
|
||||||
void TaskWindow::updateFilter()
|
void TaskWindow::updateFilter()
|
||||||
{
|
{
|
||||||
d->m_filter->updateFilterProperties(filterText(), filterCaseSensitivity(), filterUsesRegexp());
|
d->m_filter->updateFilterProperties(filterText(), filterCaseSensitivity(), filterUsesRegexp(),
|
||||||
|
filterIsInverted());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TaskWindow::canNavigate() const
|
bool TaskWindow::canNavigate() const
|
||||||
|
Reference in New Issue
Block a user