File indexing completed on 2024-05-12 17:16:02

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 <QFileDialog>
0026 #include <KMessageBox>
0027 #include <KLocalizedString>
0028 #include <KStandardGuiItem>
0029 #include <KFind>
0030 #include <KFindDialog>
0031 
0032 #include <QApplication>
0033 #include <QFontDatabase>
0034 #include <QKeyEvent>
0035 #include <QTextCodec>
0036 
0037 /*!
0038     \fn DiffBrowser::DiffBrowser(QWidget*parent=0)
0039  */
0040 DiffBrowser::DiffBrowser(QWidget *parent)
0041     : QTextBrowser(parent)
0042     , m_srchdialog(nullptr)
0043 {
0044 //     setTextFormat(Qt::PlainText);
0045     setLineWrapMode(QTextEdit::NoWrap);
0046     setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont));
0047 
0048     setLineWrapMode(QTextEdit::NoWrap);
0049     m_Syntax = new DiffSyntax(document());
0050     setToolTip(i18n("Ctrl-F for search, F3 or Shift-F3 for search again."));
0051     setWhatsThis(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 backward again.</p><p>You may save the (original) output with Ctrl-S.</p>"));
0052     setFocus();
0053 }
0054 
0055 /*!
0056     \fn DiffBrowser::~DiffBrowser()
0057  */
0058 DiffBrowser::~DiffBrowser()
0059 {
0060     delete m_Syntax;
0061     delete m_srchdialog;
0062 }
0063 
0064 void DiffBrowser::setText(const QByteArray &aText)
0065 {
0066     m_content = aText;
0067     printContent();
0068     moveCursor(QTextCursor::Start);
0069 }
0070 
0071 void DiffBrowser::printContent()
0072 {
0073     QTextCodec *cc = QTextCodec::codecForName(Kdesvnsettings::locale_for_diff().toUtf8());
0074     if (!cc) {
0075         QTextBrowser::setText(QString::fromLocal8Bit(m_content));
0076     } else {
0077         QTextBrowser::setText(cc->toUnicode(m_content));
0078     }
0079 }
0080 
0081 /*!
0082     \fn DiffBrowser::saveDiff()
0083  */
0084 void DiffBrowser::saveDiff()
0085 {
0086     QString saveTo = QFileDialog::getSaveFileName(this, i18n("Save diff"), QString(), i18n("Patch file (*.diff *.patch)"));
0087     if (saveTo.isEmpty()) {
0088         return;
0089     }
0090     QFile tfile(saveTo);
0091     if (tfile.exists()) {
0092         if (KMessageBox::warningYesNo(QApplication::activeModalWidget(),
0093                                       i18n("File %1 exists - overwrite?", saveTo))
0094                 != KMessageBox::Yes) {
0095             return;
0096         }
0097     }
0098     tfile.open(QIODevice::Truncate | QIODevice::WriteOnly | QIODevice::Unbuffered);
0099     tfile.write(m_content);
0100 }
0101 
0102 void DiffBrowser::keyPressEvent(QKeyEvent *ev)
0103 {
0104     if (ev->key() == Qt::Key_Return) {
0105         ev->ignore();
0106         return;
0107     }
0108     if (ev->key() == Qt::Key_F3) {
0109         if (ev->modifiers() == Qt::ShiftModifier) {
0110             searchagainback_slot();
0111         } else {
0112             searchagain_slot();
0113         }
0114     } else if (ev->key() == Qt::Key_F && ev->modifiers() == Qt::ControlModifier) {
0115         startSearch();
0116     } else if (ev->key() == Qt::Key_S && ev->modifiers() == Qt::ControlModifier) {
0117         saveDiff();
0118     } else {
0119         QTextBrowser::keyPressEvent(ev);
0120     }
0121 }
0122 
0123 void DiffBrowser::startSearch()
0124 {
0125     if (!m_srchdialog) {
0126         m_srchdialog = new KFindDialog(this);
0127         m_srchdialog->setSupportsWholeWordsFind(true);
0128         m_srchdialog->setHasCursor(false);
0129         m_srchdialog->setHasSelection(false);
0130         m_srchdialog->setSupportsRegularExpressionFind(false);
0131         connect(m_srchdialog, &KFindDialog::okClicked, this, &DiffBrowser::search_slot);
0132     }
0133     QString _st = m_srchdialog->pattern();
0134     m_srchdialog->setPattern(_st.isEmpty() ? m_pattern : _st);
0135     m_srchdialog->show();
0136 }
0137 
0138 /*!
0139     \fn DiffBrowser::search_slot()
0140  */
0141 void DiffBrowser::search_slot()
0142 {
0143     if (!m_srchdialog) {
0144         return;
0145     }
0146     doSearch(m_srchdialog->pattern(),
0147              (m_srchdialog->options() & KFind::FindBackwards) == KFind::FindBackwards);
0148 }
0149 
0150 void DiffBrowser::doSearch(const QString &to_find_string, bool back)
0151 {
0152     if (!m_srchdialog) {
0153         return;
0154     }
0155     while (true) {
0156         bool result;
0157         QTextDocument::FindFlags f;
0158         if (back) {
0159             f = QTextDocument::FindBackward;
0160         }
0161         if (m_srchdialog->options()&KFind::WholeWordsOnly) {
0162             f |= QTextDocument::FindWholeWords;
0163         }
0164         if (m_srchdialog->options()&KFind::CaseSensitive) {
0165             f |= QTextDocument::FindCaseSensitively;
0166         }
0167 
0168         result = find(to_find_string, f);
0169 
0170         if (result) {
0171             m_pattern = to_find_string;
0172             break;
0173         }
0174         QWidget *_parent = m_srchdialog->isVisible() ? m_srchdialog : parentWidget();
0175         if (!back) {
0176             KMessageBox::ButtonCode query = KMessageBox::questionYesNo(_parent,
0177                                                                        i18n("End of document reached.\n"\
0178                                                                             "Continue from the beginning?"),
0179                                                                        i18n("Find"),
0180                                                                        KStandardGuiItem::yes(),
0181                                                                        KStandardGuiItem::no());
0182             if (query == KMessageBox::Yes) {
0183                 moveCursor(QTextCursor::Start);
0184             } else {
0185                 break;
0186             }
0187         } else {
0188             int query = KMessageBox::questionYesNo(
0189                             _parent,
0190                             i18n("Beginning of document reached.\n"\
0191                                  "Continue from the end?"),
0192                             i18n("Find"),
0193                             KStandardGuiItem::yes(),
0194                             KStandardGuiItem::no());
0195             if (query == KMessageBox::Yes) {
0196                 moveCursor(QTextCursor::End);
0197             } else {
0198                 break;
0199             }
0200         }
0201     }
0202 }
0203 
0204 void DiffBrowser::searchagain_slot()
0205 {
0206     doSearchAgain(false);
0207 }
0208 
0209 void DiffBrowser::searchagainback_slot()
0210 {
0211     doSearchAgain(true);
0212 }
0213 
0214 void DiffBrowser::doSearchAgain(bool back)
0215 {
0216     if (!m_srchdialog || m_pattern.isEmpty()) {
0217         startSearch();
0218     } else {
0219         doSearch(m_pattern, back);
0220     }
0221 }
0222 
0223 void DiffBrowser::slotTextCodecChanged(const QString &codec)
0224 {
0225     if (Kdesvnsettings::locale_for_diff() != codec) {
0226         Kdesvnsettings::setLocale_for_diff(codec);
0227         printContent();
0228         Kdesvnsettings::self()->save();
0229     }
0230 }