Only create the snippets menu entry if doc has pages. Add code for a snippets window link inside the result list
This commit is contained in:
parent
eca84d32cb
commit
2e0cd5bc82
7 changed files with 117 additions and 29 deletions
|
@ -2022,6 +2022,10 @@ fvwm
|
||||||
</listitem>
|
</listitem>
|
||||||
<listitem><formalpara><title>%D</title><para>Date</para></formalpara>
|
<listitem><formalpara><title>%D</title><para>Date</para></formalpara>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
<listitem><formalpara><title>%E</title><para>Precooked Snippets
|
||||||
|
link (will only appear for documents indexed with page
|
||||||
|
numbers)</para></formalpara>
|
||||||
|
</listitem>
|
||||||
<listitem><formalpara><title>%I</title><para>Icon image
|
<listitem><formalpara><title>%I</title><para>Icon image
|
||||||
name. This is normally determined from the mime type. The
|
name. This is normally determined from the mime type. The
|
||||||
associations are defined inside the
|
associations are defined inside the
|
||||||
|
@ -2907,6 +2911,17 @@ application/x-chm = execm rclchm
|
||||||
|
|
||||||
</sect2>
|
</sect2>
|
||||||
|
|
||||||
|
<sect2 id="rcl.program.filters.pages">
|
||||||
|
<title>Page numbers</title>
|
||||||
|
|
||||||
|
<para>The indexer will interpret <literal>^L</literal> characters
|
||||||
|
in the filter output as indicating page breaks, and will record
|
||||||
|
them. At query time, this allows starting a viewer on the right
|
||||||
|
page for a hit or a snippet. Currently, only the PDF filter
|
||||||
|
generates page breaks (thanks to
|
||||||
|
<literal>pdftotext</literal>).</para>
|
||||||
|
</sect2>
|
||||||
|
|
||||||
</sect1>
|
</sect1>
|
||||||
|
|
||||||
<sect1 id="rcl.program.fields">
|
<sect1 id="rcl.program.fields">
|
||||||
|
@ -4514,27 +4529,42 @@ x-my-tag = mailmytag
|
||||||
|
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
<listitem>
|
<listitem>
|
||||||
<formalpara><title>%D</title><para>Document date</para></formalpara>
|
<formalpara><title>%D</title>
|
||||||
</listitem> <listitem><formalpara><title>%f</title><para>File
|
<para>Document date</para></formalpara>
|
||||||
name. This may be the name of a temporary file if it was
|
|
||||||
necessary to create one (ie: to extract a subdocument 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><formalpara><title>%f</title>
|
||||||
|
<para>File name. This may be the name of a temporary file if
|
||||||
|
it was necessary to create one (ie: to extract a subdocument
|
||||||
|
from a container).</para></formalpara>
|
||||||
</listitem>
|
</listitem>
|
||||||
<listitem><formalpara><title>%i</title><para>Internal path, for
|
|
||||||
subdocuments of containers. The format depends on the container
|
<listitem><formalpara><title>%F</title>
|
||||||
type. If this appears in the command line, &RCL; will not create
|
<para>Original file name. Same as %f except if a temporary
|
||||||
a temporary file to extract the subdocument, expecting the called
|
file is used.</para></formalpara>
|
||||||
application (possibly a script) to be able to handle
|
|
||||||
it.</para></formalpara>
|
|
||||||
</listitem>
|
</listitem>
|
||||||
<listitem><formalpara><title>%M</title><para>Mime
|
|
||||||
type</para></formalpara>
|
<listitem><formalpara><title>%i</title>
|
||||||
|
<para>Internal path, for subdocuments of containers. The
|
||||||
|
format depends on the container type. If this appears in the
|
||||||
|
command line, &RCL; will not create a temporary file to
|
||||||
|
extract the subdocument, expecting the called application
|
||||||
|
(possibly a script) to be able to handle it.</para></formalpara>
|
||||||
</listitem>
|
</listitem>
|
||||||
<listitem><formalpara><title>%U, %u</title><para>Url.
|
|
||||||
</para></formalpara>
|
<listitem><formalpara><title>%M</title>
|
||||||
|
<para>Mime type</para></formalpara>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
<listitem><formalpara><title>%p</title>
|
||||||
|
<para>Page index. Only significant for a subset of document
|
||||||
|
types, currently only PDF files. Can be used to start the
|
||||||
|
editor at the right page for a match or
|
||||||
|
snippet.</para></formalpara>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
<listitem><formalpara><title>%U, %u</title>
|
||||||
|
<para>Url.</para></formalpara>
|
||||||
</listitem>
|
</listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
|
|
||||||
|
|
|
@ -510,7 +510,7 @@ bool ResList::getDoc(int docnum, Rcl::Doc &doc)
|
||||||
|
|
||||||
// Is docnum in current page ? Then all Ok
|
// Is docnum in current page ? Then all Ok
|
||||||
if (docnum >= winfirst && docnum <= winlast) {
|
if (docnum >= winfirst && docnum <= winlast) {
|
||||||
return m_source->getDoc(docnum, doc);
|
return m_pager->getDoc(docnum, doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Else we accept to page down or up but not further
|
// Else we accept to page down or up but not further
|
||||||
|
@ -522,7 +522,7 @@ bool ResList::getDoc(int docnum, Rcl::Doc &doc)
|
||||||
winfirst = pageFirstDocNum();
|
winfirst = pageFirstDocNum();
|
||||||
winlast = m_pager->pageLastDocNum();
|
winlast = m_pager->pageLastDocNum();
|
||||||
if (docnum >= winfirst && docnum <= winlast) {
|
if (docnum >= winfirst && docnum <= winlast) {
|
||||||
return m_source->getDoc(docnum, doc);
|
return m_pager->getDoc(docnum, doc);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -801,6 +801,16 @@ void ResList::mouseDoubleClickEvent(QMouseEvent *event)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ResList::newSnippetsW(const Rcl::Doc& doc)
|
||||||
|
{
|
||||||
|
SnippetsW *sp = new SnippetsW(doc, m_source);
|
||||||
|
if (m_parent) {
|
||||||
|
connect(sp, SIGNAL(startNativeViewer(Rcl::Doc, int)),
|
||||||
|
m_parent, SLOT(startNativeViewer(Rcl::Doc, int)));
|
||||||
|
}
|
||||||
|
sp->show();
|
||||||
|
}
|
||||||
|
|
||||||
void ResList::linkWasClicked(const QUrl &url)
|
void ResList::linkWasClicked(const QUrl &url)
|
||||||
{
|
{
|
||||||
string ascurl = (const char *)url.toString().toAscii();;
|
string ascurl = (const char *)url.toString().toAscii();;
|
||||||
|
@ -808,9 +818,27 @@ void ResList::linkWasClicked(const QUrl &url)
|
||||||
|
|
||||||
int what = ascurl[0];
|
int what = ascurl[0];
|
||||||
switch (what) {
|
switch (what) {
|
||||||
|
// Open abstract/snippets window
|
||||||
|
case 'A':
|
||||||
|
{
|
||||||
|
if (m_source.isNull())
|
||||||
|
return;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
newSnippetsW(doc);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Show query details
|
||||||
case 'H':
|
case 'H':
|
||||||
emit headerClicked();
|
emit headerClicked();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// Preview and edit
|
||||||
case 'P':
|
case 'P':
|
||||||
case 'E':
|
case 'E':
|
||||||
{
|
{
|
||||||
|
@ -826,12 +854,16 @@ void ResList::linkWasClicked(const QUrl &url)
|
||||||
emit docEditClicked(doc);
|
emit docEditClicked(doc);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// Next/prev page
|
||||||
case 'n':
|
case 'n':
|
||||||
resultPageNext();
|
resultPageNext();
|
||||||
break;
|
break;
|
||||||
case 'p':
|
case 'p':
|
||||||
resultPageBack();
|
resultPageBack();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// Spelling: replacement suggestion clicked
|
||||||
case 'S':
|
case 'S':
|
||||||
{
|
{
|
||||||
QString s = url.toString();
|
QString s = url.toString();
|
||||||
|
@ -845,6 +877,7 @@ void ResList::linkWasClicked(const QUrl &url)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
LOGERR(("ResList::linkWasClicked: bad link [%s]\n", ascurl.c_str()));
|
LOGERR(("ResList::linkWasClicked: bad link [%s]\n", ascurl.c_str()));
|
||||||
break;// ??
|
break;// ??
|
||||||
|
@ -897,7 +930,7 @@ void ResList::createPopupMenu(const QPoint& pos)
|
||||||
this, SLOT(menuPreviewParent()));
|
this, SLOT(menuPreviewParent()));
|
||||||
popup->addAction(tr("&Open Parent document/folder"),
|
popup->addAction(tr("&Open Parent document/folder"),
|
||||||
this, SLOT(menuOpenParent()));
|
this, SLOT(menuOpenParent()));
|
||||||
if (m_source->snippetsCapable())
|
if (havedoc && doc.haspages && m_source->snippetsCapable())
|
||||||
popup->addAction(tr("Open &Snippets window"),
|
popup->addAction(tr("Open &Snippets window"),
|
||||||
this, SLOT(menuOpenSnippets()));
|
this, SLOT(menuOpenSnippets()));
|
||||||
popup->popup(mapToGlobal(pos));
|
popup->popup(mapToGlobal(pos));
|
||||||
|
@ -956,13 +989,7 @@ void ResList::menuOpenSnippets()
|
||||||
Rcl::Doc doc;
|
Rcl::Doc doc;
|
||||||
if (!getDoc(m_popDoc, doc) || m_source.isNull())
|
if (!getDoc(m_popDoc, doc) || m_source.isNull())
|
||||||
return;
|
return;
|
||||||
SnippetsW *sp = new SnippetsW(doc, m_source);
|
newSnippetsW(doc);
|
||||||
if (m_parent) {
|
|
||||||
connect(sp, SIGNAL(startNativeViewer(Rcl::Doc, int)),
|
|
||||||
m_parent, SLOT(startNativeViewer(Rcl::Doc, int)));
|
|
||||||
}
|
|
||||||
|
|
||||||
sp->show();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResList::menuEdit()
|
void ResList::menuEdit()
|
||||||
|
|
|
@ -145,6 +145,7 @@ class ResList : public RESLIST_PARENTCLASS
|
||||||
bool scrollIsAtTop();
|
bool scrollIsAtTop();
|
||||||
bool scrollIsAtBottom();
|
bool scrollIsAtBottom();
|
||||||
void setupArrows();
|
void setupArrows();
|
||||||
|
void newSnippetsW(const Rcl::Doc &doc);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -232,6 +232,11 @@ void ResListPager::displayDoc(RclConfig *config, int i, Rcl::Doc& doc,
|
||||||
linksbuf << "<a href=\"E" << docnumforlinks << "\">"
|
linksbuf << "<a href=\"E" << docnumforlinks << "\">"
|
||||||
<< trans("Open") << "</a>";
|
<< trans("Open") << "</a>";
|
||||||
}
|
}
|
||||||
|
ostringstream snipsbuf;
|
||||||
|
if (doc.haspages) {
|
||||||
|
snipsbuf << "<a href=\"A" << docnumforlinks << "\">"
|
||||||
|
<< trans("Snippets") << "</a> ";
|
||||||
|
}
|
||||||
|
|
||||||
// Build the result list paragraph:
|
// Build the result list paragraph:
|
||||||
|
|
||||||
|
@ -245,6 +250,7 @@ void ResListPager::displayDoc(RclConfig *config, int i, Rcl::Doc& doc,
|
||||||
map<string, string> subs;
|
map<string, string> subs;
|
||||||
subs["A"] = !richabst.empty() ? richabst : "";
|
subs["A"] = !richabst.empty() ? richabst : "";
|
||||||
subs["D"] = datebuf;
|
subs["D"] = datebuf;
|
||||||
|
subs["E"] = snipsbuf.rdbuf()->str();
|
||||||
subs["I"] = iconurl;
|
subs["I"] = iconurl;
|
||||||
subs["i"] = doc.ipath;
|
subs["i"] = doc.ipath;
|
||||||
subs["K"] = !doc.meta[Rcl::Doc::keykw].empty() ?
|
subs["K"] = !doc.meta[Rcl::Doc::keykw].empty() ?
|
||||||
|
@ -279,6 +285,16 @@ void ResListPager::displayDoc(RclConfig *config, int i, Rcl::Doc& doc,
|
||||||
append(chunk.rdbuf()->str(), i, doc);
|
append(chunk.rdbuf()->str(), i, doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ResListPager::getDoc(int num, Rcl::Doc& doc)
|
||||||
|
{
|
||||||
|
if (m_winfirst < 0 || m_respage.size() == 0)
|
||||||
|
return false;
|
||||||
|
if (num < m_winfirst || num >= m_winfirst + int(m_respage.size()))
|
||||||
|
return false;
|
||||||
|
doc = m_respage[num-m_winfirst].doc;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void ResListPager::displayPage(RclConfig *config)
|
void ResListPager::displayPage(RclConfig *config)
|
||||||
{
|
{
|
||||||
LOGDEB(("ResListPager::displayPage\n"));
|
LOGDEB(("ResListPager::displayPage\n"));
|
||||||
|
@ -384,7 +400,7 @@ void ResListPager::displayPage(RclConfig *config)
|
||||||
// Emit data for result entry paragraph. Do it in chunks that make sense
|
// Emit data for result entry paragraph. Do it in chunks that make sense
|
||||||
// html-wise, else our client may get confused
|
// html-wise, else our client may get confused
|
||||||
for (int i = 0; i < (int)m_respage.size(); i++) {
|
for (int i = 0; i < (int)m_respage.size(); i++) {
|
||||||
Rcl::Doc &doc(m_respage[i].doc);
|
Rcl::Doc& doc(m_respage[i].doc);
|
||||||
string& sh(m_respage[i].subHeader);
|
string& sh(m_respage[i].subHeader);
|
||||||
displayDoc(config, i, doc, hdata, sh);
|
displayDoc(config, i, doc, hdata, sh);
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,6 +90,8 @@ public:
|
||||||
string queryDescription() {return m_docSource.isNull() ? "" :
|
string queryDescription() {return m_docSource.isNull() ? "" :
|
||||||
m_docSource->getDescription();}
|
m_docSource->getDescription();}
|
||||||
|
|
||||||
|
bool getDoc(int num, Rcl::Doc &doc);
|
||||||
|
|
||||||
// Things that need to be reimplemented in the subclass:
|
// Things that need to be reimplemented in the subclass:
|
||||||
virtual bool append(const string& data);
|
virtual bool append(const string& data);
|
||||||
virtual bool append(const string& data, int, const Rcl::Doc&)
|
virtual bool append(const string& data, int, const Rcl::Doc&)
|
||||||
|
|
|
@ -112,10 +112,17 @@ class Doc {
|
||||||
// and indexed
|
// and indexed
|
||||||
string text;
|
string text;
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////
|
||||||
|
// Misc stuff
|
||||||
|
|
||||||
int pc; // relevancy percentage, used by sortseq, convenience
|
int pc; // relevancy percentage, used by sortseq, convenience
|
||||||
unsigned long xdocid; // Opaque: rcldb doc identifier.
|
unsigned long xdocid; // Opaque: rcldb doc identifier.
|
||||||
|
|
||||||
|
// Page breaks were stored during indexing.
|
||||||
|
bool haspages;
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void erase() {
|
void erase() {
|
||||||
url.erase();
|
url.erase();
|
||||||
ipath.erase();
|
ipath.erase();
|
||||||
|
@ -133,8 +140,12 @@ class Doc {
|
||||||
text.erase();
|
text.erase();
|
||||||
pc = 0;
|
pc = 0;
|
||||||
xdocid = 0;
|
xdocid = 0;
|
||||||
|
haspages = false;
|
||||||
|
}
|
||||||
|
Doc()
|
||||||
|
: syntabs(false), pc(0), xdocid(0), haspages(false)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Get value for named field. If value pointer is 0, just test existence */
|
/** Get value for named field. If value pointer is 0, just test existence */
|
||||||
bool getmeta(const string& nm, string *value = 0) const
|
bool getmeta(const string& nm, string *value = 0) const
|
||||||
{
|
{
|
||||||
|
|
|
@ -325,6 +325,7 @@ bool Query::makeDocAbstract(Doc &doc, vector<string>& abstract)
|
||||||
it != vpabs.end(); it++) {
|
it != vpabs.end(); it++) {
|
||||||
string chunk;
|
string chunk;
|
||||||
if (it->first > 0) {
|
if (it->first > 0) {
|
||||||
|
doc.haspages = true;
|
||||||
ostringstream ss;
|
ostringstream ss;
|
||||||
ss << it->first;
|
ss << it->first;
|
||||||
chunk += string(" [p ") + ss.str() + "] ";
|
chunk += string(" [p ") + ss.str() + "] ";
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue