- enhancement: Folder mode in "File in files" dialog.
- enhancement: When open a file, test if it contains binary contains.
This commit is contained in:
parent
eccdf68a60
commit
595156e80f
2
NEWS.md
2
NEWS.md
|
@ -30,6 +30,8 @@ Red Panda C++ Version 2.23
|
|||
- enhancement: Sort symbols by their declaration pos in the Class Browser, if not sort by alpha order.
|
||||
- fix: Keyword asm is not correctly parsed.
|
||||
- fix: Tips for problem is not correctly displayed.
|
||||
- enhancement: Folder mode in "File in files" dialog.
|
||||
- enhancement: When open a file, test if it contains binary contains.
|
||||
|
||||
Red Panda C++ Version 2.22
|
||||
|
||||
|
|
|
@ -6526,9 +6526,13 @@ void MainWindow::on_btnSearchAgain_clicked()
|
|||
if (results->scope==SearchFileScope::wholeProject
|
||||
&& pMainWindow->project()==nullptr)
|
||||
return;
|
||||
mSearchInFilesDialog->findInFiles(results->keyword,
|
||||
mSearchInFilesDialog->findInFiles(
|
||||
results->keyword,
|
||||
results->scope,
|
||||
results->options);
|
||||
results->options,
|
||||
results->folder,
|
||||
results->filters,
|
||||
results->searchSubfolders);
|
||||
} else if (results->searchType == SearchType::FindOccurences) {
|
||||
CppRefacter refactor;
|
||||
refactor.findOccurence(results->statementFullname,results->scope);
|
||||
|
|
|
@ -515,7 +515,7 @@
|
|||
<enum>QTabWidget::West</enum>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>4</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="usesScrollButtons">
|
||||
<bool>true</bool>
|
||||
|
|
|
@ -7353,6 +7353,34 @@
|
|||
<source>Abort</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>*.*</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Filters:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>...</source>
|
||||
<translation type="unfinished">...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Folder:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Search in subfolders</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Folder</source>
|
||||
<translation type="unfinished">Pasta</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Choose Folder</source>
|
||||
<translation type="unfinished">Escolher pasta</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>SearchResultListModel</name>
|
||||
|
@ -7376,6 +7404,10 @@
|
|||
<source>Find Usages in Project: '%1'</source>
|
||||
<translation>Procurar usos no projeto: '%1'</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>"%1" in Folder "%2"</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>SearchResultTreeModel</name>
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -6707,6 +6707,34 @@
|
|||
<source>Abort</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>*.*</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Filters:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>...</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Folder:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Search in subfolders</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Folder</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Choose Folder</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>SearchResultListModel</name>
|
||||
|
@ -6730,6 +6758,10 @@
|
|||
<source>Find Usages in Project: '%1'</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>"%1" in Folder "%2"</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>SearchResultTreeModel</name>
|
||||
|
|
|
@ -53,7 +53,8 @@ enum class FileType{
|
|||
enum class SearchFileScope {
|
||||
currentFile,
|
||||
wholeProject,
|
||||
openedFiles
|
||||
openedFiles,
|
||||
Folder
|
||||
};
|
||||
|
||||
enum AutoSaveTarget {
|
||||
|
|
|
@ -24,10 +24,13 @@
|
|||
#include <qsynedit/searcher/regexsearcher.h>
|
||||
#include "../project.h"
|
||||
#include "../settings.h"
|
||||
#include "../systemconsts.h"
|
||||
#include <QMessageBox>
|
||||
#include <QDebug>
|
||||
#include <QProgressDialog>
|
||||
#include <QCompleter>
|
||||
#include <QStack>
|
||||
#include <QFileDialog>
|
||||
|
||||
|
||||
SearchInFileDialog::SearchInFileDialog(QWidget *parent) :
|
||||
|
@ -40,7 +43,7 @@ SearchInFileDialog::SearchInFileDialog(QWidget *parent) :
|
|||
mBasicSearchEngine= QSynedit::PSynSearchBase(new QSynedit::BasicSearcher());
|
||||
mRegexSearchEngine= QSynedit::PSynSearchBase(new QSynedit::RegexSearcher());
|
||||
ui->cbFind->completer()->setCaseSensitivity(Qt::CaseSensitive);
|
||||
|
||||
on_rbFolder_toggled(false);
|
||||
}
|
||||
|
||||
SearchInFileDialog::~SearchInFileDialog()
|
||||
|
@ -56,7 +59,7 @@ void SearchInFileDialog::findInFiles(const QString &text)
|
|||
show();
|
||||
}
|
||||
|
||||
void SearchInFileDialog::findInFiles(const QString &keyword, SearchFileScope scope, QSynedit::SearchOptions options)
|
||||
void SearchInFileDialog::findInFiles(const QString &keyword, SearchFileScope scope, QSynedit::SearchOptions options, const QString& folder, const QString& filters, bool searchSubfolders)
|
||||
{
|
||||
ui->cbFind->setCurrentText(keyword);
|
||||
ui->cbFind->setFocus();
|
||||
|
@ -71,6 +74,12 @@ void SearchInFileDialog::findInFiles(const QString &keyword, SearchFileScope sco
|
|||
case SearchFileScope::wholeProject:
|
||||
ui->rbProject->setChecked(true);
|
||||
break;
|
||||
case SearchFileScope::Folder:
|
||||
ui->txtFolder->setText(folder);
|
||||
ui->txtFilters->setText(filters);
|
||||
ui->cbSearchSubFolders->setChecked(searchSubfolders);
|
||||
ui->rbFolder->setChecked(true);
|
||||
break;
|
||||
}
|
||||
// Apply options
|
||||
ui->chkRegExp->setChecked(options.testFlag(QSynedit::ssoRegExp));
|
||||
|
@ -97,7 +106,6 @@ void SearchInFileDialog::on_btnExecute_clicked()
|
|||
|
||||
void SearchInFileDialog::doSearch(bool replace)
|
||||
{
|
||||
int findCount = 0;
|
||||
saveComboHistory(ui->cbFind,ui->cbFind->currentText());
|
||||
|
||||
mSearchOptions&=0;
|
||||
|
@ -117,7 +125,7 @@ void SearchInFileDialog::doSearch(bool replace)
|
|||
|
||||
close();
|
||||
|
||||
// Find the first one, then quit
|
||||
int findCount=0;
|
||||
int fileSearched = 0;
|
||||
int fileHitted = 0;
|
||||
QString keyword = ui->cbFind->currentText();
|
||||
|
@ -145,6 +153,97 @@ void SearchInFileDialog::doSearch(bool replace)
|
|||
}
|
||||
}
|
||||
pMainWindow->searchResultModel()->notifySearchResultsUpdated();
|
||||
} else if (ui->rbFolder->isChecked()) {
|
||||
PSearchResults results = pMainWindow->searchResultModel()->addSearchResults(
|
||||
keyword,
|
||||
mSearchOptions,
|
||||
SearchFileScope::Folder,
|
||||
ui->txtFolder->text(),
|
||||
ui->txtFilters->text(),
|
||||
ui->cbSearchSubFolders
|
||||
);
|
||||
if (ui->txtFilters->text().trimmed().isEmpty()) {
|
||||
ui->txtFilters->setText("*.*");
|
||||
}
|
||||
QDir rootDir(ui->txtFolder->text());
|
||||
// loop through editors, add results to message control
|
||||
QProgressDialog progressDlg(
|
||||
tr("Searching..."),
|
||||
tr("Abort"),
|
||||
0,
|
||||
1,
|
||||
pMainWindow);
|
||||
|
||||
progressDlg.setWindowModality(Qt::WindowModal);
|
||||
QStack<QDir> dirs;
|
||||
QSet<QString> searched;
|
||||
QList<QFileInfo> files;
|
||||
dirs.push(rootDir);
|
||||
QDir::Filters filterOptions=QDir::Files | QDir::NoSymLinks;
|
||||
if (PATH_SENSITIVITY==Qt::CaseSensitive)
|
||||
filterOptions |= QDir::CaseSensitive;
|
||||
while (!dirs.isEmpty()) {
|
||||
QDir dir=dirs.back();
|
||||
dirs.pop_back();
|
||||
foreach(const QFileInfo& entry, dir.entryInfoList(QDir::NoSymLinks | QDir::Dirs)) {
|
||||
if (entry.fileName()==".." || entry.fileName()==".")
|
||||
continue;
|
||||
if (!searched.contains(entry.absoluteFilePath())) {
|
||||
dirs.push_back(QDir(entry.absoluteFilePath()));
|
||||
searched.insert(entry.absoluteFilePath());
|
||||
}
|
||||
}
|
||||
foreach(const QFileInfo& entry, dir.entryInfoList(ui->txtFilters->text().split(";"), filterOptions)) {
|
||||
files.append(entry);
|
||||
}
|
||||
}
|
||||
progressDlg.setMaximum(files.count());
|
||||
int i=0;
|
||||
foreach (const QFileInfo &info, files) {
|
||||
QString curFilename = info.absoluteFilePath();
|
||||
i++;
|
||||
progressDlg.setValue(i);
|
||||
progressDlg.setLabelText(tr("Searching...")+"<br/>"+curFilename);
|
||||
|
||||
if (progressDlg.wasCanceled())
|
||||
break;
|
||||
Editor * e = pMainWindow->editorList()->getOpenedEditorByFilename(curFilename);
|
||||
if (e) {
|
||||
fileSearched++;
|
||||
PSearchResultTreeItem parentItem = batchFindInEditor(
|
||||
e,
|
||||
e->filename(),
|
||||
keyword);
|
||||
int t = parentItem->results.size();
|
||||
findCount+=t;
|
||||
if (t>0) {
|
||||
fileHitted++;
|
||||
results->results.append(parentItem);
|
||||
}
|
||||
} else if (fileExists(curFilename)) {
|
||||
QSynedit::QSynEdit editor;
|
||||
QByteArray realEncoding;
|
||||
try{
|
||||
editor.document()->loadFromFile(curFilename,ENCODING_AUTO_DETECT, realEncoding);
|
||||
} catch (QSynedit::BinaryFileError e) {
|
||||
continue;
|
||||
} catch (FileError e) {
|
||||
continue;
|
||||
}
|
||||
fileSearched++;
|
||||
PSearchResultTreeItem parentItem = batchFindInEditor(
|
||||
&editor,
|
||||
curFilename,
|
||||
keyword);
|
||||
int t = parentItem->results.size();
|
||||
findCount+=t;
|
||||
if (t>0) {
|
||||
fileHitted++;
|
||||
results->results.append(parentItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
pMainWindow->searchResultModel()->notifySearchResultsUpdated();
|
||||
} else if (ui->rbCurrentFile->isChecked()) {
|
||||
PSearchResults results = pMainWindow->searchResultModel()->addSearchResults(
|
||||
keyword,
|
||||
|
@ -211,7 +310,13 @@ void SearchInFileDialog::doSearch(bool replace)
|
|||
if (encoding==ENCODING_PROJECT)
|
||||
encoding = projectEncoding;
|
||||
QByteArray realEncoding;
|
||||
try {
|
||||
editor.document()->loadFromFile(curFilename,encoding, realEncoding);
|
||||
} catch (QSynedit::BinaryFileError e) {
|
||||
continue;
|
||||
} catch (FileError e) {
|
||||
continue;
|
||||
}
|
||||
fileSearched++;
|
||||
PSearchResultTreeItem parentItem = batchFindInEditor(
|
||||
&editor,
|
||||
|
@ -320,3 +425,27 @@ void SearchInFileDialog::on_btnReplace_clicked()
|
|||
doSearch(true);
|
||||
}
|
||||
|
||||
|
||||
void SearchInFileDialog::on_rbFolder_toggled(bool checked)
|
||||
{
|
||||
ui->lblFilters->setVisible(checked);
|
||||
ui->txtFilters->setVisible(checked);
|
||||
ui->lblFolder->setVisible(checked);
|
||||
ui->txtFolder->setVisible(checked);
|
||||
ui->btnChangeFolder->setVisible(checked);
|
||||
ui->cbSearchSubFolders->setVisible(checked);
|
||||
if (checked) {
|
||||
if (!directoryExists(ui->txtFolder->text()))
|
||||
ui->txtFolder->setText(pSettings->environment().currentFolder());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SearchInFileDialog::on_btnChangeFolder_clicked()
|
||||
{
|
||||
QString folder = QFileDialog::getExistingDirectory(this,tr("Choose Folder"),
|
||||
ui->txtFolder->text());
|
||||
if (directoryExists(folder))
|
||||
ui->txtFolder->setText(folder);
|
||||
}
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ public:
|
|||
explicit SearchInFileDialog(QWidget *parent = nullptr);
|
||||
~SearchInFileDialog();
|
||||
void findInFiles(const QString& text);
|
||||
void findInFiles(const QString& keyword, SearchFileScope scope, QSynedit::SearchOptions options);
|
||||
void findInFiles(const QString& keyword, SearchFileScope scope, QSynedit::SearchOptions options, const QString& folder, const QString& filters, bool searchSubfolders );
|
||||
QSynedit::PSynSearchBase searchEngine() const;
|
||||
|
||||
private slots:
|
||||
|
@ -47,6 +47,10 @@ private slots:
|
|||
void on_btnExecute_clicked();
|
||||
void on_btnReplace_clicked();
|
||||
|
||||
void on_rbFolder_toggled(bool checked);
|
||||
|
||||
void on_btnChangeFolder_clicked();
|
||||
|
||||
private:
|
||||
void doSearch(bool replace);
|
||||
int execute(QSynedit::QSynEdit* editor, const QString& sSearch,
|
||||
|
|
|
@ -53,6 +53,13 @@
|
|||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="1" column="1" colspan="2">
|
||||
<widget class="QLineEdit" name="txtFilters">
|
||||
<property name="text">
|
||||
<string>*.*</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="lblFind">
|
||||
<property name="text">
|
||||
|
@ -60,7 +67,21 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="lblFilters">
|
||||
<property name="text">
|
||||
<string>Filters:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QToolButton" name="btnChangeFolder">
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1" colspan="2">
|
||||
<widget class="QComboBox" name="cbFind">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
|
@ -76,6 +97,26 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLineEdit" name="txtFolder"/>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="lblFolder">
|
||||
<property name="text">
|
||||
<string>Folder:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="3">
|
||||
<widget class="QCheckBox" name="cbSearchSubFolders">
|
||||
<property name="text">
|
||||
<string>Search in subfolders</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -130,6 +171,13 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="rbFolder">
|
||||
<property name="text">
|
||||
<string>Folder</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#include <QStyledItemDelegate>
|
||||
#include "mainwindow.h"
|
||||
|
||||
PSearchResults SearchResultModel::addSearchResults(const QString &keyword, QSynedit::SearchOptions options, SearchFileScope scope)
|
||||
PSearchResults SearchResultModel::addSearchResults(const QString &keyword, QSynedit::SearchOptions options, SearchFileScope scope, const QString& folder, const QString& filters, bool searchSubfolders)
|
||||
{
|
||||
int index=-1;
|
||||
for (int i=0;i<mSearchResults.size();i++) {
|
||||
|
@ -42,6 +42,9 @@ PSearchResults SearchResultModel::addSearchResults(const QString &keyword, QSyne
|
|||
results->options = options;
|
||||
results->scope = scope;
|
||||
results->searchType = SearchType::Search;
|
||||
results->folder=folder;
|
||||
results->filters=filters;
|
||||
results->searchSubfolders=searchSubfolders;
|
||||
mSearchResults.push_front(results);
|
||||
mCurrentIndex = 0;
|
||||
return results;
|
||||
|
@ -384,6 +387,8 @@ QVariant SearchResultListModel::data(const QModelIndex &index, int role) const
|
|||
return tr("Files In Project:") + QString(" \"%1\"").arg(results->keyword);
|
||||
case SearchFileScope::openedFiles:
|
||||
return tr("Open Files:") + QString(" \"%1\"").arg(results->keyword);
|
||||
case SearchFileScope::Folder:
|
||||
return tr("\"%1\" in Folder \"%2\"").arg(results->keyword).arg(results->folder);
|
||||
}
|
||||
} else if (results->searchType == SearchType::FindOccurences) {
|
||||
if (results->scope == SearchFileScope::currentFile) {
|
||||
|
|
|
@ -52,6 +52,9 @@ struct SearchResults{
|
|||
SearchFileScope scope;
|
||||
SearchType searchType;
|
||||
QString filename;
|
||||
QString folder;
|
||||
QString filters;
|
||||
bool searchSubfolders;
|
||||
QList<PSearchResultTreeItem> results;
|
||||
};
|
||||
|
||||
|
@ -62,7 +65,7 @@ class SearchResultModel : public QObject {
|
|||
public:
|
||||
explicit SearchResultModel(QObject* parent=nullptr);
|
||||
PSearchResults addSearchResults(const QString& keyword,QSynedit::SearchOptions options,
|
||||
SearchFileScope scope);
|
||||
SearchFileScope scope, const QString& folder=QString(), const QString& filters=QString(), bool searchSubfolders=true);
|
||||
PSearchResults addSearchResults(
|
||||
const QString& keyword,
|
||||
const QString& symbolFullname,
|
||||
|
|
|
@ -645,6 +645,8 @@ void Document::loadFromFile(const QString& filename, const QByteArray& encoding,
|
|||
} else if (line.endsWith("\n")){
|
||||
line.remove(line.length()-1,1);
|
||||
}
|
||||
if (isBinaryContent(line))
|
||||
throw BinaryFileError(tr("This is a binaray File!"));
|
||||
if (allAscii) {
|
||||
allAscii = isTextAllAscii(line);
|
||||
}
|
||||
|
@ -1300,4 +1302,10 @@ int RedoList::itemCount()
|
|||
return mItems.count();
|
||||
}
|
||||
|
||||
BinaryFileError::BinaryFileError(const QString& reason):
|
||||
FileError(reason)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -50,6 +50,11 @@ class Document;
|
|||
|
||||
typedef std::shared_ptr<Document> PDocument;
|
||||
|
||||
class BinaryFileError : public FileError {
|
||||
public:
|
||||
explicit BinaryFileError (const QString& reason);
|
||||
};
|
||||
|
||||
class Document : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
|
|
@ -114,7 +114,7 @@ const QByteArray guessTextEncoding(const QByteArray& text){
|
|||
|
||||
bool isTextAllAscii(const QByteArray& text) {
|
||||
for (char c:text) {
|
||||
if (c<=0) {
|
||||
if (c<0 || c>127) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -724,3 +724,13 @@ QStringList absolutePaths(const QString &dirPath, const QStringList &relativePat
|
|||
}
|
||||
|
||||
|
||||
|
||||
bool isBinaryContent(const QByteArray &text)
|
||||
{
|
||||
for (char c:text) {
|
||||
if (c>=0 && c<' ' && c!='\t' && c!='\n' && c!='\r') {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -69,6 +69,7 @@ public:
|
|||
/* text processing utils */
|
||||
const QByteArray guessTextEncoding(const QByteArray& text);
|
||||
|
||||
bool isBinaryContent(const QByteArray& text);
|
||||
bool isTextAllAscii(const QByteArray& text);
|
||||
bool isTextAllAscii(const QString& text);
|
||||
|
||||
|
|
Loading…
Reference in New Issue