• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdepim API Reference
  • KDE Home
  • Contact Us
 

messageviewer

  • sources
  • kde-4.14
  • kdepim
  • messageviewer
  • viewer
mailsourceviewer.cpp
Go to the documentation of this file.
1 /* -*- mode: C++; c-file-style: "gnu" -*-
2  *
3  * This file is part of KMail, the KDE mail client.
4  *
5  * Copyright (c) 2002-2003 Carsten Pfeiffer <pfeiffer@kde.org>
6  * Copyright (c) 2003 Zack Rusin <zack@kde.org>
7  *
8  * KMail is free software; you can redistribute it and/or modify it
9  * under the terms of the GNU General Public License, version 2, as
10  * published by the Free Software Foundation.
11  *
12  * KMail is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  *
21  * In addition, as a special exception, the copyright holders give
22  * permission to link the code of this program with any edition of
23  * the Qt library by Trolltech AS, Norway (or with modified versions
24  * of Qt that use the same license as Qt), and distribute linked
25  * combinations including the two. You must obey the GNU General
26  * Public License in all respects for all of the code used other than
27  * Qt. If you modify this file, you may extend this exception to
28  * your version of the file, but you are not obligated to do so. If
29  * you do not wish to do so, delete this exception statement from
30  * your version.
31  */
32 
33 
34 #include "mailsourceviewer.h"
35 #include "utils/util.h"
36 #include "findbar/findbarsourceview.h"
37 #include "kpimtextedit/htmlhighlighter.h"
38 #include "pimcommon/widgets/slidecontainer.h"
39 #include "pimcommon/util/pimutil.h"
40 #include <kiconloader.h>
41 #include <KLocalizedString>
42 #include <KStandardAction>
43 #include <kwindowsystem.h>
44 #include <kglobalsettings.h>
45 #include <KTabWidget>
46 #include <KFileDialog>
47 #include <KMessageBox>
48 #include <KAction>
49 
50 #include <QtCore/QRegExp>
51 #include <QApplication>
52 #include <QIcon>
53 #include <QShortcut>
54 #include <QVBoxLayout>
55 #include <QContextMenuEvent>
56 #include <QDebug>
57 #include <QMenu>
58 
59 namespace MessageViewer {
60 
61 
62 MailSourceViewTextBrowserWidget::MailSourceViewTextBrowserWidget( QWidget *parent )
63  :QWidget( parent )
64 {
65  QVBoxLayout *lay = new QVBoxLayout;
66  setLayout( lay );
67  lay->setMargin( 0 );
68  mTextBrowser = new MailSourceViewTextBrowser();
69  mTextBrowser->setLineWrapMode( QPlainTextEdit::NoWrap );
70  mTextBrowser->setTextInteractionFlags( Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard );
71  connect( mTextBrowser, SIGNAL(findText()), SLOT(slotFind()) );
72  lay->addWidget( mTextBrowser );
73  mSliderContainer = new PimCommon::SlideContainer(this);
74 
75  mFindBar = new FindBarSourceView( mTextBrowser, this );
76  connect(mFindBar, SIGNAL(hideFindBar()), mSliderContainer, SLOT(slideOut()));
77  mSliderContainer->setContent(mFindBar);
78 
79  lay->addWidget( mSliderContainer );
80  QShortcut *shortcut = new QShortcut( this );
81  shortcut->setKey( Qt::Key_F+Qt::CTRL );
82  connect( shortcut, SIGNAL(activated()), SLOT(slotFind()) );
83 }
84 
85 void MailSourceViewTextBrowserWidget::slotFind()
86 {
87  if ( mTextBrowser->textCursor().hasSelection() )
88  mFindBar->setText( mTextBrowser->textCursor().selectedText() );
89  mSliderContainer->slideIn();
90  mFindBar->focusAndSetCursor();
91 }
92 
93 void MailSourceViewTextBrowserWidget::setText( const QString& text )
94 {
95  mTextBrowser->setPlainText( text );
96 }
97 
98 void MailSourceViewTextBrowserWidget::setPlainText( const QString& text )
99 {
100  mTextBrowser->setPlainText( text );
101 }
102 
103 void MailSourceViewTextBrowserWidget::setFixedFont()
104 {
105  mTextBrowser->setFont( KGlobalSettings::fixedFont() );
106 }
107 
108 MessageViewer::MailSourceViewTextBrowser *MailSourceViewTextBrowserWidget::textBrowser() const
109 {
110  return mTextBrowser;
111 }
112 
113 MailSourceViewTextBrowser::MailSourceViewTextBrowser( QWidget *parent )
114  :QPlainTextEdit( parent )
115 {
116 }
117 
118 void MailSourceViewTextBrowser::contextMenuEvent( QContextMenuEvent *event )
119 {
120  QMenu *popup = createStandardContextMenu();
121  if (popup) {
122  popup->addSeparator();
123  popup->addAction(KStandardAction::find(this, SIGNAL(findText()), this));
124  //Code from KTextBrowser
125  KIconTheme::assignIconsToContextMenu( isReadOnly() ? KIconTheme::ReadOnlyText
126  : KIconTheme::TextEditor,
127  popup->actions() );
128  popup->addSeparator();
129  popup->addAction( KIcon(QLatin1String("preferences-desktop-text-to-speech")),i18n("Speak Text"),this,SLOT(slotSpeakText()));
130 
131  popup->addSeparator();
132  popup->addAction(KStandardAction::saveAs(this, SLOT(slotSaveAs()), this));
133 
134  popup->exec( event->globalPos() );
135  delete popup;
136  }
137 }
138 
139 void MailSourceViewTextBrowser::slotSaveAs()
140 {
141  PimCommon::Util::saveTextAs( toPlainText(), QString(), this );
142 }
143 
144 void MailSourceViewTextBrowser::slotSpeakText()
145 {
146  QString text;
147  if ( textCursor().hasSelection() ) {
148  text = textCursor().selectedText();
149  } else {
150  text = toPlainText();
151  }
152  MessageViewer::Util::speakSelectedText( text, this);
153 }
154 
155 void MailSourceHighlighter::highlightBlock ( const QString & text ) {
156  // all visible ascii except space and :
157  const QRegExp regexp( QLatin1String("^([\\x21-9;-\\x7E]+:\\s)") );
158 
159  // keep the previous state
160  setCurrentBlockState( previousBlockState() );
161  // If a header is found
162  if( regexp.indexIn( text ) != -1 )
163  {
164  const int headersState = -1; // Also the initial State
165  // Content- header starts a new mime part, and therefore new headers
166  // If a Content-* header is found, change State to headers until a blank line is found.
167  if ( text.startsWith( QLatin1String( "Content-" ) ) )
168  {
169  setCurrentBlockState( headersState );
170  }
171  // highligth it if in headers state
172  if( ( currentBlockState() == headersState ) )
173  {
174  QFont font = document()->defaultFont ();
175  font.setBold( true );
176  setFormat( 0, regexp.matchedLength(), font );
177  }
178  }
179  // Change to body state
180  else if ( text.isEmpty() )
181  {
182  const int bodyState = 0;
183  setCurrentBlockState( bodyState );
184  }
185 }
186 
187 MailSourceViewer::MailSourceViewer( QWidget *parent )
188  : KDialog( parent )
189 {
190  setAttribute( Qt::WA_DeleteOnClose );
191  setButtons( Close );
192 
193  QVBoxLayout *layout = new QVBoxLayout( mainWidget() );
194  layout->setMargin( 0 );
195  connect( this, SIGNAL(closeClicked()), SLOT(close()) );
196 
197  mRawBrowser = new MailSourceViewTextBrowserWidget();
198 
199 #ifndef NDEBUG
200  mTabWidget = new KTabWidget;
201  layout->addWidget( mTabWidget );
202 
203  mTabWidget->addTab( mRawBrowser, i18nc( "Unchanged mail message", "Raw Source" ) );
204  mTabWidget->setTabToolTip( 0, i18n( "Raw, unmodified mail as it is stored on the filesystem or on the server" ) );
205 
206  mHtmlBrowser = new MailSourceViewTextBrowserWidget();
207  mTabWidget->addTab( mHtmlBrowser, i18nc( "Mail message as shown, in HTML format", "HTML Source" ) );
208  mTabWidget->setTabToolTip( 1, i18n( "HTML code for displaying the message to the user" ) );
209  new KPIMTextEdit::HtmlHighlighter( mHtmlBrowser->textBrowser()->document() );
210 
211  mTabWidget->setCurrentIndex( 0 );
212 #else
213  layout->addWidget( mRawBrowser );
214 #endif
215 
216  // combining the shortcuts in one qkeysequence() did not work...
217  QShortcut* shortcut = new QShortcut( this );
218  shortcut->setKey( Qt::Key_Escape );
219  connect( shortcut, SIGNAL(activated()), SLOT(close()) );
220  shortcut = new QShortcut( this );
221  shortcut->setKey( Qt::Key_W+Qt::CTRL );
222  connect( shortcut, SIGNAL(activated()), SLOT(close()) );
223 
224  KWindowSystem::setIcons( winId(),
225  qApp->windowIcon().pixmap( IconSize( KIconLoader::Desktop ),
226  IconSize( KIconLoader::Desktop ) ),
227  qApp->windowIcon().pixmap( IconSize( KIconLoader::Small ),
228  IconSize( KIconLoader::Small ) ) );
229  new MailSourceHighlighter( mRawBrowser->textBrowser()->document() );
230  mRawBrowser->textBrowser()->setFocus();
231 }
232 
233 MailSourceViewer::~MailSourceViewer()
234 {
235 }
236 
237 void MailSourceViewer::setRawSource( const QString &source )
238 {
239  mRawBrowser->setText( source );
240 }
241 
242 void MailSourceViewer::setDisplayedSource( const QString &source )
243 {
244 #ifndef NDEBUG
245  mHtmlBrowser->setPlainText( reformat( source ) );
246 #else
247  Q_UNUSED( source );
248 #endif
249 }
250 
251 void MailSourceViewer::setFixedFont()
252 {
253  mRawBrowser->setFixedFont();
254 #ifndef NDEBUG
255  mHtmlBrowser->setFixedFont();
256 #endif
257 }
258 
259 QString MailSourceViewer::reformat(const QString &src)
260 {
261  const QRegExp cleanLeadingWhitespace( QLatin1String("(?:\\n)+\\w*") );
262  QStringList tmpSource;
263  QString source( src );
264  int pos = 0;
265  QString indent;
266  // Best to be really verbose about this one...
267  const static QRegExp htmlTagRegExp( QLatin1String("<"
268  "(/)?" //Captures the / if this is an end tag.
269  "(\\w+)" //Captures TagName
270  "(?:" //Groups tag contents
271  "(?:\\s+" //Groups attributes
272  "(?:\\w+)" //Attribute name
273  "(?:" //groups =value portion.
274  "\\s*=\\s*" // =
275  "(?:" //Groups attribute "value" portion.
276  "\\\"(?:[^\\\"]*)\\\"" // attVal='double quoted'
277  "|'(?:[^']*)'" // attVal='single quoted'
278  "|(?:[^'"">\\s]+)" // attVal=urlnospaces
279  ")"
280  ")?" //end optional att value portion.
281  ")+\\s*" //One or more attribute pairs
282  "|\\s*" //Some white space.
283  ")"
284  "(/)?>" //Captures the "/" if this is a complete tag.
285  ));
286 
287  //First make sure that each tag is surrounded by newlines
288  while( (pos = htmlTagRegExp.indexIn( source, pos ) ) != -1 )
289  {
290  source.insert(pos, QLatin1Char('\n'));
291  pos += htmlTagRegExp.matchedLength() + 1;
292  source.insert(pos, QLatin1Char('\n'));
293  ++pos;
294  }
295 
296  // Then split the source on newlines skiping empty parts.
297  // Now a line is either a tag or pure data.
298  tmpSource = source.split(QLatin1Char('\n'), QString::SkipEmptyParts );
299 
300  // Then clean any leading whitespace
301  for( int i = 0; i != tmpSource.length(); ++i )
302  {
303  tmpSource[i] = tmpSource[i].remove( cleanLeadingWhitespace );
304  }
305 
306  // Then indent as appropriate
307  for( int i = 0; i != tmpSource.length(); ++i ) {
308  if( htmlTagRegExp.indexIn( tmpSource.at(i) ) != -1 ) // A tag
309  {
310  if( htmlTagRegExp.cap( 3 ) == QLatin1String( "/" ) ||
311  htmlTagRegExp.cap( 2 ) == QLatin1String( "img" ) ||
312  htmlTagRegExp.cap( 2 ) == QLatin1String( "br" ) ) {
313  //Self closing tag or no closure needed
314  continue;
315  }
316  if( htmlTagRegExp.cap( 1 ) == QLatin1String( "/" ) ) {
317  // End tag
318  indent.chop( 2 );
319  tmpSource[i].prepend( indent );
320  continue;
321  }
322  // start tag
323  tmpSource[i].prepend( indent );
324  indent.append( QLatin1String(" ") );
325  continue;
326  }
327  // Data
328  tmpSource[i].prepend( indent );
329  }
330 
331  // Finally reassemble and return :)
332  return tmpSource.join( QLatin1String("\n") );
333 }
334 
335 }
QSyntaxHighlighter::previousBlockState
int previousBlockState() const
QWidget
QShortcut::setKey
void setKey(const QKeySequence &key)
QString::append
QString & append(QChar ch)
QList::remove
iterator remove(iterator pos)
MessageViewer::MailSourceViewTextBrowser::MailSourceViewTextBrowser
MailSourceViewTextBrowser(QWidget *parent=0)
Definition: mailsourceviewer.cpp:113
QList::length
int length() const
MessageViewer::MailSourceViewTextBrowser
Definition: mailsourceviewer.h:83
MessageViewer::Util::speakSelectedText
bool MESSAGEVIEWER_EXPORT speakSelectedText(const QString &text, QWidget *parent)
Definition: util.cpp:531
QSyntaxHighlighter::setCurrentBlockState
void setCurrentBlockState(int newState)
QFont
QList::at
const T & at(int i) const
QMenu::addAction
void addAction(QAction *action)
QTextCursor::selectedText
QString selectedText() const
QPlainTextEdit::setTextInteractionFlags
void setTextInteractionFlags(QFlags< Qt::TextInteractionFlag > flags)
MessageViewer::MailSourceViewer::MailSourceViewer
MailSourceViewer(QWidget *parent=0)
Definition: mailsourceviewer.cpp:187
QPlainTextEdit
KDialog
QSyntaxHighlighter::setFormat
void setFormat(int start, int count, const QTextCharFormat &format)
QStringList::join
QString join(const QString &separator) const
QString::chop
void chop(int n)
QContextMenuEvent::globalPos
const QPoint & globalPos() const
MessageViewer::FindBarSourceView
Definition: findbarsourceview.h:29
MessageViewer::MailSourceViewTextBrowser::findText
void findText()
QPlainTextEdit::textCursor
QTextCursor textCursor() const
MessageViewer::MailSourceViewTextBrowserWidget::setFixedFont
void setFixedFont()
Definition: mailsourceviewer.cpp:103
MessageViewer::MailSourceViewTextBrowserWidget::setPlainText
void setPlainText(const QString &text)
Definition: mailsourceviewer.cpp:98
QFont::setBold
void setBold(bool enable)
findbarsourceview.h
QRegExp::matchedLength
int matchedLength() const
mailsourceviewer.h
QRegExp::indexIn
int indexIn(const QString &str, int offset, CaretMode caretMode) const
QRegExp
QTextCursor::hasSelection
bool hasSelection() const
QBoxLayout::addWidget
void addWidget(QWidget *widget, int stretch, QFlags< Qt::AlignmentFlag > alignment)
MessageViewer::MailSourceHighlighter::highlightBlock
void highlightBlock(const QString &text)
Definition: mailsourceviewer.cpp:155
QWidget::setLayout
void setLayout(QLayout *layout)
MessageViewer::MailSourceViewTextBrowserWidget::textBrowser
MessageViewer::MailSourceViewTextBrowser * textBrowser() const
Definition: mailsourceviewer.cpp:108
QPlainTextEdit::document
QTextDocument * document() const
QContextMenuEvent
MessageViewer::MailSourceViewTextBrowserWidget::setText
void setText(const QString &text)
Definition: mailsourceviewer.cpp:93
QWidget::setFocus
void setFocus()
MessageViewer::MailSourceHighlighter
Definition: mailsourceviewer.h:55
QString::isEmpty
bool isEmpty() const
MessageViewer::MailSourceViewTextBrowserWidget
Definition: mailsourceviewer.h:65
QString::startsWith
bool startsWith(const QString &s, Qt::CaseSensitivity cs) const
QVBoxLayout
QShortcut
QMenu::addSeparator
QAction * addSeparator()
QString
MessageViewer::MailSourceViewer::setRawSource
void setRawSource(const QString &source)
Definition: mailsourceviewer.cpp:237
util.h
QLayout::setMargin
void setMargin(int margin)
QMenu::exec
QAction * exec()
QStringList
QTextDocument::defaultFont
defaultFont
QMenu
QSyntaxHighlighter::document
QTextDocument * document() const
QLatin1Char
QWidget::setFont
void setFont(const QFont &)
QPlainTextEdit::isReadOnly
bool isReadOnly() const
MessageViewer::FindBarBase::setText
void setText(const QString &text)
Definition: findbarbase.cpp:122
QLatin1String
MessageViewer::MailSourceViewer::~MailSourceViewer
~MailSourceViewer()
Definition: mailsourceviewer.cpp:233
QStringList::split
QStringList split(const QString &sep, const QString &str, bool allowEmptyEntries)
QSyntaxHighlighter::currentBlockState
int currentBlockState() const
MessageViewer::MailSourceViewTextBrowserWidget::MailSourceViewTextBrowserWidget
MailSourceViewTextBrowserWidget(QWidget *parent=0)
Definition: mailsourceviewer.cpp:62
QList::prepend
void prepend(const T &value)
MessageViewer::MailSourceViewTextBrowser::contextMenuEvent
void contextMenuEvent(QContextMenuEvent *event)
Definition: mailsourceviewer.cpp:118
QPlainTextEdit::setLineWrapMode
void setLineWrapMode(LineWrapMode mode)
QObject::connect
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QWidget::actions
QList< QAction * > actions() const
QPlainTextEdit::setPlainText
void setPlainText(const QString &text)
MessageViewer::MailSourceViewer::setDisplayedSource
void setDisplayedSource(const QString &source)
Definition: mailsourceviewer.cpp:242
QPlainTextEdit::createStandardContextMenu
QMenu * createStandardContextMenu()
MessageViewer::FindBarBase::focusAndSetCursor
void focusAndSetCursor()
Definition: findbarbase.cpp:127
MessageViewer::MailSourceViewer::setFixedFont
void setFixedFont()
Definition: mailsourceviewer.cpp:251
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:32:45 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

messageviewer

Skip menu "messageviewer"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdepim API Reference

Skip menu "kdepim API Reference"
  • akonadi_next
  • akregator
  • blogilo
  • calendarsupport
  • console
  •   kabcclient
  •   konsolekalendar
  • kaddressbook
  • kalarm
  •   lib
  • kdgantt2
  • kjots
  • kleopatra
  • kmail
  • knode
  • knotes
  • kontact
  • korgac
  • korganizer
  • ktimetracker
  • libkdepim
  • libkleo
  • libkpgp
  • mailcommon
  • messagelist
  • messageviewer
  • pimprint

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal