[kde-doc-english] [ktexteditor] src: move speel check dialog to bottom view bar

Michal Humpula michal.humpula at seznam.cz
Thu Feb 27 20:05:34 UTC 2014


Git commit 6bd160e438b5e0fd2343247410d0ed7a1075e7cc by Michal Humpula.
Committed on 17/01/2014 at 16:38.
Pushed by michalhumpula into branch 'master'.

move speel check dialog to bottom view bar

The ui is reasonably finished. The code could survive more polishing
but works mostly as expected.

REVIEW: 115080
GUI: spellcheck is now in bottom view bar

M  +2    -0    src/CMakeLists.txt
A  +447  -0    src/spellcheck/spellcheckbar.cpp     [License: LGPL (v2.1+)]
A  +160  -0    src/spellcheck/spellcheckbar.h     [License: LGPL (v2.1+)]
A  +251  -0    src/spellcheck/spellcheckbar.ui
M  +7    -2    src/spellcheck/spellcheckdialog.cpp
M  +7    -6    src/spellcheck/spellcheckdialog.h

http://commits.kde.org/ktexteditor/6bd160e438b5e0fd2343247410d0ed7a1075e7cc

diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 13f8f39..c6946de 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -156,6 +156,7 @@ spellcheck/spellcheck.h
 spellcheck/spellcheck.cpp
 spellcheck/spellcheckdialog.h
 spellcheck/spellcheckdialog.cpp
+spellcheck/spellcheckbar.cpp
 spellcheck/spellingmenu.h
 spellcheck/spellingmenu.cpp
 
@@ -220,6 +221,7 @@ dialogs/modonhdwidget.ui
 dialogs/completionconfigwidget.ui
 search/searchbarincremental.ui
 search/searchbarpower.ui
+spellcheck/spellcheckbar.ui
 dialogs/viinputmodeconfigwidget.ui
 dialogs/spellcheckconfigwidget.ui
 schema/howtoimportschema.ui )
