GUI: improve filter directory selection dialog in advanced search: list topdirs in side bar, use first topdir as start position

This commit is contained in:
Jean-Francois Dockes 2022-01-22 16:40:56 +01:00
parent 32195d0899
commit 1420533ceb
5 changed files with 69 additions and 26 deletions

View File

@ -356,18 +356,20 @@ void AdvSearch::saveFileTypes()
void AdvSearch::browsePB_clicked() void AdvSearch::browsePB_clicked()
{ {
QString dir = myGetFileName(true); auto topdirs = theconfig->getTopdirs();
// if dirlocation is not empty, it's the last location set by the user, leave it alone
if (m_gfnparams.dirlocation.isEmpty() && !topdirs.empty()) {
m_gfnparams.dirlocation = u8s2qs(topdirs[0]);
}
m_gfnparams.sidedirs = topdirs;
m_gfnparams.readonly = true;
m_gfnparams.caption = "Select directory";
QString dir = myGetFileName(true, m_gfnparams);
#ifdef _WIN32 #ifdef _WIN32
string s = qs2utf8s(dir); string s = qs2utf8s(dir);
for (string::size_type i = 0; i < s.size(); i++) { path_slashize(dir);
if (s[i] == '\\') { dir = path_slashdrive(dir);
s[i] = '/';
}
}
if (s.size() >= 2 && isalpha(s[0]) && s[1] == ':') {
s.erase(1,1);
s = string("/") + s;
}
dir = u8s2qs(s); dir = u8s2qs(s);
#endif #endif
subtreeCMB->setEditText(dir); subtreeCMB->setEditText(dir);

View File

@ -78,7 +78,8 @@ private:
bool m_ignByCats; bool m_ignByCats;
QShortcut *m_histnextsc{nullptr}; QShortcut *m_histnextsc{nullptr};
QShortcut *m_histprevsc{nullptr}; QShortcut *m_histprevsc{nullptr};
MyGFNParams m_gfnparams;
void saveCnf(); void saveCnf();
void fillFileTypes(); void fillFileTypes();
size_t stringToSize(QString); size_t stringToSize(QString);

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2005 J.F.Dockes /* Copyright (C) 2005-2022 J.F.Dockes
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
@ -425,18 +425,27 @@ int main(int argc, char **argv)
return app.exec(); return app.exec();
} }
QString myGetFileName(bool isdir, QString caption, bool filenosave, QString myGetFileName(bool isdir, QString caption, bool filenosave, QString dirloc, QString dfltnm)
QString dirloc, QString dfltnm)
{ {
LOGDEB1("myFileDialog: isdir " << isdir << "\n"); MyGFNParams parms;
QFileDialog dialog(0, caption); parms.caption = caption;
parms.filenosave = filenosave;
parms.dirlocation = dirloc;
parms.dfltnm = dfltnm;
return myGetFileName(isdir, parms);
}
QString myGetFileName(bool isdir, MyGFNParams &parms)
{
LOGDEB1("myGetFileName: isdir " << isdir << "\n");
QFileDialog dialog(0, parms.caption);
#ifdef _WIN32 #ifdef _WIN32
// The default initial directory on WIndows is the Recoll install, // The default initial directory on Windows is the Recoll install,
// which is not appropriate. Change it, only for the first call // which is not appropriate. Change it, only for the first call
// (next will start with the previous selection). // (next will start with the previous selection).
static bool first{true}; static bool first{true};
if (first) { if (first && parms.dirlocation.isEmpty()) {
first = false; first = false;
// See https://doc.qt.io/qt-5/qfiledialog.html#setDirectoryUrl // See https://doc.qt.io/qt-5/qfiledialog.html#setDirectoryUrl
// about the clsid magic (this one points to the desktop). // about the clsid magic (this one points to the desktop).
@ -444,22 +453,29 @@ QString myGetFileName(bool isdir, QString caption, bool filenosave,
QUrl("clsid:B4BFCC3A-DB2C-424C-B029-7FE99A87C641")); QUrl("clsid:B4BFCC3A-DB2C-424C-B029-7FE99A87C641"));
} }
#endif #endif
if (!dirloc.isEmpty()) { if (!parms.dirlocation.isEmpty()) {
dialog.setDirectory(dirloc); dialog.setDirectory(parms.dirlocation);
} }
if (!dfltnm.isEmpty()) { if (!parms.dfltnm.isEmpty()) {
dialog.selectFile(dfltnm); dialog.selectFile(parms.dfltnm);
}
// DontUseNativeDialog is needed for sidebarurls
QFileDialog::Options opts = QFileDialog::DontUseNativeDialog;
if (parms.readonly) {
opts |= QFileDialog::ReadOnly;
} }
if (isdir) { if (isdir) {
dialog.setFileMode(QFileDialog::Directory); dialog.setFileMode(QFileDialog::Directory);
dialog.setOptions(QFileDialog::ShowDirsOnly); opts |= QFileDialog::ShowDirsOnly;
} else { } else {
dialog.setFileMode(QFileDialog::AnyFile); dialog.setFileMode(QFileDialog::AnyFile);
if (filenosave) if (parms.filenosave)
dialog.setAcceptMode(QFileDialog::AcceptOpen); dialog.setAcceptMode(QFileDialog::AcceptOpen);
else else
dialog.setAcceptMode(QFileDialog::AcceptSave); dialog.setAcceptMode(QFileDialog::AcceptSave);
} }
dialog.setOptions(opts);
dialog.setViewMode(QFileDialog::List); dialog.setViewMode(QFileDialog::List);
QFlags<QDir::Filter> flags = QDir::NoDotAndDotDot | QDir::Hidden; QFlags<QDir::Filter> flags = QDir::NoDotAndDotDot | QDir::Hidden;
if (isdir) if (isdir)
@ -468,7 +484,15 @@ QString myGetFileName(bool isdir, QString caption, bool filenosave,
flags |= QDir::Dirs | QDir::Files; flags |= QDir::Dirs | QDir::Files;
dialog.setFilter(flags); dialog.setFilter(flags);
if (!parms.sidedirs.empty()) {
QList<QUrl> sidebarurls;
for (const auto& dir : parms.sidedirs) {
sidebarurls.push_back(QUrl::fromLocalFile(path2qs(dir)));
}
dialog.setSidebarUrls(sidebarurls);
}
if (dialog.exec() == QDialog::Accepted) { if (dialog.exec() == QDialog::Accepted) {
parms.dirlocation = dialog.directory().absolutePath();
return dialog.selectedFiles().value(0); return dialog.selectedFiles().value(0);
} }
return QString(); return QString();

View File

@ -75,12 +75,26 @@ inline std::string qs2path(const QString& qs)
#endif #endif
} }
/** Specialized version of the qt file dialog. Can't use getOpenFile() /** Specialized version of the qt file dialog. Can't use getOpenFile() etc. cause they hide dot
etc. cause they hide dot files... */ files... Need something more adaptable than the static functions but less complex than the full
dialog */
// Also : can't keep adding parms with default values, we now use an object as parameter.
class MyGFNParams {
public:
QString caption;
bool filenosave{false};
QString dirlocation; // Note: this holds the new location on return
QString dfltnm;
std::vector<std::string> sidedirs;
bool readonly{false};
};
extern QString myGetFileName(bool isdir, QString caption = QString(), extern QString myGetFileName(bool isdir, QString caption = QString(),
bool filenosave = false, bool filenosave = false,
QString dirlocation = QString(), QString dirlocation = QString(),
QString dlftnm = QString() QString dlftnm = QString()
); );
extern QString myGetFileName(bool isdir, MyGFNParams &parms);
#endif /* _RECOLL_H_INCLUDED_ */ #endif /* _RECOLL_H_INCLUDED_ */

View File

@ -325,6 +325,8 @@ string path_slashdrive(const string& path)
npath.append(1, '/'); npath.append(1, '/');
npath.append(path.substr(2)); npath.append(path.substr(2));
} }
} else {
npath = path; ///??
} }
return npath; return npath;
} }