|
a/src/qtgui/rclmain_w.cpp |
|
b/src/qtgui/rclmain_w.cpp |
|
... |
|
... |
1499 |
return false;
|
1499 |
return false;
|
1500 |
}
|
1500 |
}
|
1501 |
|
1501 |
|
1502 |
void RclMain::startNativeViewer(Rcl::Doc doc, int pagenum, QString term)
|
1502 |
void RclMain::startNativeViewer(Rcl::Doc doc, int pagenum, QString term)
|
1503 |
{
|
1503 |
{
|
1504 |
LOGDEB(("RclMain::startNativeViewer: page %d\n", pagenum));
|
|
|
1505 |
// Look for appropriate viewer
|
|
|
1506 |
string apptag;
|
1504 |
string apptag;
|
1507 |
doc.getmeta(Rcl::Doc::keyapptg, &apptag);
|
1505 |
doc.getmeta(Rcl::Doc::keyapptg, &apptag);
|
|
|
1506 |
LOGDEB(("RclMain::startNativeViewer: mtype [%s] apptag [%s] page %d "
|
|
|
1507 |
"term [%s] url [%s] ipath [%s]\n",
|
|
|
1508 |
doc.mimetype.c_str(), apptag.c_str(), pagenum,
|
|
|
1509 |
(const char *)(term.toUtf8()), doc.url.c_str(), doc.ipath.c_str()
|
|
|
1510 |
));
|
|
|
1511 |
|
|
|
1512 |
// Look for appropriate viewer
|
1508 |
string cmdplusattr = theconfig->getMimeViewerDef(doc.mimetype, apptag,
|
1513 |
string cmdplusattr = theconfig->getMimeViewerDef(doc.mimetype, apptag,
|
1509 |
prefs.useDesktopOpen);
|
1514 |
prefs.useDesktopOpen);
|
1510 |
|
|
|
1511 |
if (cmdplusattr.empty()) {
|
1515 |
if (cmdplusattr.empty()) {
|
1512 |
QMessageBox::warning(0, "Recoll",
|
1516 |
QMessageBox::warning(0, "Recoll",
|
1513 |
tr("No external viewer configured for mime type [")
|
1517 |
tr("No external viewer configured for mime type [")
|
1514 |
+ doc.mimetype.c_str() + "]");
|
1518 |
+ doc.mimetype.c_str() + "]");
|
1515 |
return;
|
1519 |
return;
|
1516 |
}
|
1520 |
}
|
1517 |
|
1521 |
|
1518 |
if (pagenum == -1) {
|
1522 |
// Separate command string and viewer attributes (if any)
|
1519 |
pagenum = 1;
|
|
|
1520 |
string lterm;
|
|
|
1521 |
if (m_source.isNotNull())
|
|
|
1522 |
pagenum = m_source->getFirstMatchPage(doc, lterm);
|
|
|
1523 |
if (pagenum == -1)
|
|
|
1524 |
pagenum = 1;
|
|
|
1525 |
else
|
|
|
1526 |
term = QString::fromUtf8(lterm.c_str());
|
|
|
1527 |
}
|
|
|
1528 |
char cpagenum[20];
|
|
|
1529 |
sprintf(cpagenum, "%d", pagenum);
|
|
|
1530 |
|
|
|
1531 |
// Extract possible viewer attributes
|
|
|
1532 |
ConfSimple attrs;
|
1523 |
ConfSimple viewerattrs;
|
1533 |
string cmd;
|
1524 |
string cmd;
|
1534 |
theconfig->valueSplitAttributes(cmdplusattr, cmd, attrs);
|
1525 |
theconfig->valueSplitAttributes(cmdplusattr, cmd, viewerattrs);
|
1535 |
bool ignoreipath = false;
|
1526 |
bool ignoreipath = false;
|
1536 |
if (attrs.get("ignoreipath", cmdplusattr))
|
1527 |
if (viewerattrs.get("ignoreipath", cmdplusattr))
|
1537 |
ignoreipath = stringToBool(cmdplusattr);
|
1528 |
ignoreipath = stringToBool(cmdplusattr);
|
1538 |
|
1529 |
|
1539 |
// Split the command line
|
1530 |
// Split the command line
|
1540 |
vector<string> lcmd;
|
1531 |
vector<string> lcmd;
|
1541 |
if (!stringToStrings(cmd, lcmd)) {
|
1532 |
if (!stringToStrings(cmd, lcmd)) {
|
1542 |
QMessageBox::warning(0, "Recoll",
|
1533 |
QMessageBox::warning(0, "Recoll",
|
1543 |
tr("Bad viewer command line for %1: [%2]\n"
|
1534 |
tr("Bad viewer command line for %1: [%2]\n"
|
1544 |
"Please check the mimeconf file")
|
1535 |
"Please check the mimeview file")
|
1545 |
.arg(QString::fromAscii(doc.mimetype.c_str()))
|
1536 |
.arg(QString::fromAscii(doc.mimetype.c_str()))
|
1546 |
.arg(QString::fromLocal8Bit(cmd.c_str())));
|
1537 |
.arg(QString::fromLocal8Bit(cmd.c_str())));
|
1547 |
return;
|
1538 |
return;
|
1548 |
}
|
1539 |
}
|
1549 |
|
1540 |
|
1550 |
// Look for the command to execute in the exec path and the filters
|
1541 |
// Look for the command to execute in the exec path and the filters
|
1551 |
// directory
|
1542 |
// directory
|
1552 |
string cmdpath;
|
1543 |
string execpath;
|
1553 |
if (!ExecCmd::which(lcmd.front(), cmdpath)) {
|
1544 |
if (!ExecCmd::which(lcmd.front(), execpath)) {
|
1554 |
cmdpath = theconfig->findFilter(lcmd.front());
|
1545 |
execpath = theconfig->findFilter(lcmd.front());
|
1555 |
// findFilter returns its input param if the filter is not in
|
1546 |
// findFilter returns its input param if the filter is not in
|
1556 |
// the normal places. As we already looked in the path, we
|
1547 |
// the normal places. As we already looked in the path, we
|
1557 |
// have no use for a simple command name here (as opposed to
|
1548 |
// have no use for a simple command name here (as opposed to
|
1558 |
// mimehandler which will just let execvp do its thing). Erase
|
1549 |
// mimehandler which will just let execvp do its thing). Erase
|
1559 |
// cmdpath so that the user dialog will be started further
|
1550 |
// execpath so that the user dialog will be started further
|
1560 |
// down.
|
1551 |
// down.
|
1561 |
if (!cmdpath.compare(lcmd.front()))
|
1552 |
if (!execpath.compare(lcmd.front()))
|
1562 |
cmdpath.erase();
|
1553 |
execpath.erase();
|
1563 |
|
1554 |
|
1564 |
// Specialcase text/html because of the help browser need
|
1555 |
// Specialcase text/html because of the help browser need
|
1565 |
if (cmdpath.empty() && !doc.mimetype.compare("text/html")) {
|
1556 |
if (execpath.empty() && !doc.mimetype.compare("text/html")) {
|
1566 |
if (lookForHtmlBrowser(cmdpath)) {
|
1557 |
if (lookForHtmlBrowser(execpath)) {
|
1567 |
lcmd.clear();
|
1558 |
lcmd.clear();
|
1568 |
lcmd.push_back(cmdpath);
|
1559 |
lcmd.push_back(execpath);
|
1569 |
lcmd.push_back("%u");
|
1560 |
lcmd.push_back("%u");
|
1570 |
}
|
1561 |
}
|
1571 |
}
|
1562 |
}
|
1572 |
}
|
1563 |
}
|
1573 |
|
1564 |
|
1574 |
|
1565 |
|
1575 |
// Command not found: start the user dialog to help find another one:
|
1566 |
// Command not found: start the user dialog to help find another one:
|
1576 |
if (cmdpath.empty()) {
|
1567 |
if (execpath.empty()) {
|
1577 |
QString mt = QString::fromAscii(doc.mimetype.c_str());
|
1568 |
QString mt = QString::fromAscii(doc.mimetype.c_str());
|
1578 |
QString message = tr("The viewer specified in mimeview for %1: %2"
|
1569 |
QString message = tr("The viewer specified in mimeview for %1: %2"
|
1579 |
" is not found.\nDo you want to start the "
|
1570 |
" is not found.\nDo you want to start the "
|
1580 |
" preferences dialog ?")
|
1571 |
" preferences dialog ?")
|
1581 |
.arg(mt).arg(QString::fromLocal8Bit(lcmd.front().c_str()));
|
1572 |
.arg(mt).arg(QString::fromLocal8Bit(lcmd.front().c_str()));
|
|
... |
|
... |
1592 |
}
|
1583 |
}
|
1593 |
// The user will have to click on the link again to try the
|
1584 |
// The user will have to click on the link again to try the
|
1594 |
// new command.
|
1585 |
// new command.
|
1595 |
return;
|
1586 |
return;
|
1596 |
}
|
1587 |
}
|
|
|
1588 |
// Get rid of the command name. lcmd is now argv[1...n]
|
|
|
1589 |
lcmd.erase(lcmd.begin());
|
1597 |
|
1590 |
|
1598 |
// We may need a temp file, or not, depending on the command
|
1591 |
|
1599 |
// arguments and the fact that this is a subdoc or not.
|
1592 |
// Process the command arguments to determine if we need to create
|
|
|
1593 |
// a temporary file.
|
|
|
1594 |
|
|
|
1595 |
// If the command has a %i parameter it will manage the
|
|
|
1596 |
// un-embedding. Else if ipath is not empty, we need a temp file.
|
|
|
1597 |
// This can be overridden with the "ignoreipath" attribute
|
1600 |
bool wantsipath = (cmd.find("%i") != string::npos) || ignoreipath;
|
1598 |
bool groksipath = (cmd.find("%i") != string::npos) || ignoreipath;
|
|
|
1599 |
|
|
|
1600 |
// wantsfile: do we actually need a local file ? The only other
|
|
|
1601 |
// case here is an url %u (ie: for web history).
|
1601 |
bool wantsfile = cmd.find("%f") != string::npos;
|
1602 |
bool wantsfile = cmd.find("%f") != string::npos;
|
|
|
1603 |
bool wantsparentfile = cmd.find("%F") != string::npos;
|
|
|
1604 |
|
|
|
1605 |
if (wantsfile && wantsparentfile) {
|
|
|
1606 |
QMessageBox::warning(0, "Recoll",
|
|
|
1607 |
tr("Viewer command line for %1 specifies both "
|
|
|
1608 |
"file and parent file value: unsupported")
|
|
|
1609 |
.arg(QString::fromAscii(doc.mimetype.c_str())));
|
|
|
1610 |
return;
|
|
|
1611 |
}
|
|
|
1612 |
|
|
|
1613 |
string url = doc.url;
|
|
|
1614 |
string fn = fileurltolocalpath(doc.url);
|
|
|
1615 |
Rcl::Doc pdoc;
|
|
|
1616 |
if (wantsparentfile) {
|
|
|
1617 |
// We want the path for the parent document. For example to
|
|
|
1618 |
// open the chm file, not the internal page. Note that we just
|
|
|
1619 |
// override the other file name in this case.
|
|
|
1620 |
if (m_source.isNull() || !m_source->getEnclosing(doc, pdoc)) {
|
|
|
1621 |
QMessageBox::warning(0, "Recoll",
|
|
|
1622 |
tr("Cannot find parent document"));
|
|
|
1623 |
return;
|
|
|
1624 |
}
|
|
|
1625 |
// Override fn with the parent's :
|
|
|
1626 |
fn = fileurltolocalpath(pdoc.url);
|
|
|
1627 |
|
|
|
1628 |
// If the parent document has an ipath too, we need to create
|
|
|
1629 |
// a temp file even if the command takes an ipath
|
|
|
1630 |
// parameter. We have no viewer which could handle a double
|
|
|
1631 |
// embedding. Will have to change if such a one appears.
|
|
|
1632 |
if (!pdoc.ipath.empty()) {
|
|
|
1633 |
groksipath = false;
|
|
|
1634 |
}
|
|
|
1635 |
}
|
|
|
1636 |
|
1602 |
bool istempfile = false;
|
1637 |
bool istempfile = false;
|
1603 |
string fn = fileurltolocalpath(doc.url);
|
1638 |
|
1604 |
string orgfn = fn;
|
1639 |
LOGDEB(("RclMain::startNV: groksipath %d wantsf %d wantsparentf %d\n",
|
1605 |
string url = doc.url;
|
1640 |
groksipath, wantsfile, wantsparentfile));
|
1606 |
|
1641 |
|
1607 |
// If the command wants a file but this is not a file url, or
|
1642 |
// If the command wants a file but this is not a file url, or
|
1608 |
// there is an ipath that it won't understand, we need a temp file:
|
1643 |
// there is an ipath that it won't understand, we need a temp file:
|
1609 |
theconfig->setKeyDir(path_getfather(fn));
|
1644 |
theconfig->setKeyDir(path_getfather(fn));
|
1610 |
if ((wantsfile && fn.empty()) || (!wantsipath && !doc.ipath.empty())) {
|
1645 |
if (((wantsfile || wantsparentfile) && fn.empty()) ||
|
|
|
1646 |
(!groksipath && !doc.ipath.empty())) {
|
1611 |
TempFile temp;
|
1647 |
TempFile temp;
|
|
|
1648 |
Rcl::Doc& thedoc = wantsparentfile ? pdoc : doc;
|
1612 |
if (!FileInterner::idocToFile(temp, string(), theconfig, doc)) {
|
1649 |
if (!FileInterner::idocToFile(temp, string(), theconfig, thedoc)) {
|
1613 |
QMessageBox::warning(0, "Recoll",
|
1650 |
QMessageBox::warning(0, "Recoll",
|
1614 |
tr("Cannot extract document or create "
|
1651 |
tr("Cannot extract document or create "
|
1615 |
"temporary file"));
|
1652 |
"temporary file"));
|
1616 |
return;
|
1653 |
return;
|
1617 |
}
|
1654 |
}
|
|
... |
|
... |
1645 |
fn = temp->filename();
|
1682 |
fn = temp->filename();
|
1646 |
url = string("file://") + fn;
|
1683 |
url = string("file://") + fn;
|
1647 |
}
|
1684 |
}
|
1648 |
}
|
1685 |
}
|
1649 |
|
1686 |
|
1650 |
// Get rid of the command name. lcmd is now argv[1...n]
|
1687 |
// If we are not called with a page number (which would happen for a call
|
1651 |
lcmd.erase(lcmd.begin());
|
1688 |
// from the snippets window), see if we can compute a page number anyway.
|
|
|
1689 |
if (pagenum == -1) {
|
|
|
1690 |
pagenum = 1;
|
|
|
1691 |
string lterm;
|
|
|
1692 |
if (m_source.isNotNull())
|
|
|
1693 |
pagenum = m_source->getFirstMatchPage(doc, lterm);
|
|
|
1694 |
if (pagenum == -1)
|
|
|
1695 |
pagenum = 1;
|
|
|
1696 |
else // We get the match term used to compute the page
|
|
|
1697 |
term = QString::fromUtf8(lterm.c_str());
|
|
|
1698 |
}
|
|
|
1699 |
char cpagenum[20];
|
|
|
1700 |
sprintf(cpagenum, "%d", pagenum);
|
|
|
1701 |
|
1652 |
|
1702 |
|
1653 |
// Substitute %xx inside arguments
|
1703 |
// Substitute %xx inside arguments
|
1654 |
string efftime;
|
1704 |
string efftime;
|
1655 |
if (!doc.dmtime.empty() || !doc.fmtime.empty()) {
|
1705 |
if (!doc.dmtime.empty() || !doc.fmtime.empty()) {
|
1656 |
efftime = doc.dmtime.empty() ? doc.fmtime : doc.dmtime;
|
1706 |
efftime = doc.dmtime.empty() ? doc.fmtime : doc.dmtime;
|
|
... |
|
... |
1660 |
// Try to keep the letters used more or less consistent with the reslist
|
1710 |
// Try to keep the letters used more or less consistent with the reslist
|
1661 |
// paragraph format.
|
1711 |
// paragraph format.
|
1662 |
map<string, string> subs;
|
1712 |
map<string, string> subs;
|
1663 |
subs["D"] = efftime;
|
1713 |
subs["D"] = efftime;
|
1664 |
subs["f"] = fn;
|
1714 |
subs["f"] = fn;
|
1665 |
subs["F"] = orgfn;
|
1715 |
subs["F"] = fn;
|
1666 |
subs["i"] = doc.ipath;
|
1716 |
subs["i"] = FileInterner::getLastIpathElt(doc.ipath);
|
1667 |
subs["M"] = doc.mimetype;
|
1717 |
subs["M"] = doc.mimetype;
|
1668 |
subs["p"] = cpagenum;
|
1718 |
subs["p"] = cpagenum;
|
1669 |
subs["s"] = (const char*)term.toLocal8Bit();
|
1719 |
subs["s"] = (const char*)term.toLocal8Bit();
|
1670 |
subs["U"] = url;
|
1720 |
subs["U"] = url;
|
1671 |
subs["u"] = url;
|
1721 |
subs["u"] = url;
|
|
... |
|
... |
1703 |
zg_send_event(ZGSEND_OPEN, doc);
|
1753 |
zg_send_event(ZGSEND_OPEN, doc);
|
1704 |
|
1754 |
|
1705 |
// We keep pushing back and never deleting. This can't be good...
|
1755 |
// We keep pushing back and never deleting. This can't be good...
|
1706 |
ExecCmd *ecmd = new ExecCmd;
|
1756 |
ExecCmd *ecmd = new ExecCmd;
|
1707 |
m_viewers.push_back(ecmd);
|
1757 |
m_viewers.push_back(ecmd);
|
1708 |
ecmd->startExec(cmdpath, lcmd, false, false);
|
1758 |
ecmd->startExec(execpath, lcmd, false, false);
|
1709 |
}
|
1759 |
}
|
1710 |
|
1760 |
|
1711 |
void RclMain::startManual()
|
1761 |
void RclMain::startManual()
|
1712 |
{
|
1762 |
{
|
1713 |
startManual(string());
|
1763 |
startManual(string());
|