1 /* This file is part of ksirc
2 Copyright (c) 2001 Malte Starostik <malte@kde.org>
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License version 2 as published by the Free Software Foundation.
8 This library is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 Library General Public License for more details.
13 You should have received a copy of the GNU Library General Public License
14 along with this library; see the file COPYING.LIB. If not, write to
15 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
16 Boston, MA 02110-1301, USA.
21 #include <qclipboard.h>
22 #include <qdatetime.h>
24 #include <q3dragobject.h>
25 #include <q3valuestack.h>
26 #include <q3stylesheet.h>
28 #include <QMouseEvent>
30 #include <QDragEnterEvent>
31 #include <QDragMoveEvent>
34 #include <QTextDocumentFragment>
37 #include <kapplication.h>
42 #include <kstringhandler.h>
43 #include <knotifyclient.h>
44 #include <kfiledialog.h>
46 #include <k3urldrag.h>
47 #include <kiconloader.h>
48 #include <QTextDocument>
53 #include "nickColourMaker.h"
54 #include "ksircprocess.h"
58 KSircView::KSircView(KSircProcess
*proc
, QWidget
*parent
, const char *name
)
59 : QTextBrowser(parent
), m_proc(proc
)
62 m_acceptFiles
= false;
65 setUndoRedoEnabled(false);
66 connect(this, SIGNAL(anchorClicked(const QUrl
&)),
67 this, SLOT(activateAnchor(const QUrl
&)));
69 QPixmap background
= ksopts
->backgroundPixmap();
70 if ( !background
.isNull() )
71 viewport()->setBackgroundPixmap( background
);
74 //setLinkColor( ksopts->linkColor );
77 KSircView::~KSircView()
81 void KSircView::clear()
85 QTextBrowser::clear();
88 QString
KSircView::makeTimeStamp()
90 QTime now
= QTime::currentTime();
91 QString timeStamp
= QString::fromLatin1( "[%1:%2:%3] " )
92 .arg( QString::number( now
.hour() ).rightJustified( 2, '0' ) )
93 .arg( QString::number( now
.minute() ).rightJustified( 2, '0' ) )
94 .arg( QString::number( now
.second() ).rightJustified( 2, '0' ) );
98 void KSircView::saveURL( const QString
&url
)
102 KFileDialog
*dlg
= new KFileDialog( QString::null
, QString::null
/*filter*/, this /*parent*/);
104 dlg
->setKeepLocation( true );
106 dlg
->setCaption( i18n( "Save As" ) );
108 if ( !kurl
.fileName().isEmpty() )
109 dlg
->setSelection( kurl
.fileName() );
112 KUrl
destURL( dlg
->selectedURL() );
113 if ( destURL
.isValid() ) {
114 KIO::Job
*job
= KIO::copy( kurl
, destURL
);
115 job
->setAutoErrorHandlingEnabled( true );
122 QString
KSircView::addLine(const QString
&pixmap
, const QColor
&color
, const QString
&_text
)
124 //kDebug(5008) << "Start Text: " << _text << endl;
126 QString
richText( "<font color=\"%1\">" );
127 richText
= richText
.arg( color
.name() );
129 if ( !pixmap
.isEmpty() )
130 richText
.prepend( QString::fromLatin1( "<img src=\"%1\"></img>" ).arg( pixmap
) );
132 QString timeStamp
= QString::fromLatin1( "<font color=\"%1\">%2</font>" )
133 .arg( ksopts
->textColor
.name() )
134 .arg( makeTimeStamp() );
135 m_timeStamps
.append(timeStamp
);
137 richText
.prepend( timeStamp
);
139 QString text
= Qt::escape(_text
);
141 // ### a bit of a hack: turn '<nick> message' into
142 // <span><nick><span> message' . span itself isn't supported but it
143 // enforces the creation of separate item objects and hence separate
144 // drawing of '<nick>' and 'message' , which is needed for BiDi users,
145 // according to UV Kochavi <uv1st@yahoo.com> , to prevent output like
146 // '<nick message<' , which is supposedly a bug in Qt's reordering. The
147 // same is done for [nick] and >nick< to catch queries.
148 QRegExp
bidiRe( "^(<\\S+>)(.+)$" );
149 text
.replace( bidiRe
, QString::fromLatin1( "<span>\\1</span>\\2" ) );
150 QRegExp
bidiRe2( "^(\\[\\S+\\])(.+)$" );
151 text
.replace( bidiRe2
, QString::fromLatin1( "<span>\\1</span>\\2" ) );
152 QRegExp
bidiRe3( "^(>\\S+<)(.+)$" );
153 text
.replace( bidiRe3
, QString::fromLatin1( "<span>\\1</span>\\2" ) );
155 QRegExp
nickCol( "~n(.+)~n" );
156 nickCol
.setMinimal(true);
159 while( (pos
= nickCol
.search(text
)) >= 0 ){
160 //kDebug(5008) << "Found nick: " << nickCol.cap(1) << endl;
161 QString newText
= nickCol
.cap(1);
162 if( nickCol
.cap(1) != m_proc
->getNick()){
163 QColor col
= nickColourMaker::colourMaker()->findFg(nickCol
.cap(1));
165 newText
.prepend(QString("<font color=\"%1\">").arg(col
.name()));
166 newText
.append("</font>");
168 QColor col
= ksopts
->ownNickColor
.name();
170 nickColourMaker::colourMaker()->findFg(nickCol
.cap(1));
171 newText
.prepend(QString("<font color=\"%1\">").arg(col
.name()));
172 newText
.append("</font>");
173 if(ksopts
->ownNickBold
){
174 newText
.prepend("<b>");
175 newText
.append("</b>");
177 if(ksopts
->ownNickUl
){
178 newText
.prepend("<u>");
179 newText
.append("</u>");
181 if(ksopts
->ownNickRev
){
182 newText
.prepend("<r>");
183 newText
.append("</r>");
186 text
.replace(pos
, nickCol
.matchedLength(), newText
);
189 //kDebug(5008) << "After Text: " << text << endl;
192 richText
+= parser
.parse( text
);
194 richText
+= "</font>";
197 //kDebug(5008) << "Text: " << _text << endl;
199 setCurrentCharFormat(QTextCharFormat());
200 richText
= KStringHandler::tagURLs( richText
);
201 //kDebug(5008) << "Rich text: " << richText << endl;
206 if ( ksopts
->windowLength
&& m_lines
> ksopts
->windowLength
)
208 while ( m_lines
> ksopts
->windowLength
)
210 QTextCursor cursor
= textCursor();
211 cursor
.movePosition(QTextCursor::Start
);
212 cursor
.movePosition(QTextCursor::NextBlock
, QTextCursor::KeepAnchor
);
213 cursor
.removeSelectedText();
214 m_timeStamps
.remove( m_timeStamps
.begin() );
219 if (parser
.beeped()) {
220 KNotifyClient::event(winId(), QString::fromLatin1("BeepReceived"),
221 i18n("Beep Received"));
224 QTextCursor cursor
= textCursor();
225 cursor
.movePosition(QTextCursor::End
);
226 QString logText
= cursor
.block().text();
227 // append timestamp if it's not already there
228 if ( ! m_timestamps
)
229 logText
.prepend( makeTimeStamp() );
233 return logText
+ '\n';
236 void KSircView::addRichText(const QString
&_text
)
238 //kDebug(5008) << "Start Text: " << _text << endl;
240 QString text
= _text
;
242 QRegExp
re("^(<font color=\"[^\"]+\">\\[[0-9:]+\\] </font>)");
245 if(re
.search(text
) >= 0){
246 timeStamp
= re
.cap(1);
249 timeStamp
= QString::fromLatin1( "<font color=\"%1\">%2</font>" )
250 .arg( ksopts
->textColor
.name() )
251 .arg( makeTimeStamp() );
253 text
.prepend( timeStamp
);
255 m_timeStamps
.append(timeStamp
);
257 setCurrentCharFormat(QTextCharFormat());
261 if ( ksopts
->windowLength
&& m_lines
> ksopts
->windowLength
)
263 while ( m_lines
> ksopts
->windowLength
)
265 QTextCursor cursor
= textCursor();
266 cursor
.movePosition(QTextCursor::Start
);
267 cursor
.movePosition(QTextCursor::NextBlock
, QTextCursor::KeepAnchor
);
268 cursor
.removeSelectedText();
269 m_timeStamps
.remove( m_timeStamps
.begin() );
277 void KSircView::enableTimeStamps(bool enable
)
279 if(enable
== m_timestamps
)
281 setUpdatesEnabled( false );
282 m_timestamps
= enable
;
283 const int timeStampLen
= makeTimeStamp().length();
284 QTextCursor cursor
= textCursor();
285 cursor
.movePosition(QTextCursor::Start
);
286 QStringList::ConstIterator timeStampIt
= m_timeStamps
.begin();
287 for (; timeStampIt
!= m_timeStamps
.end(); ++timeStampIt
)
290 cursor
.insertFragment(QTextDocumentFragment::fromHtml(*timeStampIt
));
292 cursor
.movePosition(QTextCursor::NextCharacter
, QTextCursor::KeepAnchor
, timeStampLen
);
293 cursor
.removeSelectedText();
295 cursor
.movePosition(QTextCursor::NextBlock
);
297 setUpdatesEnabled( true );
300 void KSircView::activateAnchor(const QUrl
&url
)
302 const QString u
= url
.toString();
303 if (QApplication::keyboardModifiers() & Qt::ShiftModifier
)
309 void KSircView::contextMenuEvent(QContextMenuEvent
*e
)
311 const QString url
= anchorAt(e
->pos());
315 // Adding a nice contextmenu
316 KMenu
* menu
= new KMenu( this );
317 menu
->addTitle( i18n( "URL" ) );
318 QAction
* openUrl
= menu
->addAction( i18n("Open URL") );
319 QAction
* opendLink
= menu
->addAction( i18n("Copy Link Address"));
320 QAction
*ret
= menu
->exec( e
->globalPos() );
323 else if( ret
== opendLink
)
324 copyLinkToClipboard( url
);
328 void KSircView::openBrowser(const QString
&url
)
330 (void) new KRun( KUrl( url
.startsWith("www") ? QString::fromLatin1("http://") + url
: url
),this);
333 void KSircView::copyLinkToClipboard( const QString
&url
)
335 QApplication::clipboard()->setText( url
, QClipboard::Clipboard
);
338 QColor
KSircView::ircColor(int code
)
340 if (code
>= 0 && code
< 16)
341 return ksopts
->ircColors
[code
];
345 void KSircView::dragEnterEvent(QDragEnterEvent
* event
)
347 event
->accept((Q3TextDrag::canDecode(event
) ||
348 (m_acceptFiles
&& K3URLDrag::canDecode(event
))) &&
349 (!event
->source() || event
->source() != viewport()));
352 void KSircView::dragMoveEvent(QDragMoveEvent
* event
)
354 event
->accept(!event
->source() || event
->source() != viewport());
357 void KSircView::dropEvent(QDropEvent
* event
)
362 if (m_acceptFiles
&& K3URLDrag::decodeLocalFiles(event
, urls
))
363 emit
urlsDropped(urls
);
364 else if (Q3TextDrag::decode(event
, text
))
365 emit
textDropped(text
);
368 QVariant
KSircView::loadResource(int type
, const QUrl
&name
)
370 if (type
!= QTextDocument::ImageResource
) {
371 return QTextBrowser::loadResource(type
, name
);
375 icon
.remove("user|");
376 return UserIcon(icon
);
379 void KSircView::scrollToBottom()
381 verticalScrollBar()->setValue(verticalScrollBar()->maximum());
384 void KSircView::resizeEvent(QResizeEvent
*e
)
386 QTextBrowser::resizeEvent(e
);
390 // vim: ts=4 sw=4 noet