31 setWindowTitle(tr(
"Find in Shader Files"));
32 setAttribute(Qt::WA_DeleteOnClose);
35 auto *layout =
new QVBoxLayout(
this);
36 layout->addWidget(
new QLabel(tr(
"Search the active shader library using a regular expression:"),
this));
37 auto *pathLabel =
new QLabel(tr(
"Library: %1").arg(this->shaderPath),
this);
38 pathLabel->setTextInteractionFlags(Qt::TextSelectableByMouse);
39 layout->addWidget(pathLabel);
41 auto *searchRow =
new QHBoxLayout();
43 patternEdit->setPlaceholderText(tr(
"Regular expression, for example: uniform\\s+float"));
45 auto *searchButton =
new QPushButton(tr(
"Search"),
this);
46 searchButton->setDefault(
true);
48 searchRow->addWidget(searchButton);
49 layout->addLayout(searchRow);
56 resultsTree->setHeaderLabels({tr(
"Shader"), tr(
"Line"), tr(
"Match"), tr(
"Source")});
59 resultsTree->setSelectionBehavior(QAbstractItemView::SelectRows);
60 resultsTree->setSelectionMode(QAbstractItemView::SingleSelection);
62 resultsTree->header()->setSectionResizeMode(0, QHeaderView::ResizeToContents);
63 resultsTree->header()->setSectionResizeMode(1, QHeaderView::ResizeToContents);
64 resultsTree->header()->setSectionResizeMode(2, QHeaderView::ResizeToContents);
65 resultsTree->header()->setSectionResizeMode(3, QHeaderView::Stretch);
68 statusLabel =
new QLabel(tr(
"Enter a regular expression to search."),
this);
71 auto *buttonBox =
new QDialogButtonBox(QDialogButtonBox::Close,
this);
72 openButton = buttonBox->addButton(tr(
"Open Result"), QDialogButtonBox::ActionRole);
74 layout->addWidget(buttonBox);
80 connect(
resultsTree, &QTreeWidget::itemActivated,
this, [
this](QTreeWidgetItem *item,
int) {
openResult(item); });
82 connect(buttonBox, &QDialogButtonBox::rejected,
this, &QDialog::close);
84 QSettings settings(
"LostSideDead");
85 caseSensitiveCheck->setChecked(settings.value(
"findInFiles/caseSensitive",
false).toBool());
86 if (!restoreGeometry(settings.value(
"findInFiles/geometry").toByteArray()))
101 if (pattern.isEmpty()) {
102 statusLabel->setText(tr(
"Enter a regular expression to search."));
106 QRegularExpression::PatternOptions options;
108 options |= QRegularExpression::CaseInsensitiveOption;
109 const QRegularExpression expression(pattern, options);
110 if (!expression.isValid()) {
111 statusLabel->setText(tr(
"Invalid regular expression at position %1: %2").arg(expression.patternErrorOffset()).arg(expression.errorString()));
115 QSettings settings(
"LostSideDead");
117 settings.setValue(
"findInFiles/geometry", saveGeometry());
119 QApplication::setOverrideCursor(Qt::WaitCursor);
122 const QStringList filters = {
"*.glsl",
"*.frag",
"*.vert",
"*.comp"};
123 QDirIterator files(
shaderPath, filters, QDir::Files | QDir::Readable, QDirIterator::Subdirectories);
126 bool limitReached =
false;
129 while (files.hasNext() && !limitReached) {
130 const QString filePath = files.next();
131 QFile file(filePath);
132 if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
136 QTextStream input(&file);
138 while (!input.atEnd() && !limitReached) {
139 const QString line = input.readLine();
141 QRegularExpressionMatchIterator matches = expression.globalMatch(line);
142 while (matches.hasNext()) {
143 const QRegularExpressionMatch match = matches.next();
145 item->setText(0, root.relativeFilePath(filePath));
146 item->setText(1, QString::number(lineNumber));
147 item->setText(2, match.captured(0).isEmpty() ? tr(
"(zero-length match)") : match.captured(0));
148 item->setText(3, line.trimmed());
149 item->setData(0, FILE_PATH_ROLE, QFileInfo(filePath).absoluteFilePath());
150 item->setData(0, LINE_NUMBER_ROLE, lineNumber);
151 item->setData(0, COLUMN_NUMBER_ROLE, match.capturedStart());
152 item->setData(0, MATCH_LENGTH_ROLE, match.capturedLength());
154 if (resultCount >= MAX_RESULTS) {
164 QApplication::restoreOverrideCursor();
167 statusLabel->setText(tr(
"Showing the first %1 matches from %2 shader files.").arg(resultCount).arg(fileCount));
169 statusLabel->setText(tr(
"Found %1 match(es) in %2 shader file(s).").arg(resultCount).arg(fileCount));
void resultActivated(const QString &filePath, int lineNumber, int columnNumber, int matchLength)
Emitted when the user opens one search result.