Gui result list: add %P substitution for parent folder and F link target for opening the parent folder

This commit is contained in:
Jean-Francois Dockes 2014-07-17 10:46:15 +02:00
parent e6b2c4434a
commit ce24fbe678
6 changed files with 59 additions and 6 deletions

View file

@ -2421,6 +2421,10 @@ fs.inotify.max_user_watches=32768
<listitem><formalpara><title>%N</title><para>result Number inside <listitem><formalpara><title>%N</title><para>result Number inside
the result page</para></formalpara> the result page</para></formalpara>
</listitem> </listitem>
<listitem><formalpara><title>%P</title><para>Parent folder
Url. In the case of an embedded document, this is the parent folder
for the top level container file.</para></formalpara>
</listitem>
<listitem><formalpara><title>%R</title><para>Relevance <listitem><formalpara><title>%R</title><para>Relevance
percentage</para></formalpara> percentage</para></formalpara>
</listitem> </listitem>
@ -2445,6 +2449,14 @@ fs.inotify.max_user_watches=32768
where <replaceable>docnum</replaceable> (%N) expands to the document where <replaceable>docnum</replaceable> (%N) expands to the document
number inside the result page).</para> number inside the result page).</para>
<para>It is also possible to use a <literal>"F%N"</literal> value
as a link target. This will open the document corresponding to the
<literal>%P</literal> parent folder expansion, usually creating a
file manager window on the folder where the container file
resides. E.g.:
<programlisting>&lt;a href="F%N"&gt;%P&lt;/a&gt;</programlisting>
</para>
<para>In addition to the predefined values above, all strings <para>In addition to the predefined values above, all strings
like <literal>%(fieldname)</literal> will be replaced by the like <literal>%(fieldname)</literal> will be replaced by the
value of the field named <literal>fieldname</literal> for this value of the field named <literal>fieldname</literal> for this
@ -5863,11 +5875,6 @@ x-my-tag = mailmytag
from a container).</para></formalpara> from a container).</para></formalpara>
</listitem> </listitem>
<listitem><formalpara><title>%F</title>
<para>Original file name. Same as %f except if a temporary
file is used.</para></formalpara>
</listitem>
<listitem><formalpara><title>%i</title> <listitem><formalpara><title>%i</title>
<para>Internal path, for subdocuments of containers. The <para>Internal path, for subdocuments of containers. The
format depends on the container type. If this appears in the format depends on the container type. If this appears in the
@ -5895,7 +5902,7 @@ x-my-tag = mailmytag
highlighting of the term.</para></formalpara> highlighting of the term.</para></formalpara>
</listitem> </listitem>
<listitem><formalpara><title>%U, %u</title> <listitem><formalpara><title>%u</title>
<para>Url.</para></formalpara> <para>Url.</para></formalpara>
</listitem> </listitem>
</itemizedlist> </itemizedlist>

View file

@ -876,6 +876,22 @@ void ResList::linkWasClicked(const QUrl &url)
} }
break; break;
// Open parent folder
case 'F':
{
int i = atoi(ascurl.c_str()+1) - 1;
Rcl::Doc doc;
if (!getDoc(i, doc)) {
LOGERR(("ResList::linkWasClicked: can't get doc for %d\n", i));
return;
}
Rcl::Doc pdoc;
pdoc.url = url_parentfolder(doc.url);
pdoc.mimetype = "inode/directory";
emit editRequested(pdoc);
}
break;
// Show query details // Show query details
case 'H': case 'H':
{ {

View file

@ -764,6 +764,16 @@ void ResTable::linkWasClicked(const QUrl &url)
m_rclmain->newDupsW(m_detaildoc, dups); m_rclmain->newDupsW(m_detaildoc, dups);
} }
} }
// Open parent folder
case 'F':
{
Rcl::Doc pdoc;
pdoc.url = url_parentfolder(m_detaildoc.url);
pdoc.mimetype = "inode/directory";
emit editRequested(pdoc);
}
break;
case 'P': case 'P':
case 'E': case 'E':
{ {

View file

@ -179,6 +179,8 @@ void ResListPager::displayDoc(RclConfig *config, int i, Rcl::Doc& doc,
titleOrFilename = utf8fn; titleOrFilename = utf8fn;
} }
string parenturl = url_parentfolder(url);
// Result number // Result number
char numbuf[20]; char numbuf[20];
int docnumforlinks = m_winfirst + 1 + i; int docnumforlinks = m_winfirst + 1 + i;
@ -286,6 +288,7 @@ void ResListPager::displayDoc(RclConfig *config, int i, Rcl::Doc& doc,
subs["L"] = linksbuf.str(); subs["L"] = linksbuf.str();
subs["N"] = numbuf; subs["N"] = numbuf;
subs["M"] = doc.mimetype; subs["M"] = doc.mimetype;
subs["P"] = parenturl;
subs["R"] = doc.meta[Rcl::Doc::keyrr]; subs["R"] = doc.meta[Rcl::Doc::keyrr];
subs["S"] = sizebuf; subs["S"] = sizebuf;
subs["T"] = maybeEscapeHtml(titleOrFilename); subs["T"] = maybeEscapeHtml(titleOrFilename);

View file

@ -525,6 +525,20 @@ string url_gpath(const string& url)
return path_canon(url.substr(colon+1)); return path_canon(url.substr(colon+1));
} }
string url_parentfolder(const string& url)
{
// In general, the parent is the directory above the full path
string parenturl = path_getfather(url_gpath(url));
// But if this is http, make sure to keep the host part. Recoll
// only has file or http urls for now.
bool isfileurl = urlisfileurl(url);
if (!isfileurl && parenturl == "/") {
parenturl = url_gpath(url);
}
return isfileurl ? string("file://") + parenturl :
string("http://") + parenturl;
}
// Convert to file path if url is like file: // Convert to file path if url is like file:
// Note: this only works with our internal pseudo-urls which are not // Note: this only works with our internal pseudo-urls which are not
// encoded/escaped // encoded/escaped
@ -540,6 +554,7 @@ string fileurltolocalpath(string url)
} }
return url; return url;
} }
bool urlisfileurl(const string& url) bool urlisfileurl(const string& url)
{ {
return url.find("file://") == 0; return url.find("file://") == 0;

View file

@ -60,6 +60,8 @@ extern bool printableUrl(const std::string &fcharset,
extern std::string fileurltolocalpath(std::string url); extern std::string fileurltolocalpath(std::string url);
/// Test for file:/// url /// Test for file:/// url
extern bool urlisfileurl(const std::string& url); extern bool urlisfileurl(const std::string& url);
///
extern std::string url_parentfolder(const std::string& url);
/// Return the host+path part of an url. This is not a general /// Return the host+path part of an url. This is not a general
/// routine, it does the right thing only in the recoll context /// routine, it does the right thing only in the recoll context