GUI: add popup menu option to copy simple file name. fix typo keytcfn->keyctfn. Change utf8check() parms for easier usage

This commit is contained in:
Jean-Francois Dockes 2021-03-27 09:00:28 +01:00
parent fbec7a6adb
commit 8da0bf28cc
14 changed files with 91 additions and 32 deletions

View File

@ -800,7 +800,7 @@ FsIndexer::processonefile(RclConfig *config,
doc.meta[Rcl::Doc::keyfn] = utf8fn;
}
// Set container file name for all docs, top or subdoc
doc.meta[Rcl::Doc::keytcfn] = utf8fn;
doc.meta[Rcl::Doc::keyctfn] = utf8fn;
doc.pcbytes = lltodecstr(stp->pst_size);
// Document signature for up to date checks. All subdocs inherit the
@ -900,8 +900,7 @@ FsIndexer::processonefile(RclConfig *config,
fileDoc.onlyxattr = true;
} else {
fileDoc.fmtime = ascdate;
fileDoc.meta[Rcl::Doc::keyfn] =
fileDoc.meta[Rcl::Doc::keytcfn] = utf8fn;
fileDoc.meta[Rcl::Doc::keyfn] = fileDoc.meta[Rcl::Doc::keyctfn] = utf8fn;
fileDoc.haschildren = true;
fileDoc.mimetype = mimetype;
fileDoc.url = path_pathtofileurl(fn);

View File

@ -121,7 +121,7 @@ bool RecollFilter::txtdcode(const string& who)
// utf-8. We check if the text is actually utf-8. This is worth
// it, else the conversion from 8-bit is going to succeed if the
// text is already utf-8, and produce bogus data.
if (utf8check(itext, otext) >= 0) {
if (utf8check(itext) >= 0) {
m_metaData[cstr_dj_keycharset] = cstr_utf8;
return true;
}

View File

@ -1270,6 +1270,13 @@ void ResList::menuCopyFN()
ResultPopup::copyFN(doc);
}
void ResList::menuCopyPath()
{
Rcl::Doc doc;
if (getDoc(m_popDoc, doc))
ResultPopup::copyPath(doc);
}
void ResList::menuCopyText()
{
Rcl::Doc doc;

View File

@ -81,6 +81,7 @@ public slots:
virtual void menuEdit();
virtual void menuOpenWith(QAction *);
virtual void menuCopyFN();
virtual void menuCopyPath();
virtual void menuCopyURL();
virtual void menuCopyText();
virtual void menuExpand();

View File

@ -30,6 +30,7 @@
#include "respopup.h"
#include "appformime.h"
#include "rclmain_w.h"
#include "utf8iter.h"
namespace ResultPopup {
@ -95,9 +96,10 @@ QMenu *create(QWidget *me, int opts, std::shared_ptr<DocSequence> source,
}
if (doc.isFsFile()) {
popup->addAction(QWidget::tr("Copy &File Path"), me, SLOT(menuCopyFN()));
popup->addAction(QWidget::tr("Copy &File Path"), me, SLOT(menuCopyPath()));
}
popup->addAction(QWidget::tr("Copy &URL"), me, SLOT(menuCopyURL()));
popup->addAction(QWidget::tr("Copy File Name"), me, SLOT(menuCopyFN()));
popup->addAction(QWidget::tr("Copy Text"), me, SLOT(menuCopyText()));
if ((opts&showSaveOne) && !(isFsTop))
@ -158,24 +160,52 @@ Rcl::Doc getFolder(Rcl::Doc& doc)
return pdoc;
}
static const std::string twoslash{"//"};
void copyPath(const Rcl::Doc &doc)
{
auto pos = doc.url.find(twoslash);
std::string path;
if (pos == std::string::npos) {
path = doc.url; // ??
} else {
path = doc.url.substr(pos+2);
}
// Problem: setText expects a QString. Passing a (const char*) as
// we used to do causes an implicit conversion from latin1. File
// are binary and the right approach would be no conversion, but
// it's probably better (less worse...) to make a "best effort"
// tentative and try to convert from the locale's charset than
// accept the default conversion. This is unlikely to yield a
// usable path for binary paths in non-utf8 locales though.
QString qpath = path2qs(path);
QApplication::clipboard()->setText(qpath, QClipboard::Selection);
QApplication::clipboard()->setText(qpath, QClipboard::Clipboard);
}
// This is typically used to add the file name to the query string, so
// we want the values as search terms here, not the binary from the
// url.
void copyFN(const Rcl::Doc &doc)
{
// Our urls currently always begin with "file://"
//
// Problem: setText expects a QString. Passing a (const char*)
// as we used to do causes an implicit conversion from
// latin1. File are binary and the right approach would be no
// conversion, but it's probably better (less worse...) to
// make a "best effort" tentative and try to convert from the
// locale's charset than accept the default conversion.
QString qfn = path2qs(doc.url.c_str()+7);
QApplication::clipboard()->setText(qfn, QClipboard::Selection);
QApplication::clipboard()->setText(qfn, QClipboard::Clipboard);
std::string fn;
doc.getmeta(Rcl::Doc::keyfn, &fn);
QString qpath = u8s2qs(fn);
QApplication::clipboard()->setText(qpath, QClipboard::Selection);
QApplication::clipboard()->setText(qpath, QClipboard::Clipboard);
}
void copyURL(const Rcl::Doc &doc)
{
QString url = path2qs(doc.url);
QString url;
#ifdef _WIN32
url = u8s2qs(doc.url);
#else
if (utf8check(doc.url)) {
url = u8s2qs(doc.url);
} else {
url = u8s2qs(url_encode(doc.url));
}
#endif
QApplication::clipboard()->setText(url, QClipboard::Selection);
QApplication::clipboard()->setText(url, QClipboard::Clipboard);
}

View File

@ -29,6 +29,7 @@ extern Rcl::Doc getParent(std::shared_ptr<DocSequence> source,
Rcl::Doc& doc);
extern Rcl::Doc getFolder(Rcl::Doc& doc);
extern void copyFN(const Rcl::Doc &doc);
extern void copyPath(const Rcl::Doc &doc);
extern void copyURL(const Rcl::Doc &doc);
extern void copyText(Rcl::Doc &doc, RclMain *rclmain=nullptr);
};

View File

@ -1255,6 +1255,12 @@ void ResTable::menuCopyFN()
ResultPopup::copyFN(m_detaildoc);
}
void ResTable::menuCopyPath()
{
if (m_detaildocnum >= 0)
ResultPopup::copyPath(m_detaildoc);
}
void ResTable::menuCopyURL()
{
if (m_detaildocnum >= 0)

View File

@ -169,6 +169,7 @@ public slots:
virtual void menuEditAndQuit();
virtual void menuOpenWith(QAction *);
virtual void menuCopyFN();
virtual void menuCopyPath();
virtual void menuCopyURL();
virtual void menuCopyText();
virtual void menuExpand();

View File

@ -1845,10 +1845,8 @@ bool Db::addOrUpdate(const string &udi, const string &parent_udi, Doc &doc)
// purposes.
const string *fnp = 0;
if (!doc.peekmeta(Rcl::Doc::keyfn, &fnp) || fnp->empty()) {
if (doc.peekmeta(Rcl::Doc::keytcfn, &fnp) && !fnp->empty()) {
string value =
neutchars(truncate_to_word(*fnp,
m_idxMetaStoredLen), cstr_nc);
if (doc.peekmeta(Rcl::Doc::keyctfn, &fnp) && !fnp->empty()) {
string value = neutchars(truncate_to_word(*fnp, m_idxMetaStoredLen), cstr_nc);
RECORD_APPEND(record, Rcl::Doc::keyfn, value);
}
}

View File

@ -34,7 +34,7 @@ const string Doc::keydmt("dmtime");
const string Doc::keyds("dbytes");
const string Doc::keyfmt("fmtime");
const string Doc::keyfn("filename");
const string Doc::keytcfn("containerfilename");
const string Doc::keyctfn("containerfilename");
const string Doc::keyfs("fbytes");
const string Doc::keyipt("ipath");
const string Doc::keykw("keywords");

View File

@ -233,7 +233,7 @@ public:
// given top level container. It is not indexed by default but
// stored in the document record keyfn field if this is still
// empty when we create it, for display purposes.
static const std::string keytcfn;
static const std::string keyctfn;
static const std::string keyipt; // ipath
static const std::string keytp; // mime type
static const std::string keyfmt; // file mtime

View File

@ -13,6 +13,7 @@ static std::map<std::string, int> options {
{"path_home", 0},
{"path_tildexpand", 0},
{"listdir", 0},
{"url_encode", 0},
};
static const char *thisprog;
@ -55,19 +56,34 @@ int main(int argc, char **argv)
return 1;
}
string s = argv[optind];
argc--;
optind++;
if (optind != argc) {
return 1;
}
cout << "path_tildexpand(" << s << ") -> [" << path_tildexpand(s) <<
"]\n";
cout << "path_tildexpand(" << s << ") -> [" << path_tildexpand(s) << "]\n";
} else if (options["url_encode"]) {
if (optind >= argc) {
cerr << "Usage: trsmallut --url_encode <arg> [offs=0]\n";
return 1;
}
string s = argv[optind];
optind++;
int offs = 0;
if (optind != argc) {
offs = atoi(argv[optind]);
optind++;
}
if (optind != argc) {
return 1;
}
cout << "url_encode(" << s << ", " << offs << ") -> [" << url_encode(s, offs) << "]\n";
} else if (options["listdir"]) {
if (optind >= argc) {
cerr << "Usage: trsmallut --listdir <arg>\n";
return 1;
}
std::string path = argv[optind];
argc--;
optind++;
if (optind != argc) {
cerr << "Usage: trsmallut --listdir <arg>\n";
return 1;

View File

@ -94,7 +94,7 @@ size_t utf8len(const string& s)
static const std::string replchar{"\xef\xbf\xbd"};
// Check utf-8 encoding, replacing errors with the ? char above
int utf8check(const std::string& in, std::string& out, bool fixit, int maxrepl)
int utf8check(const std::string& in, bool fixit, std::string *out, int maxrepl)
{
int cnt = 0;
Utf8Iter it(in);
@ -103,7 +103,7 @@ int utf8check(const std::string& in, std::string& out, bool fixit, int maxrepl)
if (!fixit) {
return -1;
}
out += replchar;
*out += replchar;
++cnt;
for (; cnt < maxrepl; cnt++) {
it.retryfurther();
@ -111,7 +111,7 @@ int utf8check(const std::string& in, std::string& out, bool fixit, int maxrepl)
return cnt;
if (!it.error())
break;
out += replchar;
*out += replchar;
}
if (it.error()) {
return -1;
@ -119,7 +119,7 @@ int utf8check(const std::string& in, std::string& out, bool fixit, int maxrepl)
}
// We have reached a good char and eof is false
if (fixit) {
it.appendchartostring(out);
it.appendchartostring(*out);
}
}
return cnt;

View File

@ -305,6 +305,6 @@ size_t utf8len(const std::string& s);
* 0 or positive: replacement count.
*/
int utf8check(
const std::string& in, std::string& out, bool fixit=false, int maxrepl=100);
const std::string& in, bool fixit=false, std::string* out = nullptr, int maxrepl=100);
#endif /* _UTF8ITER_H_INCLUDED_ */