GUI: result table: when displaying content in the detail area, if the doc is a free-standing image, display it
This commit is contained in:
parent
ae8fd0902a
commit
e6055681d4
@ -61,6 +61,7 @@
|
||||
#include "preview_plaintorich.h"
|
||||
#include "rclmain_w.h"
|
||||
#include "scbase.h"
|
||||
#include "appformime.h"
|
||||
|
||||
// Make an attempt at trimming wildcard exprs at both ends of string
|
||||
static void trimwildcards(string& elt)
|
||||
@ -945,18 +946,16 @@ bool Preview::loadDocInCurrentTab(const Rcl::Doc &idoc, int docnum)
|
||||
editor->displayFields();
|
||||
|
||||
// If this is an image, display it instead of the text.
|
||||
if (!idoc.mimetype.compare(0, 6, "image/")) {
|
||||
if (mimeIsImage(idoc.mimetype)) {
|
||||
string fn = fileurltolocalpath(idoc.url);
|
||||
theconfig->setKeyDir(fn.empty() ? "" : path_getfather(fn));
|
||||
|
||||
// We want a real file, so if this comes from data or we have
|
||||
// an ipath, create it.
|
||||
// We want a real file, so if this comes from data or we have an ipath, create it.
|
||||
if (fn.empty() || !idoc.ipath.empty()) {
|
||||
TempFile temp = lthr.tmpimg;
|
||||
if (temp.ok()) {
|
||||
LOGDEB1("Preview: load: got temp file from internfile\n");
|
||||
} else if (!FileInterner::idocToFile(temp, string(),
|
||||
theconfig, idoc)) {
|
||||
} else if (!FileInterner::idocToFile(temp, string(), theconfig, idoc)) {
|
||||
temp = TempFile(); // just in case.
|
||||
}
|
||||
if (temp.ok()) {
|
||||
@ -1137,10 +1136,8 @@ void PreviewTextEdit::displayImage()
|
||||
m_image.height() > height()) {
|
||||
m_image = m_image.scaled(width(), height(), Qt::KeepAspectRatio);
|
||||
}
|
||||
document()->addResource(QTextDocument::ImageResource, QUrl("image"),
|
||||
m_image);
|
||||
QTextCursor cursor = textCursor();
|
||||
cursor.insertImage("image");
|
||||
document()->addResource(QTextDocument::ImageResource, QUrl("image"), m_image);
|
||||
textCursor().insertImage("image");
|
||||
m_curdsp = PTE_DSPIMG;
|
||||
}
|
||||
|
||||
|
||||
@ -147,9 +147,8 @@ void ResTableDetailArea::createPopupMenu(const QPoint& pos)
|
||||
if (m_table && m_table->m_model && m_table->m_detaildocnum >= 0) {
|
||||
int opts = m_table->m_ismainres ? ResultPopup::showExpand : 0;
|
||||
opts |= ResultPopup::showSaveOne;
|
||||
QMenu *popup = ResultPopup::create(m_table, opts,
|
||||
m_table->m_model->getDocSource(),
|
||||
m_table->m_detaildoc);
|
||||
QMenu *popup = ResultPopup::create(
|
||||
m_table, opts, m_table->m_model->getDocSource(), m_table->m_detaildoc);
|
||||
popup->popup(mapToGlobal(pos));
|
||||
}
|
||||
}
|
||||
@ -669,8 +668,7 @@ void ResTable::init()
|
||||
m_detail->setOpenLinks(false);
|
||||
m_detail->init();
|
||||
// signals and slots connections
|
||||
connect(m_detail, SIGNAL(anchorClicked(const QUrl &)),
|
||||
this, SLOT(linkWasClicked(const QUrl &)));
|
||||
connect(m_detail, SIGNAL(anchorClicked(const QUrl&)), this, SLOT(linkWasClicked(const QUrl&)));
|
||||
splitter->addWidget(m_detail);
|
||||
splitter->setOrientation(Qt::Vertical);
|
||||
QVariant saved = settings.value(settingskey_splittersizes);
|
||||
@ -767,21 +765,15 @@ void ResTable::setRclMain(RclMain *m, bool ismain)
|
||||
tableView->setSelectionMode(QAbstractItemView::ExtendedSelection);
|
||||
|
||||
if (!m_ismainres) {
|
||||
// don't set this shortcut when we are a child of main, would
|
||||
// be duplicate/ambiguous
|
||||
connect(new QShortcut(quitKeySeq, this), SIGNAL(activated()),
|
||||
m_rclmain, SLOT (fileExit()));
|
||||
// Don't set this shortcut when we are a child of main, would be duplicate/ambiguous
|
||||
connect(new QShortcut(quitKeySeq, this), SIGNAL(activated()), m_rclmain, SLOT (fileExit()));
|
||||
}
|
||||
|
||||
new QShortcut(closeKeySeq, this, SLOT (close()));
|
||||
connect(this, SIGNAL(previewRequested(Rcl::Doc)),
|
||||
m_rclmain, SLOT(startPreview(Rcl::Doc)));
|
||||
connect(this, SIGNAL(editRequested(Rcl::Doc)),
|
||||
m_rclmain, SLOT(startNativeViewer(Rcl::Doc)));
|
||||
connect(this, SIGNAL(docSaveToFileClicked(Rcl::Doc)),
|
||||
m_rclmain, SLOT(saveDocToFile(Rcl::Doc)));
|
||||
connect(this, SIGNAL(showSnippets(Rcl::Doc)),
|
||||
m_rclmain, SLOT(showSnippets(Rcl::Doc)));
|
||||
connect(this, SIGNAL(previewRequested(Rcl::Doc)), m_rclmain, SLOT(startPreview(Rcl::Doc)));
|
||||
connect(this, SIGNAL(editRequested(Rcl::Doc)), m_rclmain, SLOT(startNativeViewer(Rcl::Doc)));
|
||||
connect(this, SIGNAL(docSaveToFileClicked(Rcl::Doc)), m_rclmain, SLOT(saveDocToFile(Rcl::Doc)));
|
||||
connect(this, SIGNAL(showSnippets(Rcl::Doc)), m_rclmain, SLOT(showSnippets(Rcl::Doc)));
|
||||
}
|
||||
|
||||
void ResTable::toggleHeader()
|
||||
@ -911,39 +903,65 @@ void ResTable::onTableView_currentChanged(const QModelIndex& index)
|
||||
if (!m_model || !m_model->getDocSource())
|
||||
return;
|
||||
Rcl::Doc doc;
|
||||
if (m_model->getDocSource()->getDoc(index.row(), doc)) {
|
||||
m_detail->init();
|
||||
m_detaildocnum = index.row();
|
||||
m_detaildoc = doc;
|
||||
bool isShift = (QApplication::keyboardModifiers() & Qt::ShiftModifier);
|
||||
bool showtext{false};
|
||||
bool showmeta{false};
|
||||
if (m_rowchangefromkbd) {
|
||||
// Ctrl+... jump to row. Show text/meta as for simple click
|
||||
if (hasselection) {
|
||||
// When getting here from ctrl+... we get called twice, once with row 0
|
||||
// and no selection, once with the actual row and selection. Only
|
||||
// reset fromkbd and set showtext in the second case.
|
||||
m_rowchangefromkbd = false;
|
||||
showtext = prefs.resTableTextNoShift;
|
||||
}
|
||||
} else {
|
||||
// Mouse click. Show text or meta depending on shift key. Never show text when hovering
|
||||
// (no selection).
|
||||
showtext = hasselection && (isShift ^ prefs.resTableTextNoShift);
|
||||
}
|
||||
if (!showtext) {
|
||||
showmeta = hasselection || !prefs.resTableNoHoverMeta;
|
||||
}
|
||||
if (showtext && rcldb->getDocRawText(m_detaildoc)) {
|
||||
m_detail->setPlainText(u8s2qs(m_detaildoc.text));
|
||||
} else if (showmeta) {
|
||||
m_pager->displaySingleDoc(theconfig, m_detaildocnum, m_detaildoc, m_model->m_hdata);
|
||||
}
|
||||
emit(detailDocChanged(doc, m_model->getDocSource()));
|
||||
} else {
|
||||
if (!m_model->getDocSource()->getDoc(index.row(), doc)) {
|
||||
m_detaildocnum = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
m_detail->init();
|
||||
m_detaildocnum = index.row();
|
||||
m_detaildoc = doc;
|
||||
bool isShift = (QApplication::keyboardModifiers() & Qt::ShiftModifier);
|
||||
bool showcontent{false};
|
||||
bool showmeta{false};
|
||||
|
||||
if (m_rowchangefromkbd) {
|
||||
// Ctrl+... jump to row. Show text/meta as for simple click
|
||||
if (hasselection) {
|
||||
// When getting here from ctrl+... we get called twice, once with row 0
|
||||
// and no selection, once with the actual row and selection. Only
|
||||
// reset fromkbd and set showcontent in the second case.
|
||||
m_rowchangefromkbd = false;
|
||||
showcontent = prefs.resTableTextNoShift;
|
||||
}
|
||||
} else {
|
||||
// Mouse click. Show text or meta depending on shift key. Never show text when hovering
|
||||
// (no selection).
|
||||
showcontent = hasselection && (isShift ^ prefs.resTableTextNoShift);
|
||||
}
|
||||
if (!showcontent) {
|
||||
showmeta = hasselection || !prefs.resTableNoHoverMeta;
|
||||
}
|
||||
|
||||
bool displaydone{false};
|
||||
|
||||
if (showcontent) {
|
||||
// If it's an image, and simply stored in a file, display it. We don't go to the trouble of
|
||||
// extracting an embedded image here.
|
||||
if (mimeIsImage(m_detaildoc.mimetype) && m_detaildoc.ipath.empty()) {
|
||||
auto image = QImage(fileurltolocalpath(m_detaildoc.url).c_str());
|
||||
if (!image.isNull()) {
|
||||
m_detail->setPlainText("");
|
||||
auto w = m_detail->width();
|
||||
auto h = m_detail->height();
|
||||
if (image.width() > w || image.height() > h) {
|
||||
image = image.scaled(w, h, Qt::KeepAspectRatio);
|
||||
}
|
||||
m_detail->document()->addResource(QTextDocument::ImageResource,QUrl("image"),image);
|
||||
m_detail->textCursor().insertImage("image");
|
||||
displaydone = true;
|
||||
}
|
||||
}
|
||||
if (!displaydone && rcldb->getDocRawText(m_detaildoc)) {
|
||||
m_detail->setPlainText(u8s2qs(m_detaildoc.text));
|
||||
displaydone = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!displaydone && showmeta) {
|
||||
m_pager->displaySingleDoc(theconfig, m_detaildocnum, m_detaildoc, m_model->m_hdata);
|
||||
}
|
||||
emit(detailDocChanged(doc, m_model->getDocSource()));
|
||||
}
|
||||
|
||||
void ResTable::on_tableView_entered(const QModelIndex& index)
|
||||
@ -1163,8 +1181,7 @@ void ResTable::onDoubleClick(const QModelIndex& index)
|
||||
|
||||
void ResTable::createPopupMenu(const QPoint& pos)
|
||||
{
|
||||
LOGDEB("ResTable::createPopupMenu: m_detaildocnum " << m_detaildocnum <<
|
||||
"\n");
|
||||
LOGDEB("ResTable::createPopupMenu: m_detaildocnum " << m_detaildocnum << "\n");
|
||||
if (m_detaildocnum >= 0 && m_model) {
|
||||
int opts = m_ismainres? ResultPopup::isMain : 0;
|
||||
|
||||
@ -1177,8 +1194,7 @@ void ResTable::createPopupMenu(const QPoint& pos)
|
||||
// docs are necessary subdocs and multisave only works with those.
|
||||
opts |= ResultPopup::showSaveSel;
|
||||
}
|
||||
QMenu *popup = ResultPopup::create(this, opts, m_model->getDocSource(),
|
||||
m_detaildoc);
|
||||
QMenu *popup = ResultPopup::create(this, opts, m_model->getDocSource(), m_detaildoc);
|
||||
popup->popup(mapToGlobal(pos));
|
||||
}
|
||||
}
|
||||
@ -1343,8 +1359,7 @@ void ResTable::menuShowSubDocs()
|
||||
|
||||
void ResTable::createHeaderPopupMenu(const QPoint& pos)
|
||||
{
|
||||
LOGDEB("ResTable::createHeaderPopupMenu(" << pos.x() << ", " <<
|
||||
pos.y() << ")\n");
|
||||
LOGDEB("ResTable::createHeaderPopupMenu(" << pos.x() << ", " << pos.y() << ")\n");
|
||||
QHeaderView *header = tableView->horizontalHeader();
|
||||
if (!header || !m_model)
|
||||
return;
|
||||
@ -1386,10 +1401,10 @@ void ResTable::deleteColumn()
|
||||
|
||||
void ResTable::addColumn()
|
||||
{
|
||||
if (!m_model)
|
||||
return;
|
||||
QAction *action = (QAction *)sender();
|
||||
LOGDEB("addColumn: text " << qs2utf8s(action->text()) << ", data " <<
|
||||
qs2utf8s(action->data().toString()) << "\n");
|
||||
m_model->addColumn(m_popcolumn, qs2utf8s(action->data().toString()));
|
||||
if (nullptr == action || nullptr == m_model)
|
||||
return;
|
||||
std::string field = qs2utf8s(action->data().toString());
|
||||
LOGDEB("addColumn: text " << qs2utf8s(action->text()) << ", field " << field << "\n");
|
||||
m_model->addColumn(m_popcolumn, field);
|
||||
}
|
||||
|
||||
59
src/testmains/trappformime.cpp
Normal file
59
src/testmains/trappformime.cpp
Normal file
@ -0,0 +1,59 @@
|
||||
#else // TEST_APPFORMIME
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
using namespace std;
|
||||
|
||||
#include "appformime.h"
|
||||
|
||||
static char *thisprog;
|
||||
|
||||
static char usage [] =
|
||||
" appformime <mime type>\n\n"
|
||||
;
|
||||
static void
|
||||
Usage(void)
|
||||
{
|
||||
fprintf(stderr, "%s: usage:\n%s", thisprog, usage);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
thisprog = argv[0];
|
||||
argc--; argv++;
|
||||
|
||||
if (argc != 1)
|
||||
Usage();
|
||||
string mime = *argv++;argc--;
|
||||
|
||||
string reason;
|
||||
vector<DesktopDb::AppDef> appdefs;
|
||||
DesktopDb *ddb = DesktopDb::getDb();
|
||||
if (ddb == 0) {
|
||||
cerr << "Could not create desktop db\n";
|
||||
exit(1);
|
||||
}
|
||||
if (!ddb->appForMime(mime, &appdefs, &reason)) {
|
||||
cerr << "appForMime failed: " << reason << endl;
|
||||
exit(1);
|
||||
}
|
||||
if (appdefs.empty()) {
|
||||
cerr << "No application found for [" << mime << "]" << endl;
|
||||
exit(1);
|
||||
}
|
||||
cout << mime << " -> ";
|
||||
for (vector<DesktopDb::AppDef>::const_iterator it = appdefs.begin();
|
||||
it != appdefs.end(); it++) {
|
||||
cout << "[" << it->name << ", " << it->command << "], ";
|
||||
}
|
||||
cout << endl;
|
||||
|
||||
exit(0);
|
||||
}
|
||||
@ -14,7 +14,7 @@
|
||||
* Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
#ifndef TEST_APPFORMIME
|
||||
|
||||
#include <conftree.h>
|
||||
#include <fstreewalk.h>
|
||||
|
||||
@ -33,9 +33,7 @@ static DesktopDb *theDb;
|
||||
class FstCb : public FsTreeWalkerCB {
|
||||
public:
|
||||
FstCb(DesktopDb::AppMap *appdefs)
|
||||
: m_appdefs(appdefs)
|
||||
{
|
||||
}
|
||||
: m_appdefs(appdefs) {}
|
||||
virtual FsTreeWalker::Status
|
||||
processone(const string &, const struct PathStat *, FsTreeWalker::CbFlag);
|
||||
DesktopDb::AppMap *m_appdefs;
|
||||
@ -173,64 +171,8 @@ const string& DesktopDb::getReason()
|
||||
return m_reason;
|
||||
}
|
||||
|
||||
#else // TEST_APPFORMIME
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
using namespace std;
|
||||
|
||||
#include "appformime.h"
|
||||
|
||||
static char *thisprog;
|
||||
|
||||
static char usage [] =
|
||||
" appformime <mime type>\n\n"
|
||||
;
|
||||
static void
|
||||
Usage(void)
|
||||
bool mimeIsImage(const std::string& tp)
|
||||
{
|
||||
fprintf(stderr, "%s: usage:\n%s", thisprog, usage);
|
||||
exit(1);
|
||||
return !tp.compare(0, 6, "image/") &&
|
||||
tp.compare("image/vnd.djvu") && tp.compare("image/svg+xml");
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
thisprog = argv[0];
|
||||
argc--; argv++;
|
||||
|
||||
if (argc != 1)
|
||||
Usage();
|
||||
string mime = *argv++;argc--;
|
||||
|
||||
string reason;
|
||||
vector<DesktopDb::AppDef> appdefs;
|
||||
DesktopDb *ddb = DesktopDb::getDb();
|
||||
if (ddb == 0) {
|
||||
cerr << "Could not create desktop db\n";
|
||||
exit(1);
|
||||
}
|
||||
if (!ddb->appForMime(mime, &appdefs, &reason)) {
|
||||
cerr << "appForMime failed: " << reason << endl;
|
||||
exit(1);
|
||||
}
|
||||
if (appdefs.empty()) {
|
||||
cerr << "No application found for [" << mime << "]" << endl;
|
||||
exit(1);
|
||||
}
|
||||
cout << mime << " -> ";
|
||||
for (vector<DesktopDb::AppDef>::const_iterator it = appdefs.begin();
|
||||
it != appdefs.end(); it++) {
|
||||
cout << "[" << it->name << ", " << it->command << "], ";
|
||||
}
|
||||
cout << endl;
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
#endif //TEST_APPFORMIME
|
||||
|
||||
@ -88,4 +88,7 @@ private:
|
||||
};
|
||||
|
||||
|
||||
/** Helper function: is MIME type a simple image ? */
|
||||
bool mimeIsImage(const std::string& tp);
|
||||
|
||||
#endif /* _APPFORMIME_H_INCLUDED_ */
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user