Warning, file /sdk/cervisia/logplainview.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /*
0002  *  Copyright (c) 2003 Christian Loose <christian.loose@hamburg.de>
0003  *
0004  * This program is free software; you can redistribute it and/or modify
0005  * it under the terms of the GNU General Public License as published by
0006  * the Free Software Foundation; either version 2 of the License, or
0007  * (at your option) any later version.
0008  *
0009  * This program is distributed in the hope that it will be useful,
0010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0012  * GNU General Public License for more details.
0013  *
0014  * You should have received a copy of the GNU General Public License
0015  * along with this program; if not, write to the Free Software
0016  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
0017  */
0018 
0019 #include "logplainview.h"
0020 
0021 #include "loginfo.h"
0022 #include <KLocalizedString>
0023 #include <QScrollBar>
0024 #include <kfind.h>
0025 #include <kfinddialog.h>
0026 
0027 using namespace Cervisia;
0028 
0029 LogPlainView::LogPlainView(QWidget *parent)
0030     : QTextBrowser(parent)
0031     , m_find(0)
0032 {
0033 }
0034 
0035 LogPlainView::~LogPlainView()
0036 {
0037     delete m_find;
0038     m_find = 0;
0039 }
0040 
0041 void LogPlainView::addRevision(const LogInfo &logInfo)
0042 {
0043     // assemble revision information lines
0044     QString logEntry;
0045 
0046     logEntry += "<b>" + i18n("revision %1", logInfo.m_revision.toHtmlEscaped()) + "</b>";
0047     logEntry += " &nbsp;[<a href=\"revA#" + logInfo.m_revision.toHtmlEscaped() + "\">" + i18n("Select for revision A") + "</a>]";
0048     logEntry += " [<a href=\"revB#" + logInfo.m_revision.toHtmlEscaped() + "\">" + i18n("Select for revision B") + "</a>]<br>";
0049     logEntry += "<i>" + i18n("date: %1; author: %2", logInfo.dateTimeToString().toHtmlEscaped(), logInfo.m_author.toHtmlEscaped()) + "</i><br><br>";
0050 
0051     insertHtml(logEntry);
0052 
0053     const QLatin1String lineBreak("<br>");
0054 
0055     insertPlainText(logInfo.m_comment);
0056     insertHtml(lineBreak);
0057 
0058     for (LogInfo::TTagInfoSeq::const_iterator it = logInfo.m_tags.begin(); it != logInfo.m_tags.end(); ++it) {
0059         insertHtml("<br><i>" + (*it).toString().toHtmlEscaped() + "</i>");
0060     }
0061 
0062     // add an empty line when we had tags or branches
0063     if (!logInfo.m_tags.empty())
0064         insertHtml(lineBreak);
0065     // seems to be superfluous with Qt 4.4
0066     // insertHtml(lineBreak);
0067 
0068     // workaround Qt bug (TT ID 166111)
0069     const QTextBlockFormat blockFmt(textCursor().blockFormat());
0070 
0071     // add horizontal line
0072     insertHtml(QLatin1String("<hr><br>"));
0073 
0074     textCursor().setBlockFormat(blockFmt);
0075 }
0076 
0077 void LogPlainView::searchText(int options, const QString &pattern)
0078 {
0079     m_find = new KFind(pattern, options, this);
0080 
0081     connect(m_find, SIGNAL(highlight(QString, int, int)), this, SLOT(searchHighlight(QString, int, int)));
0082     connect(m_find, SIGNAL(findNext()), this, SLOT(findNext()));
0083 
0084     m_currentBlock = (m_find->options() & KFind::FindBackwards) ? document()->end().previous() : document()->begin();
0085     if (options & KFind::FromCursor) {
0086 #ifdef __GNUC__
0087 #warning maybe this can be improved
0088 #endif
0089         const QPoint pos(horizontalScrollBar()->value(), 0);
0090         const QTextCursor cursor(cursorForPosition(pos));
0091         if (!cursor.isNull())
0092             m_currentBlock = cursor.block();
0093     }
0094 
0095     findNext();
0096 }
0097 
0098 void LogPlainView::scrollToTop()
0099 {
0100     QTextCursor cursor(document());
0101     cursor.movePosition(QTextCursor::Start);
0102     setTextCursor(cursor);
0103 }
0104 
0105 void LogPlainView::findNext()
0106 {
0107     KFind::Result res = KFind::NoMatch;
0108 
0109     while ((res == KFind::NoMatch) && m_currentBlock.isValid()) {
0110         if (m_find->needData())
0111             m_find->setData(m_currentBlock.text());
0112 
0113         res = m_find->find();
0114 
0115         if (res == KFind::NoMatch) {
0116             if (m_find->options() & KFind::FindBackwards)
0117                 m_currentBlock = m_currentBlock.previous();
0118             else
0119                 m_currentBlock = m_currentBlock.next();
0120         }
0121     }
0122 
0123     // reached the end?
0124     if (res == KFind::NoMatch) {
0125         if (m_find->shouldRestart()) {
0126             m_currentBlock = (m_find->options() & KFind::FindBackwards) ? document()->end().previous() : document()->begin();
0127             findNext();
0128         } else {
0129             delete m_find;
0130             m_find = 0;
0131         }
0132     }
0133 }
0134 
0135 void LogPlainView::searchHighlight(const QString &text, int index, int length)
0136 {
0137     Q_UNUSED(text);
0138 
0139     const int position(m_currentBlock.position() + index);
0140 
0141     QTextCursor cursor(document());
0142     cursor.setPosition(position);
0143     cursor.setPosition(position + length, QTextCursor::KeepAnchor);
0144     setTextCursor(cursor);
0145 }
0146 
0147 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
0148 void LogPlainView::setSource(const QUrl &url)
0149 #else
0150 void LogPlainView::doSetSource(const QUrl &url, QTextDocument::ResourceType type)
0151 #endif
0152 {
0153     const QString name(url.toString());
0154     if (name.isEmpty())
0155         return;
0156 
0157     bool selectedRevisionB = name.startsWith(QLatin1String("revB#"));
0158     if (selectedRevisionB || name.startsWith(QLatin1String("revA#"))) {
0159         emit revisionClicked(name.mid(5), selectedRevisionB);
0160     }
0161 }