Scale identity combobox and send/cancel buttons according to screen DPI.
[kdepim.git] / messageviewer / mailsourceviewer.cpp
blob97c6da66d88d8fe034f954777b37b4a5a1295c3f
1 /* -*- mode: C++; c-file-style: "gnu" -*-
3 * This file is part of KMail, the KDE mail client.
5 * Copyright (c) 2002-2003 Carsten Pfeiffer <pfeiffer@kde.org>
6 * Copyright (c) 2003 Zack Rusin <zack@kde.org>
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.
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.
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
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.
32 #include <config-messageviewer.h>
34 #include "mailsourceviewer.h"
35 #include "findbar/findbarsourceview.h"
36 #include <kiconloader.h>
37 #include <KLocalizedString>
38 #include <kstandardguiitem.h>
39 #include <kwindowsystem.h>
41 #include <QtCore/QRegExp>
42 #include <QtGui/QApplication>
43 #include <QtGui/QIcon>
44 #include <QtGui/QPushButton>
45 #include <QtGui/QShortcut>
46 #include <QtGui/QTabBar>
47 #include <QtGui/QVBoxLayout>
48 #include <QContextMenuEvent>
49 #include <QMenu>
51 namespace MessageViewer {
54 MailSourceViewTextBrowserWidget::MailSourceViewTextBrowserWidget( QWidget *parent )
55 :QWidget( parent )
57 QVBoxLayout *lay = new QVBoxLayout;
58 setLayout( lay );
59 mTextBrowser = new MailSourceViewTextBrowser();
60 mTextBrowser->setLineWrapMode( QTextEdit::NoWrap );
61 mTextBrowser->setTextInteractionFlags( Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard );
62 connect( mTextBrowser, SIGNAL( findText() ), SLOT( slotFind() ) );
63 lay->addWidget( mTextBrowser );
64 mFindBar = new FindBarSourceView( mTextBrowser, this );
65 lay->addWidget( mFindBar );
66 QShortcut *shortcut = new QShortcut( this );
67 shortcut->setKey( Qt::Key_F+Qt::CTRL );
68 connect( shortcut, SIGNAL(activated()), SLOT(slotFind()) );
71 void MailSourceViewTextBrowserWidget::slotFind()
73 mFindBar->show();
74 mFindBar->focusAndSetCursor();
77 void MailSourceViewTextBrowserWidget::setText( const QString& text )
79 mTextBrowser->setText( text );
82 void MailSourceViewTextBrowserWidget::setPlainText( const QString& text )
84 mTextBrowser->setPlainText( text );
87 MessageViewer::MailSourceViewTextBrowser *MailSourceViewTextBrowserWidget::textBrowser() const
89 return mTextBrowser;
92 MailSourceViewTextBrowser::MailSourceViewTextBrowser( QWidget *parent )
93 :KTextBrowser( parent )
97 void MailSourceViewTextBrowser::contextMenuEvent( QContextMenuEvent *event )
99 QMenu *popup = createStandardContextMenu(event->pos());
100 if (popup) {
101 popup->addSeparator();
102 popup->addAction( KStandardGuiItem::find().text(),this,SIGNAL( findText() ) , Qt::Key_F+Qt::CTRL);
103 //Code from KTextBrowser
104 KIconTheme::assignIconsToContextMenu( isReadOnly() ? KIconTheme::ReadOnlyText
105 : KIconTheme::TextEditor,
106 popup->actions() );
108 popup->exec( event->globalPos() );
109 delete popup;
114 void MailSourceHighlighter::highlightBlock ( const QString & text ) {
115 // all visible ascii except space and :
116 const QRegExp regexp( "^([\\x21-9;-\\x7E]+:\\s)" );
117 const int headersState = -1; // Also the initial State
118 const int bodyState = 0;
120 // keep the previous state
121 setCurrentBlockState( previousBlockState() );
122 // If a header is found
123 if( regexp.indexIn( text ) != -1 )
125 // Content- header starts a new mime part, and therefore new headers
126 // If a Content-* header is found, change State to headers until a blank line is found.
127 if ( text.startsWith( QLatin1String( "Content-" ) ) )
129 setCurrentBlockState( headersState );
131 // highligth it if in headers state
132 if( ( currentBlockState() == headersState ) )
134 QFont font = document()->defaultFont ();
135 font.setBold( true );
136 setFormat( 0, regexp.matchedLength(), font );
139 // Change to body state
140 else if ( text.isEmpty() )
142 setCurrentBlockState( bodyState );
146 void HTMLSourceHighlighter::highlightBlock ( const QString & text ) {
147 int pos = 0;
148 if( ( pos = HTMLPrettyFormatter::htmlTagRegExp.indexIn( text ) ) != -1 )
150 QFont font = document()->defaultFont();
151 font.setBold( true );
152 setFormat( pos, HTMLPrettyFormatter::htmlTagRegExp.matchedLength(), font );
156 const QString HTMLPrettyFormatter::reformat( const QString &src )
158 const QRegExp cleanLeadingWhitespace( "(?:\\n)+\\w*" );
159 QStringList tmpSource;
160 QString source( src );
161 int pos = 0;
162 QString indent = "";
164 //First make sure that each tag is surrounded by newlines
165 while( (pos = htmlTagRegExp.indexIn( source, pos ) ) != -1 )
167 source.insert(pos, '\n');
168 pos += htmlTagRegExp.matchedLength() + 1;
169 source.insert(pos, '\n');
170 pos++;
173 // Then split the source on newlines skiping empty parts.
174 // Now a line is either a tag or pure data.
175 tmpSource = source.split('\n', QString::SkipEmptyParts );
177 // Then clean any leading whitespace
178 for( int i = 0; i != tmpSource.length(); i++ )
180 tmpSource[i] = tmpSource[i].remove( cleanLeadingWhitespace );
183 // Then indent as appropriate
184 for( int i = 0; i != tmpSource.length(); i++ ) {
185 if( htmlTagRegExp.indexIn( tmpSource[i] ) != -1 ) // A tag
187 if( htmlTagRegExp.cap( 3 ) == "/" || htmlTagRegExp.cap( 2 ) == "img" || htmlTagRegExp.cap( 2 ) == "br" ) {
188 //Self closing tag or no closure needed
189 continue;
191 if( htmlTagRegExp.cap( 1 ) == "/" ) {
192 // End tag
193 indent.chop( 2 );
194 tmpSource[i].prepend( indent );
195 continue;
197 // start tag
198 tmpSource[i].prepend( indent );
199 indent.append( " " );
200 continue;
202 // Data
203 tmpSource[i].prepend( indent );
206 // Finally reassemble and return :)
207 return tmpSource.join( "\n" );
210 MailSourceViewer::MailSourceViewer( QWidget *parent )
211 : KDialog( parent ), mRawSourceHighLighter( 0 )
213 setAttribute( Qt::WA_DeleteOnClose );
214 setButtons( Close );
216 QVBoxLayout *layout = new QVBoxLayout( mainWidget() );
217 layout->setMargin( 0 );
218 mTabWidget = new KTabWidget;
219 layout->addWidget( mTabWidget );
221 connect( this, SIGNAL(closeClicked()), SLOT(close()) );
223 mRawBrowser = new MailSourceViewTextBrowserWidget();
224 mTabWidget->addTab( mRawBrowser, i18nc( "Unchanged mail message", "Raw Source" ) );
225 mTabWidget->setTabToolTip( 0, i18n( "Raw, unmodified mail as it is stored on the filesystem or on the server" ) );
227 #ifndef NDEBUG
228 mHtmlBrowser = new MailSourceViewTextBrowserWidget();
229 mTabWidget->addTab( mHtmlBrowser, i18nc( "Mail message as shown, in HTML format", "HTML Source" ) );
230 mTabWidget->setTabToolTip( 1, i18n( "HTML code for displaying the message to the user" ) );
231 mHtmlSourceHighLighter = new HTMLSourceHighlighter( mHtmlBrowser->textBrowser() );
232 #endif
234 mTabWidget->setCurrentIndex( 0 );
236 // combining the shortcuts in one qkeysequence() did not work...
237 QShortcut* shortcut = new QShortcut( this );
238 shortcut->setKey( Qt::Key_Escape );
239 connect( shortcut, SIGNAL(activated()), SLOT(close()) );
241 shortcut = new QShortcut( this );
242 shortcut->setKey( Qt::Key_W+Qt::CTRL );
243 connect( shortcut, SIGNAL(activated()), SLOT(close()) );
245 KWindowSystem::setIcons( winId(),
246 qApp->windowIcon().pixmap( IconSize( KIconLoader::Desktop ),
247 IconSize( KIconLoader::Desktop ) ),
248 qApp->windowIcon().pixmap( IconSize( KIconLoader::Small ),
249 IconSize( KIconLoader::Small ) ) );
250 mRawSourceHighLighter = new MailSourceHighlighter( mRawBrowser->textBrowser() );
253 MailSourceViewer::~MailSourceViewer()
257 void MailSourceViewer::setRawSource( const QString &source )
259 mRawBrowser->setText( source );
262 void MailSourceViewer::setDisplayedSource( const QString &source )
264 #ifndef NDEBUG
265 mHtmlBrowser->setPlainText( HTMLPrettyFormatter::reformat( source ) );
266 #else
267 Q_UNUSED( source );
268 #endif
271 #include "mailsourceviewer.moc"