diff --git a/src/spellcheck/spellcheckbar.cpp b/src/spellcheck/spellcheckbar.cpp
new file mode 100644
index 0000000..30d7a77
--- /dev/null
+++ b/src/spellcheck/spellcheckbar.cpp
@@ -0,0 +1,447 @@
+/**
+ * Copyright (C)  2003  Zack Rusin <zack at kde.org>
+ * Copyright (C)  2009-2010  Michel Ludwig <michel.ludwig at kdemail.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301  USA
+ */
+#include "spellcheckbar.h"
+#include "ui_spellcheckbar.h"
+
+#include "sonnet/backgroundchecker.h"
+#include "sonnet/speller.h"
+/*
+#include "sonnet/filter_p.h"
+#include "sonnet/settings_p.h"
+*/
+
+#include <qprogressdialog.h>
+
+#include <QDialogButtonBox>
+#include <QListView>
+#include <QStringListModel>
+#include <QPushButton>
+#include <QComboBox>
+#include <QLabel>
+#include <QtCore/QTimer>
+#include <QMessageBox>
+
+//to initially disable sorting in the suggestions listview
+#define NONSORTINGCOLUMN 2
+
+class ReadOnlyStringListModel: public QStringListModel
+{
+public:
+    ReadOnlyStringListModel(QObject *parent): QStringListModel(parent) {}
+    Qt::ItemFlags flags(const QModelIndex &index) const
+    {
+        Q_UNUSED(index);
+        return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
+    }
+};
+
+/**
+ * Structure abstracts the word and its position in the
+ * parent text.
+ *
+ * @author Zack Rusin <zack at kde.org>
+ * @short struct represents word
+ */
+struct Word {
+  Word() : start(0), end(true)
+  {}
+
+  Word(const QString &w, int st, bool e = false)
+  : word(w), start(st), end(e)
+  {}
+  Word(const Word &other)
+  : word(other.word), start(other.start),
+  end(other.end)
+  {}
+
+  QString word;
+  int    start;
+  bool    end;
+};
+
+class SpellCheckBar::Private
+{
+public:
+    Ui_SonnetUi ui;
+    ReadOnlyStringListModel *suggestionsModel;
+    QWidget *wdg;
+    QDialogButtonBox *buttonBox;
+    QProgressDialog *progressDialog;
+    QString   originalBuffer;
+    Sonnet::BackgroundChecker *checker;
+
+    Word   currentWord;
+    QMap<QString, QString> replaceAllMap;
+    bool restart;//used when text is distributed across several qtextedits, eg in KAider
+
+    QMap<QString, QString> dictsMap;
+
+    int progressDialogTimeout;
+    bool showCompletionMessageBox;
+    bool spellCheckContinuedAfterReplacement;
+    bool canceled;
+
+    void deleteProgressDialog(bool directly)
+    {
+        if (progressDialog) {
+            progressDialog->hide();
+            if (directly) {
+                delete progressDialog;
+            } else {
+                progressDialog->deleteLater();
+            }
+            progressDialog = NULL;
+        }
+    }
+};
+
+SpellCheckBar::SpellCheckBar(Sonnet::BackgroundChecker *checker, QWidget *parent)
+    : KateViewBarWidget(true, parent),
+      d(new Private)
+{
+    d->checker = checker;
+
+    d->canceled = false;
+    d->showCompletionMessageBox = false;
+    d->spellCheckContinuedAfterReplacement = true;
+    d->progressDialogTimeout = -1;
+    d->progressDialog = NULL;
+
+    initGui();
+    initConnections();
+}
+
+SpellCheckBar::~SpellCheckBar()
+{
+    delete d;
+}
+
+void SpellCheckBar::closed()
+{
+    if (viewBar()) {
+        viewBar()->removeBarWidget(this);
+    }
+
+    // called from hideMe, so don't call it again!
+    d->canceled = true;
+    d->deleteProgressDialog(false); // this method can be called in response to
+    // pressing 'Cancel' on the dialog
+    emit cancel();
+    emit spellCheckStatus(tr("Spell check canceled."));
+}
+
+void SpellCheckBar::initConnections()
+{
+    connect(d->ui.m_addBtn, SIGNAL(clicked()),
+            SLOT(slotAddWord()));
+    connect(d->ui.m_replaceBtn, SIGNAL(clicked()),
+            SLOT(slotReplaceWord()));
+    connect(d->ui.m_replaceAllBtn, SIGNAL(clicked()),
+            SLOT(slotReplaceAll()));
+    connect(d->ui.m_skipBtn, SIGNAL(clicked()),
+            SLOT(slotSkip()));
+    connect(d->ui.m_skipAllBtn, SIGNAL(clicked()),
+            SLOT(slotSkipAll()));
+    connect(d->ui.m_suggestBtn, SIGNAL(clicked()),
+            SLOT(slotSuggest()));
+    connect(d->ui.m_language, SIGNAL(activated(QString)),
+            SLOT(slotChangeLanguage(QString)));
+    connect(d->checker, SIGNAL(misspelling(QString,int)),
+            SLOT(slotMisspelling(QString,int)));
+    connect(d->checker, SIGNAL(done()),
+            SLOT(slotDone()));
+    /*
+    connect(d->ui.m_suggestions, SIGNAL(doubleClicked(QModelIndex)),
+            SLOT(slotReplaceWord()));
+            */
+
+    connect(d->ui.cmbReplacement, SIGNAL(returnPressed()), this, SLOT(slotReplaceWord()));
+    connect(d->ui.m_autoCorrect, SIGNAL(clicked()),
+            SLOT(slotAutocorrect()));
+    // button use by kword/kpresenter
+    // hide by default
+    d->ui.m_autoCorrect->hide();
+}
+
+void SpellCheckBar::initGui()
+{
+    QVBoxLayout *layout = new QVBoxLayout;
+    layout->setMargin(0);
+    centralWidget()->setLayout(layout);
+
+    d->wdg = new QWidget(this);
+    d->ui.setupUi(d->wdg);
+    layout->addWidget(d->wdg);
+    setGuiEnabled(false);
+
+    /*
+    d->buttonBox = new QDialogButtonBox(this);
+    d->buttonBox->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
+
+    layout->addWidget(d->buttonBox);
+    */
+
+    //d->ui.m_suggestions->setSorting( NONSORTINGCOLUMN );
+    fillDictionaryComboBox();
+    d->restart = false;
+
+    d->suggestionsModel = new ReadOnlyStringListModel(this);
+    d->ui.cmbReplacement->setModel(d->suggestionsModel);
+}
+
+void SpellCheckBar::activeAutoCorrect(bool _active)
+{
+    if (_active) {
+        d->ui.m_autoCorrect->show();
+    } else {
+        d->ui.m_autoCorrect->hide();
+    }
+}
+
+void SpellCheckBar::showProgressDialog(int timeout)
+{
+    d->progressDialogTimeout = timeout;
+}
+
+void SpellCheckBar::showSpellCheckCompletionMessage(bool b)
+{
+    d->showCompletionMessageBox = b;
+}
+
+void SpellCheckBar::setSpellCheckContinuedAfterReplacement(bool b)
+{
+    d->spellCheckContinuedAfterReplacement = b;
+}
+
+void SpellCheckBar::slotAutocorrect()
+{
+    setGuiEnabled(false);
+    setProgressDialogVisible(true);
+    emit autoCorrect(d->currentWord.word, d->ui.cmbReplacement->lineEdit()->text());
+    slotReplaceWord();
+}
+
+void SpellCheckBar::setGuiEnabled(bool b)
+{
+    d->wdg->setEnabled(b);
+}
+
+void SpellCheckBar::setProgressDialogVisible(bool b)
+{
+    if (!b) {
+        d->deleteProgressDialog(true);
+    } else if (d->progressDialogTimeout >= 0) {
+        if (d->progressDialog) {
+            return;
+        }
+        d->progressDialog = new QProgressDialog(this);
+        d->progressDialog->setLabelText(tr("Spell checking in progress...", "progress label"));
+        d->progressDialog->setWindowTitle(tr("Check Spelling", "@title:window"));
+        d->progressDialog->setModal(true);
+        d->progressDialog->setAutoClose(false);
+        d->progressDialog->setAutoReset(false);
+        // create an 'indefinite' progress box as we currently cannot get progress feedback from
+        // the speller
+        d->progressDialog->reset();
+        d->progressDialog->setRange(0, 0);
+        d->progressDialog->setValue(0);
+        connect(d->progressDialog, SIGNAL(canceled()), this, SLOT(slotCancel()));
+        d->progressDialog->setMinimumDuration(d->progressDialogTimeout);
+    }
+}
+
+void SpellCheckBar::slotCancel()
+{
+    hideMe();
+}
+
+QString SpellCheckBar::originalBuffer() const
+{
+    return d->originalBuffer;
+}
+
+QString SpellCheckBar::buffer() const
+{
+    return d->checker->text();
+}
+
+void SpellCheckBar::setBuffer(const QString &buf)
+{
+    d->originalBuffer = buf;
+    //it is possible to change buffer inside slot connected to done() signal
+    d->restart = true;
+}
+
+void SpellCheckBar::fillDictionaryComboBox()
+{
+    Sonnet::Speller speller = d->checker->speller();
+    d->dictsMap = speller.availableDictionaries();
+    QStringList langs = d->dictsMap.keys();
+    d->ui.m_language->clear();
+    d->ui.m_language->addItems(langs);
+    updateDictionaryComboBox();
+}
+
+void SpellCheckBar::updateDictionaryComboBox()
+{
+    Sonnet::Speller speller = d->checker->speller();
+    d->ui.m_language->setCurrentIndex(d->dictsMap.values().indexOf(speller.language()));
+}
+
+void SpellCheckBar::updateDialog(const QString &word)
+{
+    d->ui.m_unknownWord->setText(word);
+    //d->ui.m_contextLabel->setText(d->checker->currentContext());
+    const QStringList suggs = d->checker->suggest(word);
+
+    if (suggs.isEmpty()) {
+        d->ui.cmbReplacement->lineEdit()->clear();
+    } else {
+        d->ui.cmbReplacement->lineEdit()->setText(suggs.first());
+    }
+    fillSuggestions(suggs);
+}
+
+void SpellCheckBar::show()
+{
+    d->canceled = false;
+    fillDictionaryComboBox();
+    updateDictionaryComboBox();
+    if (d->originalBuffer.isEmpty()) {
+        d->checker->start();
+    } else {
+        d->checker->setText(d->originalBuffer);
+    }
+    setProgressDialogVisible(true);
+}
+
+void SpellCheckBar::slotAddWord()
+{
+    setGuiEnabled(false);
+    setProgressDialogVisible(true);
+    d->checker->addWordToPersonal(d->currentWord.word);
+    d->checker->continueChecking();
+}
+
+void SpellCheckBar::slotReplaceWord()
+{
+    setGuiEnabled(false);
+    setProgressDialogVisible(true);
+    const QString replacementText = d->ui.cmbReplacement->lineEdit()->text();
+    emit replace(d->currentWord.word, d->currentWord.start,
+                 replacementText);
+
+    if (d->spellCheckContinuedAfterReplacement) {
+        d->checker->replace(d->currentWord.start,
+                            d->currentWord.word,
+                            replacementText);
+        d->checker->continueChecking();
+    } else {
+        d->checker->stop();
+    }
+}
+
+void SpellCheckBar::slotReplaceAll()
+{
+    setGuiEnabled(false);
+    setProgressDialogVisible(true);
+    d->replaceAllMap.insert(d->currentWord.word,
+                            d->ui.cmbReplacement->lineEdit()->text());
+    slotReplaceWord();
+}
+
+void SpellCheckBar::slotSkip()
+{
+    setGuiEnabled(false);
+    setProgressDialogVisible(true);
+    d->checker->continueChecking();
+}
+
+void SpellCheckBar::slotSkipAll()
+{
+    setGuiEnabled(false);
+    setProgressDialogVisible(true);
+    //### do we want that or should we have a d->ignoreAll list?
+    Sonnet::Speller speller = d->checker->speller();
+    speller.addToPersonal(d->currentWord.word);
+    d->checker->setSpeller(speller);
+    d->checker->continueChecking();
+}
+
+void SpellCheckBar::slotSuggest()
+{
+    QStringList suggs = d->checker->suggest(d->ui.cmbReplacement->lineEdit()->text());
+    fillSuggestions(suggs);
+}
+
+void SpellCheckBar::slotChangeLanguage(const QString &lang)
+{
+    Sonnet::Speller speller = d->checker->speller();
+    QString languageCode = d->dictsMap[lang];
+    if (!languageCode.isEmpty()) {
+        d->checker->changeLanguage(languageCode);
+        slotSuggest();
+        emit languageChanged(languageCode);
+    }
+}
+
+void SpellCheckBar::fillSuggestions(const QStringList &suggs)
+{
+    d->suggestionsModel->setStringList(suggs);
+}
+
+void SpellCheckBar::slotMisspelling(const QString &word, int start)
+{
+    setGuiEnabled(true);
+    setProgressDialogVisible(false);
+    emit misspelling(word, start);
+    //NOTE this is HACK I had to introduce because BackgroundChecker lacks 'virtual' marks on methods
+    //this dramatically reduces spellchecking time in Lokalize
+    //as this doesn't fetch suggestions for words that are present in msgid
+    if (!updatesEnabled()) {
+        return;
+    }
+
+    d->currentWord = Word(word, start);
+    if (d->replaceAllMap.contains(word)) {
+        d->ui.cmbReplacement->lineEdit()->setText(d->replaceAllMap[ word ]);
+        slotReplaceWord();
+    } else {
+        updateDialog(word);
+    }
+}
+
+void SpellCheckBar::slotDone()
+{
+    d->restart = false;
+    emit done(d->checker->text());
+    if (d->restart) {
+        updateDictionaryComboBox();
+        d->checker->setText(d->originalBuffer);
+        d->restart = false;
+    } else {
+        setProgressDialogVisible(false);
+        emit spellCheckStatus(tr("Spell check complete."));
+        hideMe();
+        if (!d->canceled && d->showCompletionMessageBox) {
+            QMessageBox::information(this, tr("Spell check complete."), tr("Check Spelling", "@title:window"));
+        }
+    }
+}
diff --git a/src/spellcheck/spellcheckbar.h b/src/spellcheck/spellcheckbar.h
new file mode 100644
index 0000000..d06be41
--- /dev/null
+++ b/src/spellcheck/spellcheckbar.h
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C)  2003  Zack Rusin <zack at kde.org>
+ * Copyright (C)  2009-2010  Michel Ludwig <michel.ludwig at kdemail.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301  USA
+ */
+
+#ifndef SONNET_DIALOG_H
+#define SONNET_DIALOG_H
+
+#include "kateviewhelpers.h"
+
+class QListWidgetItem;
+class QModelIndex;
+
+namespace Sonnet
+{
+class BackgroundChecker;
+};
+
+/**
+ * @short Spellcheck dialog
+ *
+ * \code
+ * Sonnet::SpellCheckBar dlg = new Sonnet::SpellCheckBar(
+ *       new Sonnet::BackgroundChecker(this), this);
+ * //connect signals
+ * ...
+ * dlg->setBuffer( someText );
+ * dlg->show();
+ * \endcode
+ *
+ * You can change buffer inside a slot connected to done() signal
+ * and spellcheck will continue with new data automatically.
+ */
+class SpellCheckBar : public KateViewBarWidget
+{
+    Q_OBJECT
+  public:
+    SpellCheckBar(Sonnet::BackgroundChecker *checker, QWidget *parent);
+    ~SpellCheckBar();
+
+    QString originalBuffer() const;
+    QString buffer() const;
+
+    virtual void closed();
+
+    void show();
+    void activeAutoCorrect(bool _active);
+
+    /**
+     * Controls whether an (indefinite) progress dialog is shown when the spell
+     * checking takes longer than the given time to complete. By default no
+     * progress dialog is shown. If the progress dialog is set to be shown, no
+     * time consuming operation (for example, showing a notification message) should
+     * be performed in a slot connected to the 'done' signal as this might trigger
+     * the progress dialog unnecessarily.
+     *
+     * @param timeout time after which the progress dialog should appear; a negative
+     *                value can be used to hide it
+     * @since 4.4
+     */
+    void showProgressDialog(int timeout = 500);
+
+    /**
+     * Controls whether a message box indicating the completion of the spell checking
+     * is shown or not. By default it is not shown.
+     *
+     * @since 4.4
+     */
+    void showSpellCheckCompletionMessage(bool b = true);
+
+    /**
+     * Controls whether the spell checking is continued after the replacement of a
+     * misspelled word has been performed. By default it is continued.
+     *
+     * @since 4.4
+     */
+    void setSpellCheckContinuedAfterReplacement(bool b);
+
+  public Q_SLOTS:
+    void setBuffer(const QString &);
+
+  Q_SIGNALS:
+    /**
+     * The dialog won't be closed if you setBuffer() in slot connected to this signal
+     *
+     * Also emitted after stop() signal
+     */
+    void done(const QString &newBuffer);
+    void misspelling(const QString &word, int start);
+    void replace(const QString &oldWord, int start,
+                 const QString &newWord);
+
+    void stop();
+    void cancel();
+    void autoCorrect(const QString &currentWord, const QString &replaceWord);
+
+    /**
+     * Signal sends when spell checking is finished/stopped/completed
+     * @since 4.1
+     */
+    void spellCheckStatus(const QString &);
+
+    /**
+     * Emitted when the user changes the language used for spellchecking,
+     * which is shown in a combobox of this dialog.
+     *
+     * @param dictionary the new language the user selected
+     * @since 4.1
+     */
+    void languageChanged(const QString &language);
+
+  private Q_SLOTS:
+    void slotMisspelling(const QString &word, int start);
+    void slotDone();
+
+    void slotCancel();
+
+    void slotAddWord();
+    void slotReplaceWord();
+    void slotReplaceAll();
+    void slotSkip();
+    void slotSkipAll();
+    void slotSuggest();
+    void slotChangeLanguage(const QString &);
+    void slotAutocorrect();
+
+    void setGuiEnabled(bool b);
+    void setProgressDialogVisible(bool b);
+
+  private:
+    void updateDialog(const QString &word);
+    void fillDictionaryComboBox();
+    void updateDictionaryComboBox();
+    void fillSuggestions(const QStringList &suggs);
+    void initConnections();
+    void initGui();
+    void continueChecking();
+
+  private:
+    class Private;
+    Private *const d;
+    Q_DISABLE_COPY(SpellCheckBar)
+};
+
+#endif
diff --git a/src/spellcheck/spellcheckbar.ui b/src/spellcheck/spellcheckbar.ui
new file mode 100644
index 0000000..7da6202
--- /dev/null
+++ b/src/spellcheck/spellcheckbar.ui
@@ -0,0 +1,251 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>SonnetUi</class>
+ <widget class="QWidget" name="SonnetUi">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>740</width>
+    <height>101</height>
+   </rect>
+  </property>
+  <property name="sizePolicy">
+   <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+    <horstretch>0</horstretch>
+    <verstretch>0</verstretch>
+   </sizepolicy>
+  </property>
+  <layout class="QHBoxLayout" name="horizontalLayout_5">
+   <item>
+    <layout class="QVBoxLayout" name="verticalLayout">
+     <item>
+      <layout class="QHBoxLayout" name="horizontalLayout">
+       <item>
+        <widget class="QLabel" name="textLabel2">
+         <property name="whatsThis">
+          <string><qt><p>This word was considered to be an "unknown word" because it does not match any entry in the dictionary currently in use. It may also be a word in a foreign language.</p>
+<p>If the word is not misspelled, you may add it to the dictionary by clicking <b>Add to Dictionary</b>. If you do not want to add the unknown word to the dictionary, but you want to leave it unchanged, click <b>Ignore</b> or <b>Ignore All</b>.</p>
+<p>However, if the word is misspelled, you can try to find the correct replacement in the list below. If you cannot find a replacement there, you may type it in the text box below, and click <b>Replace</b> or <b>Replace All</b>.</p>
+</qt></string>
+         </property>
+         <property name="text">
+          <string>Unknown word:</string>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QLabel" name="m_unknownWord">
+         <property name="toolTip">
+          <string>Unknown word</string>
+         </property>
+         <property name="whatsThis">
+          <string><qt><p>This word was considered to be an "unknown word" because it does not match any entry in the dictionary currently in use. It may also be a word in a foreign language.</p>
+<p>If the word is not misspelled, you may add it to the dictionary by clicking <b>Add to Dictionary</b>. If you do not want to add the unknown word to the dictionary, but you want to leave it unchanged, click <b>Ignore</b> or <b>Ignore All</b>.</p>
+<p>However, if the word is misspelled, you can try to find the correct replacement in the list below. If you cannot find a replacement there, you may type it in the text box below, and click <b>Replace</b> or <b>Replace All</b>.</p>
+</qt></string>
+         </property>
+         <property name="text">
+          <string><b>misspelled</b></string>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <spacer name="horizontalSpacer_3">
+         <property name="orientation">
+          <enum>Qt::Horizontal</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>40</width>
+           <height>20</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+       <item>
+        <widget class="QPushButton" name="m_addBtn">
+         <property name="whatsThis">
+          <string><qt>
+<p>The unknown word was detected and considered unknown because it is not included in the dictionary.<br>
+Click here if you consider the unknown word not to be misspelled, and you want to avoid wrongly detecting it again in the future. If you want to let it remain as is, but not add it to the dictionary, then click <b>Ignore</b> or <b>Ignore All</b> instead.</p>
+</qt></string>
+         </property>
+         <property name="text">
+          <string><< Add to Dictionary</string>
+         </property>
+        </widget>
+       </item>
+      </layout>
+     </item>
+     <item>
+      <layout class="QHBoxLayout" name="horizontalLayout_2">
+       <item>
+        <widget class="QLabel" name="textLabel4">
+         <property name="whatsThis">
+          <string><qt>
+<p>If the unknown word is misspelled, you should type the correction for your misspelled word here or select it from the list below.</p>
+<p>You can then click <b>Replace</b> if you want to correct only this occurrence of the word or <b>Replace All</b> if you want to correct all occurrences.</p>
+</qt></string>
+         </property>
+         <property name="text">
+          <string>Replace &with:</string>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="KComboBox" name="cmbReplacement">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="editable">
+          <bool>true</bool>
+         </property>
+         <property name="autoCompletion">
+          <bool>true</bool>
+         </property>
+         <property name="trapReturnKey">
+          <bool>true</bool>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QPushButton" name="m_suggestBtn">
+         <property name="text">
+          <string>S&uggest</string>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QPushButton" name="m_replaceBtn">
+         <property name="whatsThis">
+          <string><qt>
+<p>Click here to replace this occurrence of the unknown text with the text in the edit box above (to the left).</p>
+</qt></string>
+         </property>
+         <property name="text">
+          <string>&Replace</string>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QPushButton" name="m_skipBtn">
+         <property name="whatsThis">
+          <string><qt>
+<p>Click here to let this occurrence of the unknown word remain as is.</p>
+<p>This action is useful when the word is a name, an acronym, a foreign word or any other unknown word that you want to use but not add to the dictionary.</p>
+</qt></string>
+         </property>
+         <property name="text">
+          <string>&Ignore</string>
+         </property>
+        </widget>
+       </item>
+      </layout>
+     </item>
+     <item>
+      <layout class="QHBoxLayout" name="horizontalLayout_4">
+       <item>
+        <widget class="QLabel" name="textLabel5">
+         <property name="whatsThis">
+          <string><qt>
+<p>Select the language of the document you are proofing here.</p>
+</qt></string>
+         </property>
+         <property name="text">
+          <string>&Language:</string>
+         </property>
+         <property name="buddy">
+          <cstring>m_language</cstring>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QComboBox" name="m_language">
+         <property name="toolTip">
+          <string>Language Selection</string>
+         </property>
+         <property name="whatsThis">
+          <string><qt>
+<p>Select the language of the document you are proofing here.</p>
+</qt></string>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <spacer name="horizontalSpacer_2">
+         <property name="orientation">
+          <enum>Qt::Horizontal</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>40</width>
+           <height>20</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+       <item>
+        <widget class="QPushButton" name="m_autoCorrect">
+         <property name="whatsThis">
+          <string><qt>
+<p>Click here to let all occurrences of the unknown word remain as they are.</p>
+<p>This action is useful when the word is a name, an acronym, a foreign word or any other unknown word that you want to use but not add to the dictionary.</p>
+</qt></string>
+         </property>
+         <property name="text">
+          <string>Autocorrect</string>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QPushButton" name="m_replaceAllBtn">
+         <property name="whatsThis">
+          <string><qt>
+<p>Click here to replace all occurrences of the unknown text with the text in the edit box above (to the left).</p>
+</qt></string>
+         </property>
+         <property name="text">
+          <string>R&eplace All</string>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QPushButton" name="m_skipAllBtn">
+         <property name="whatsThis">
+          <string><qt>
+<p>Click here to let all occurrences of the unknown word remain as they are.</p>
+<p>This action is useful when the word is a name, an acronym, a foreign word or any other unknown word that you want to use but not add to the dictionary.</p>
+</qt></string>
+         </property>
+         <property name="text">
+          <string>I&gnore All</string>
+         </property>
+        </widget>
+       </item>
+      </layout>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <customwidgets>
+  <customwidget>
+   <class>KComboBox</class>
+   <extends>QComboBox</extends>
+   <header>kcombobox.h</header>
+  </customwidget>
+ </customwidgets>
+ <tabstops>
+  <tabstop>m_addBtn</tabstop>
+  <tabstop>m_suggestBtn</tabstop>
+  <tabstop>m_replaceBtn</tabstop>
+  <tabstop>m_replaceAllBtn</tabstop>
+  <tabstop>m_skipAllBtn</tabstop>
+ </tabstops>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/spellcheck/spellcheckdialog.cpp b/src/spellcheck/spellcheckdialog.cpp
index bf23b9d..531d24f 100644
--- a/src/spellcheck/spellcheckdialog.cpp
+++ b/src/spellcheck/spellcheckdialog.cpp
@@ -30,12 +30,12 @@
 #include "kateglobal.h"
 #include "kateview.h"
 #include "spellcheck/spellcheck.h"
