File indexing completed on 2024-05-05 05:44:49

0001 /***************************************************************************
0002  *   Copyright (C) 2007 by Rajko Albrecht                                  *
0003  *   ral@alwins-world.de                                                   *
0004  *                                                                         *
0005  *   This program is free software; you can redistribute it and/or modify  *
0006  *   it under the terms of the GNU General Public License as published by  *
0007  *   the Free Software Foundation; either version 2 of the License, or     *
0008  *   (at your option) any later version.                                   *
0009  *                                                                         *
0010  *   This program is distributed in the hope that it will be useful,       *
0011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
0012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
0013  *   GNU General Public License for more details.                          *
0014  *                                                                         *
0015  *   You should have received a copy of the GNU General Public License     *
0016  *   along with this program; if not, write to the                         *
0017  *   Free Software Foundation, Inc.,                                       *
0018  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.         *
0019  ***************************************************************************/
0020 
0021 #include "diffbrowser.h"
0022 #include "diffsyntax.h"
0023 #include "settings/kdesvnsettings.h"
0024 
0025 #include <KFind>
0026 #include <KFindDialog>
0027 #include <KLocalizedString>
0028 #include <KMessageBox>
0029 #include <KMessageBox_KDESvnCompat>
0030 #include <KStandardGuiItem>
0031 #include <QFileDialog>
0032 
0033 #include <QApplication>
0034 #include <QFontDatabase>
0035 #include <QKeyEvent>
0036 #include <QTextCodec>
0037 
0038 /*!
0039     \fn DiffBrowser::DiffBrowser(QWidget*parent=0)
0040  */
0041 DiffBrowser::DiffBrowser(QWidget *parent)
0042     : QTextBrowser(parent)
0043     , m_srchdialog(nullptr)
0044 {
0045     //     setTextFormat(Qt::PlainText);
0046     setLineWrapMode(QTextEdit::NoWrap);
0047     setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont));
0048 
0049     setLineWrapMode(QTextEdit::NoWrap);
0050     m_Syntax = new DiffSyntax(document());
0051     setToolTip(i18n("Ctrl-F for search, F3 or Shift-F3 for search again."));
0052     setWhatsThis(
0053         i18n("<b>Display differences between files</b><p>You may search inside text with Ctrl-F.</p><p>F3 for search forward again, Shift-F3 for search "
0054              "backward again.</p><p>You may save the (original) output with Ctrl-S.</p>"));
0055     setFocus();
0056 }
0057 
0058 /*!
0059     \fn DiffBrowser::~DiffBrowser()
0060  */
0061 DiffBrowser::~DiffBrowser()
0062 {
0063     delete m_Syntax;
0064     delete m_srchdialog;
0065 }
0066 
0067 void DiffBrowser::setText(const QByteArray &aText)
0068 {
0069     m_content = aText;
0070     printContent();
0071     moveCursor(QTextCursor::Start);
0072 }
0073 
0074 void DiffBrowser::printContent()
0075 {
0076     QTextCodec *cc = QTextCodec::codecForName(Kdesvnsettings::locale_for_diff().toUtf8());
0077     if (!cc) {
0078         QTextBrowser::setText(QString::fromLocal8Bit(m_content));
0079     } else {
0080         QTextBrowser::setText(cc->toUnicode(m_content));
0081     }
0082 }
0083 
0084 /*!
0085     \fn DiffBrowser::saveDiff()
0086  */
0087 void DiffBrowser::saveDiff()
0088 {
0089     QString saveTo = QFileDialog::getSaveFileName(this, i18n("Save diff"), QString(), i18n("Patch file (*.diff *.patch)"));
0090     if (saveTo.isEmpty()) {
0091         return;
0092     }
0093     QFile tfile(saveTo);
0094     tfile.open(QIODevice::Truncate | QIODevice::WriteOnly | QIODevice::Unbuffered);
0095     tfile.write(m_content);
0096 }
0097 
0098 void DiffBrowser::keyPressEvent(QKeyEvent *ev)
0099 {
0100     if (ev->key() == Qt::Key_Return) {
0101         ev->ignore();
0102         return;
0103     }
0104     if (ev->key() == Qt::Key_F3) {
0105         if (ev->modifiers() == Qt::ShiftModifier) {
0106             searchagainback_slot();
0107         } else {
0108             searchagain_slot();
0109         }
0110     } else if (ev->key() == Qt::Key_F && ev->modifiers() == Qt::ControlModifier) {
0111         startSearch();
0112     } else if (ev->key() == Qt::Key_S && ev->modifiers() == Qt::ControlModifier) {
0113         saveDiff();
0114     } else {
0115         QTextBrowser::keyPressEvent(ev);
0116     }
0117 }
0118 
0119 void DiffBrowser::startSearch()
0120 {
0121     if (!m_srchdialog) {
0122         m_srchdialog = new KFindDialog(this);
0123         m_srchdialog->setSupportsWholeWordsFind(true);
0124         m_srchdialog->setHasCursor(false);
0125         m_srchdialog->setHasSelection(false);
0126         m_srchdialog->setSupportsRegularExpressionFind(false);
0127         connect(m_srchdialog, &KFindDialog::okClicked, this, &DiffBrowser::search_slot);
0128     }
0129     QString _st = m_srchdialog->pattern();
0130     m_srchdialog->setPattern(_st.isEmpty() ? m_pattern : _st);
0131     m_srchdialog->show();
0132 }
0133 
0134 /*!
0135     \fn DiffBrowser::search_slot()
0136  */
0137 void DiffBrowser::search_slot()
0138 {
0139     if (!m_srchdialog) {
0140         return;
0141     }
0142     doSearch(m_srchdialog->pattern(), (m_srchdialog->options() & KFind::FindBackwards) == KFind::FindBackwards);
0143 }
0144 
0145 void DiffBrowser::doSearch(const QString &to_find_string, bool back)
0146 {
0147     if (!m_srchdialog) {
0148         return;
0149     }
0150     while (true) {
0151         bool result;
0152         QTextDocument::FindFlags f;
0153         if (back) {
0154             f = QTextDocument::FindBackward;
0155         }
0156         if (m_srchdialog->options() & KFind::WholeWordsOnly) {
0157             f |= QTextDocument::FindWholeWords;
0158         }
0159         if (m_srchdialog->options() & KFind::CaseSensitive) {
0160             f |= QTextDocument::FindCaseSensitively;
0161         }
0162 
0163         result = find(to_find_string, f);
0164 
0165         if (result) {
0166             m_pattern = to_find_string;
0167             break;
0168         }
0169         QWidget *_parent = m_srchdialog->isVisible() ? m_srchdialog : parentWidget();
0170         if (!back) {
0171             KMessageBox::ButtonCode query = KMessageBox::questionTwoActions(_parent,
0172                                                                             i18n("End of document reached.\n"
0173                                                                                  "Continue from the beginning?"),
0174                                                                             i18n("Find"),
0175                                                                             KStandardGuiItem::cont(),
0176                                                                             KStandardGuiItem::cancel());
0177             if (query == KMessageBox::PrimaryAction) {
0178                 moveCursor(QTextCursor::Start);
0179             } else {
0180                 break;
0181             }
0182         } else {
0183             int query = KMessageBox::questionTwoActions(_parent,
0184                                                         i18n("Beginning of document reached.\n"
0185                                                              "Continue from the end?"),
0186                                                         i18n("Find"),
0187                                                         KStandardGuiItem::cont(),
0188                                                         KStandardGuiItem::cancel());
0189             if (query == KMessageBox::PrimaryAction) {
0190                 moveCursor(QTextCursor::End);
0191             } else {
0192                 break;
0193             }
0194         }
0195     }
0196 }
0197 
0198 void DiffBrowser::searchagain_slot()
0199 {
0200     doSearchAgain(false);
0201 }
0202 
0203 void DiffBrowser::searchagainback_slot()
0204 {
0205     doSearchAgain(true);
0206 }
0207 
0208 void DiffBrowser::doSearchAgain(bool back)
0209 {
0210     if (!m_srchdialog || m_pattern.isEmpty()) {
0211         startSearch();
0212     } else {
0213         doSearch(m_pattern, back);
0214     }
0215 }
0216 
0217 void DiffBrowser::slotTextCodecChanged(const QString &codec)
0218 {
0219     if (Kdesvnsettings::locale_for_diff() != codec) {
0220         Kdesvnsettings::setLocale_for_diff(codec);
0221         printContent();
0222         Kdesvnsettings::self()->save();
0223     }
0224 }
0225 
0226 #include "moc_diffbrowser.cpp"