1 /* This file is part of the KDE project
2 Copyright 2008 Stefan Nikolaus <stefan.nikolaus@kdemail.net>
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 Boston, MA 02110-1301, USA.
18 */
19
20 #include "SpellCheckCommand.h"
21
22 #include "Cell.h"
23 #include "CellStorage.h"
24 #include "Map.h"
25 #include "Sheet.h"
26 #include "Region.h"
27 #include "ValueStorage.h"
28
29 #include "commands/DataManipulators.h"
30
31 #include <KoCanvasBase.h>
32
33 #include <kmessagebox.h>
34 #include <sonnet/dialog.h>
35 #include <sonnet/speller.h>
36
37 using namespace Calligra::Sheets;
38
39 class SpellCheckCommand::Private
40 {
41 public:
42 KoCanvasBase* canvasBase;
43 int index;
44 Region region;
45 Cell currentCell;
46 Sheet* currentSheet;
47 ValueStorage storage;
48 Sonnet::Speller speller;
49 Sonnet::Dialog* dialog;
50 KUndo2Command* command;
51 };
52
SpellCheckCommand(const Region & region,KoCanvasBase * canvasBase)53 SpellCheckCommand::SpellCheckCommand(const Region ®ion, KoCanvasBase* canvasBase)
54 : BackgroundChecker(canvasBase->canvasWidget())
55 , d(new Private)
56 {
57 d->canvasBase = canvasBase;
58 d->index = 0;
59 d->region = region;
60 d->currentSheet = region.firstSheet();
61 if (region.isSingular()) {
62 // take the whole sheet
63 d->storage = *d->currentSheet->valueStorage();
64 } else {
65 // only take the selection
66 d->storage = d->currentSheet->valueStorage()->subStorage(region);
67 }
68 setSpeller(d->speller);
69 d->dialog = new Sonnet::Dialog(this, canvasBase->canvasWidget());
70 d->command = 0;
71
72 connect(this, SIGNAL(done()),
73 this, SLOT(finishCommand()));
74 connect(d->dialog, SIGNAL(replace(QString,int,QString)),
75 this, SLOT(replace(QString,int,QString)));
76 }
77
~SpellCheckCommand()78 SpellCheckCommand::~SpellCheckCommand()
79 {
80 delete d->dialog;
81 delete d;
82 }
83
fetchMoreText()84 QString SpellCheckCommand::fetchMoreText()
85 {
86 QString text;
87 // Take the next string value.
88 while (d->index < d->storage.count() && text.isEmpty()) {
89 const Value value = d->storage.data(d->index);
90 if (value.isString()) {
91 text = value.asString();
92 d->currentCell = Cell(d->currentSheet, d->storage.col(d->index), d->storage.row(d->index));
93 }
94 d->index++;
95 }
96 if (text.isEmpty() && d->region.isSingular()) {
97 if (d->currentSheet->map()->count() == 1) {
98 // Nothing more to do, if there's only one sheet.
99 return QString();
100 }
101 // Ask whether we should continue on the next sheet.
102 const QString question = i18n("Do you want to check the spelling in the next sheet?");
103 if (KMessageBox::questionYesNo(d->canvasBase->canvasWidget(), question) == KMessageBox::Yes) {
104 const Map* map = d->currentSheet->map();
105 if (d->currentSheet == map->sheet(map->count() - 1)) {
106 // Switch from the last to the first sheet.
107 d->currentSheet = map->sheet(0);
108 } else {
109 // Switch to the next sheet.
110 d->currentSheet = map->nextSheet(d->currentSheet);
111 }
112 if (d->currentSheet == d->region.firstSheet()) {
113 // Stop, if reached the starting sheet.
114 return QString();
115 }
116 // Set the storage and reset its index.
117 d->index = 0;
118 d->storage = *d->currentSheet->valueStorage();
119 }
120 }
121 return text;
122 }
123
finishedCurrentFeed()124 void SpellCheckCommand::finishedCurrentFeed()
125 {
126 if (d->dialog->originalBuffer() == d->dialog->buffer()) {
127 return;
128 }
129 // TODO Stefan: KUndo2Command-based undo recording for CellStorage.
130 if (!d->command) {
131 d->command = new KUndo2Command(kundo2_i18n("Correct Misspelled Words"));
132 }
133 DataManipulator* command = new DataManipulator(d->command);
134 command->setSheet(d->currentSheet);
135 command->setValue(Value(d->dialog->buffer()));
136 command->setParsing(false);
137 command->add(QPoint(d->currentCell.column(), d->currentCell.row()));
138 command->setRegisterUndo(false);
139 }
140
finishCommand()141 void SpellCheckCommand::finishCommand()
142 {
143 if (d->command) {
144 d->canvasBase->addCommand(d->command);
145 }
146 deleteLater();
147 // TODO Stefan: Save the ignored words in document.
148 }
149