+#include "spellcheck/spellcheckbar.h"
 
 #include <KActionCollection>
 #include <KLocalizedString>
 #include <KStandardAction>
 
-#include <sonnet/dialog.h>
 #include <sonnet/backgroundchecker.h>
 #include <sonnet/speller.h>
 
@@ -114,11 +114,13 @@ void KateSpellCheckDialog::spellcheck(const KTextEditor::Cursor &from, const KTe
     }
 
     if (!m_sonnetDialog) {
-        m_sonnetDialog = new Sonnet::Dialog(m_backgroundChecker, m_view);
+        m_sonnetDialog = new SpellCheckBar(m_backgroundChecker, m_view);
         m_sonnetDialog->showProgressDialog(200);
         m_sonnetDialog->showSpellCheckCompletionMessage();
         m_sonnetDialog->setSpellCheckContinuedAfterReplacement(false);
 
+        m_view->bottomViewBar()->addBarWidget(m_sonnetDialog);
+
         connect(m_sonnetDialog, SIGNAL(done(QString)), this, SLOT(installNextSpellCheckRange()));
 
         connect(m_sonnetDialog, SIGNAL(replace(QString,int,QString)),
@@ -211,7 +213,9 @@ void KateSpellCheckDialog::performSpellCheck(const KTextEditor::Range &range)
     installNextSpellCheckRange();
     // first check if there is really something to spell check
     if (m_currentSpellCheckRange.isValid()) {
+        m_view->bottomViewBar()->showBarWidget(m_sonnetDialog);
         m_sonnetDialog->show();
+        m_sonnetDialog->setFocus();
     }
 }
 
@@ -293,6 +297,7 @@ void KateSpellCheckDialog::installNextSpellCheckRange()
 void KateSpellCheckDialog::cancelClicked()
 {
     m_spellCheckCancelledByUser = true;
+    spellCheckDone();
 }
 
 void KateSpellCheckDialog::spellCheckDone()
diff --git a/src/spellcheck/spellcheckdialog.h b/src/spellcheck/spellcheckdialog.h
index 832afcb..b75d354 100644
--- a/src/spellcheck/spellcheckdialog.h
+++ b/src/spellcheck/spellcheckdialog.h
@@ -34,11 +34,9 @@ namespace KTextEditor { class ViewPrivate; }
 class QAction;
 class KActionCollection;
 
-namespace Sonnet
-{
-class Dialog;
-class BackgroundChecker;
-class Speller;
+namespace Sonnet {
+    class BackgroundChecker;
+    class Speller;
 }
 
 #include "ktexteditor/range.h"
@@ -48,6 +46,8 @@ namespace KTextEditor
 class MovingRange;
 }
 
+class SpellCheckBar;
+
 class KateSpellCheckDialog : public QObject
 {
     Q_OBJECT
@@ -97,7 +97,8 @@ private:
 
     Sonnet::Speller *m_speller;
     Sonnet::BackgroundChecker *m_backgroundChecker;
-    Sonnet::Dialog *m_sonnetDialog;
+
+    SpellCheckBar *m_sonnetDialog;
 
     // define the part of the text that is to be checked
     KTextEditor::Range m_currentSpellCheckRange;


More information about the kde-doc-english mailing list