Source file: src/headers_view.cpp
/* Copyright (C) 2004-2008 Daniel Vérité
This file is part of Manitou-Mail (see http://www.manitou-mail.org)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2 as
published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
*/
/* headers_view is a rich-text viewer for mail headers, with some additional features:
- xface and face rendering
- html links to trigger some actions
- filter logs display
*/
#include "headers_view.h"
#include <QTextEdit>
#include <QTextCursor>
#include <QUrl>
headers_view::headers_view(QWidget* parent) : QTextBrowser(parent)
{
setFrameStyle(QFrame::NoFrame);
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
// We track resizings of the header contents to adjust the height of
// m_headersv so that all headers stay visible.
connect((const QObject*)document()->documentLayout(),
SIGNAL(documentSizeChanged(const QSizeF&)),
this,
SLOT(size_headers_changed(const QSizeF&)));
setFocusPolicy(Qt::NoFocus); // no keyboard events?
// document()->setDefaultStyleSheet("body { background: ivory; }");
connect(this, SIGNAL(anchorClicked(const QUrl&)), this, SLOT(link_clicked(const QUrl&)));
}
headers_view::~headers_view()
{
}
void
headers_view::set_contents(const QString& html_text)
{
m_base_text = html_text;
setHtml(QString("<html><body>")+html_text+"</body></html>");
}
void
headers_view::size_headers_changed(const QSizeF& newsize)
{
setFixedHeight(newsize.height());
/* calling update() on the layout appears unnecessary at the moment
but it was before (for an unknown reason), so keep the code to be
uncommented later if required (m_layout relates to the parent widget) */
#if 0
m_layout->update();
#endif
}
bool
headers_view::set_xface(QString& xface)
{
return m_xface_pixmap.loadFromData((const uchar*)xface.toLatin1().constData(), xface.length());
}
bool
headers_view::set_face(const QByteArray& png)
{
return m_xface_pixmap.loadFromData(png, "PNG");
}
void
headers_view::clear_selection()
{
QTextCursor cursor = this->textCursor();
cursor.clearSelection();
setTextCursor(cursor);
}
void
headers_view::set_show_on_demand(bool b)
{
if (b) {
setHtml("<h2><a href=\"#show\">" + tr("Fetch on demand mode: click this link to display the message") + "</a></h2>");
}
else {
redisplay();
}
}
QVariant
headers_view::loadResource(int type, const QUrl& name)
{
Q_UNUSED(type);
if (name.toString()=="/xface.xpm") {
QVariant v(m_xface_pixmap);
return v;
}
return QVariant();
}
void
headers_view::clear()
{
setHtml("<html><body></body></html>");
m_base_text.truncate(0);
QList<QTextEdit::ExtraSelection> qlist;
// remove any selection
setExtraSelections(QList<QTextEdit::ExtraSelection>());
}
QString
headers_view::command_links()
{
static const char* commands[] = {
"fetch", QT_TR_NOOP("Fetch external contents"),
"to_text", QT_TR_NOOP("Show text part"),
"to_html", QT_TR_NOOP("Show HTML part"),
"complete_load", QT_TR_NOOP("Complete load")
};
QString line;
for (uint i=0; i<sizeof(commands)/sizeof(commands[0]); i+=2) {
if (m_enabled_commands.contains(commands[i])) {
const QString cmd=commands[i];
bool b=m_enabled_commands.value(cmd);
if (b==true) {
line.append(QString(" <a href=\"#%1\">%2</a>").arg(commands[i]).arg(tr(commands[i+1])));
}
}
}
return line;
}
void
headers_view::redisplay()
{
QString links = command_links();
if (!links.isEmpty())
links.prepend("<br>");
setHtml(QString("<html><body>")+m_base_text+links+"</body></html>");
}
void
headers_view::reset_commands()
{
m_enabled_commands.clear();
}
void
headers_view::enable_command(const QString command, bool enable)
{
m_enabled_commands.insert(command, enable);
redisplay();
}
void
headers_view::link_clicked(const QUrl& url)
{
const QString cmd=url.toString();
if (cmd=="#fetch") {
emit fetch_ext_contents();
}
else if (cmd=="#to_text") {
emit to_text();
}
else if (cmd=="#to_html") {
emit to_html();
}
else if (cmd=="#show") {
emit msg_display_request();
}
else if (cmd=="#complete_load") {
emit complete_load_request();
}
}
void
headers_view::highlight_terms(const std::list<searched_text>& lst)
{
QList<QTextEdit::ExtraSelection> qlist;
if (lst.empty()) {
setExtraSelections(qlist);
return;
}
std::list<searched_text>::const_iterator it = lst.begin();
QTextEdit::ExtraSelection qsel;
QTextCharFormat qfmt;
qfmt.setBackground(QBrush(QColor("yellow")));
qsel.format = qfmt;
QTextCursor tcursor;
QTextDocument::FindFlags flags=0;
if (it->m_is_cs)
flags |= QTextDocument::FindCaseSensitively;
if (it->m_is_word) {
flags |= QTextDocument::FindWholeWords;
}
for ( ; it!=lst.end(); ++it) {
int index=0;
do {
tcursor = document()->find(it->m_text, index, flags);
if (!tcursor.isNull()) {
qsel.cursor=tcursor;
qlist.append(qsel);
index = tcursor.position()+1;
}
} while (!tcursor.isNull());
}
setExtraSelections(qlist); // even if qlist is empty (otherwise we get a blank rectangle colored as the selection)
}
HTML source code generated by GNU Source-Highlight plus some custom post-processing
List of all available source files