File indexing completed on 2024-05-12 16:35:13

0001 /* This file is part of the KDE project
0002    Copyright 2008 Stefan Nikolaus <stefan.nikolaus@kdemail.net>
0003 
0004    This library is free software; you can redistribute it and/or
0005    modify it under the terms of the GNU Library General Public
0006    License as published by the Free Software Foundation; either
0007    version 2 of the License, or (at your option) any later version.
0008 
0009    This library 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 GNU
0012    Library General Public License for more details.
0013 
0014    You should have received a copy of the GNU Library General Public License
0015    along with this library; see the file COPYING.LIB.  If not, write to
0016    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0017    Boston, MA 02110-1301, USA.
0018 */
0019 
0020 #include "SpellCheckCommand.h"
0021 
0022 #include "Cell.h"
0023 #include "CellStorage.h"
0024 #include "Map.h"
0025 #include "Sheet.h"
0026 #include "Region.h"
0027 #include "ValueStorage.h"
0028 
0029 #include "commands/DataManipulators.h"
0030 
0031 #include <KoCanvasBase.h>
0032 
0033 #include <kmessagebox.h>
0034 #include <sonnet/dialog.h>
0035 #include <sonnet/speller.h>
0036 
0037 using namespace Calligra::Sheets;
0038 
0039 class SpellCheckCommand::Private
0040 {
0041 public:
0042     KoCanvasBase* canvasBase;
0043     int index;
0044     Region region;
0045     Cell currentCell;
0046     Sheet* currentSheet;
0047     ValueStorage storage;
0048     Sonnet::Speller speller;
0049     Sonnet::Dialog* dialog;
0050     KUndo2Command* command;
0051 };
0052 
0053 SpellCheckCommand::SpellCheckCommand(const Region &region, KoCanvasBase* canvasBase)
0054         : BackgroundChecker(canvasBase->canvasWidget())
0055         , d(new Private)
0056 {
0057     d->canvasBase = canvasBase;
0058     d->index = 0;
0059     d->region = region;
0060     d->currentSheet = region.firstSheet();
0061     if (region.isSingular()) {
0062         // take the whole sheet
0063         d->storage = *d->currentSheet->valueStorage();
0064     } else {
0065         // only take the selection
0066         d->storage = d->currentSheet->valueStorage()->subStorage(region);
0067     }
0068     setSpeller(d->speller);
0069     d->dialog = new Sonnet::Dialog(this, canvasBase->canvasWidget());
0070     d->command = 0;
0071 
0072     connect(this, SIGNAL(done()),
0073             this, SLOT(finishCommand()));
0074     connect(d->dialog, SIGNAL(replace(QString,int,QString)),
0075             this, SLOT(replace(QString,int,QString)));
0076 }
0077 
0078 SpellCheckCommand::~SpellCheckCommand()
0079 {
0080     delete d->dialog;
0081     delete d;
0082 }
0083 
0084 QString SpellCheckCommand::fetchMoreText()
0085 {
0086     QString text;
0087     // Take the next string value.
0088     while (d->index < d->storage.count() && text.isEmpty()) {
0089         const Value value = d->storage.data(d->index);
0090         if (value.isString()) {
0091             text = value.asString();
0092             d->currentCell = Cell(d->currentSheet, d->storage.col(d->index), d->storage.row(d->index));
0093         }
0094         d->index++;
0095     }
0096     if (text.isEmpty() && d->region.isSingular()) {
0097         if (d->currentSheet->map()->count() == 1) {
0098             // Nothing more to do, if there's only one sheet.
0099             return QString();
0100         }
0101         // Ask whether we should continue on the next sheet.
0102         const QString question = i18n("Do you want to check the spelling in the next sheet?");
0103         if (KMessageBox::questionYesNo(d->canvasBase->canvasWidget(), question) == KMessageBox::Yes) {
0104             const Map* map = d->currentSheet->map();
0105             if (d->currentSheet == map->sheet(map->count() - 1)) {
0106                 // Switch from the last to the first sheet.
0107                 d->currentSheet = map->sheet(0);
0108             } else {
0109                 // Switch to the next sheet.
0110                 d->currentSheet = map->nextSheet(d->currentSheet);
0111             }
0112             if (d->currentSheet == d->region.firstSheet()) {
0113                 // Stop, if reached the starting sheet.
0114                 return QString();
0115             }
0116             // Set the storage and reset its index.
0117             d->index = 0;
0118             d->storage = *d->currentSheet->valueStorage();
0119         }
0120     }
0121     return text;
0122 }
0123 
0124 void SpellCheckCommand::finishedCurrentFeed()
0125 {
0126     if (d->dialog->originalBuffer() == d->dialog->buffer()) {
0127         return;
0128     }
0129     // TODO Stefan: KUndo2Command-based undo recording for CellStorage.
0130     if (!d->command) {
0131         d->command = new KUndo2Command(kundo2_i18n("Correct Misspelled Words"));
0132     }
0133     DataManipulator* command = new DataManipulator(d->command);
0134     command->setSheet(d->currentSheet);
0135     command->setValue(Value(d->dialog->buffer()));
0136     command->setParsing(false);
0137     command->add(QPoint(d->currentCell.column(), d->currentCell.row()));
0138     command->setRegisterUndo(false);
0139 }
0140 
0141 void SpellCheckCommand::finishCommand()
0142 {
0143     if (d->command) {
0144         d->canvasBase->addCommand(d->command);
0145     }
0146     deleteLater();
0147     // TODO Stefan: Save the ignored words in document.
0148 }