diff --git a/src/qtgui/preview_w.cpp b/src/qtgui/preview_w.cpp index d095ba51..bb879d2a 100644 --- a/src/qtgui/preview_w.cpp +++ b/src/qtgui/preview_w.cpp @@ -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; } diff --git a/src/qtgui/restable.cpp b/src/qtgui/restable.cpp index f6fd0d24..051984b4 100644 --- a/src/qtgui/restable.cpp +++ b/src/qtgui/restable.cpp @@ -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); } diff --git a/src/testmains/trappformime.cpp b/src/testmains/trappformime.cpp new file mode 100644 index 00000000..a6ecafbe --- /dev/null +++ b/src/testmains/trappformime.cpp @@ -0,0 +1,59 @@ +#else // TEST_APPFORMIME + +#include +#include +#include +#include + +#include +#include +#include +using namespace std; + +#include "appformime.h" + +static char *thisprog; + +static char usage [] = +" appformime \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 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::const_iterator it = appdefs.begin(); + it != appdefs.end(); it++) { + cout << "[" << it->name << ", " << it->command << "], "; + } + cout << endl; + + exit(0); +} diff --git a/src/utils/appformime.cpp b/src/utils/appformime.cpp index 14747371..6aa6f5ff 100644 --- a/src/utils/appformime.cpp +++ b/src/utils/appformime.cpp @@ -14,7 +14,7 @@ * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef TEST_APPFORMIME + #include #include @@ -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 -#include -#include -#include - -#include -#include -#include -using namespace std; - -#include "appformime.h" - -static char *thisprog; - -static char usage [] = -" appformime \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 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::const_iterator it = appdefs.begin(); - it != appdefs.end(); it++) { - cout << "[" << it->name << ", " << it->command << "], "; - } - cout << endl; - - exit(0); -} - -#endif //TEST_APPFORMIME diff --git a/src/utils/appformime.h b/src/utils/appformime.h index 45ca018d..4c19cc48 100644 --- a/src/utils/appformime.h +++ b/src/utils/appformime.h @@ -88,4 +88,7 @@ private: }; +/** Helper function: is MIME type a simple image ? */ +bool mimeIsImage(const std::string& tp); + #endif /* _APPFORMIME_H_INCLUDED_ */