]> git.lyx.org Git - lyx.git/blob - src/frontends/qt4/FindAndReplace.cpp
Introduce splitindex support. File format change.
[lyx.git] / src / frontends / qt4 / FindAndReplace.cpp
1 /**
2  * \file FindAndReplace.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Tommaso Cucinotta
7  *
8  * Full author contact details are available in file CREDITS.
9  */
10
11 #include <config.h>
12
13 #include "FindAndReplace.h"
14
15 #include "GuiApplication.h"
16 #include "qt_helpers.h"
17 #include "GuiView.h"
18 #include "GuiWorkArea.h"
19
20 #include "buffer_funcs.h"
21 #include "BufferParams.h"
22 #include "Cursor.h"
23 #include "FuncRequest.h"
24 #include "lyxfind.h"
25 #include "OutputParams.h"
26 #include "output_latex.h"
27 #include "TexRow.h"
28
29 #include "support/convert.h"
30 #include "support/debug.h"
31 #include "support/FileName.h"
32 #include "support/gettext.h"
33 #include "support/lassert.h"
34
35 #include <QCloseEvent>
36 #include <QLineEdit>
37
38 #include <iostream>
39
40 using namespace std;
41 using namespace lyx::support;
42
43 namespace lyx {
44 namespace frontend {
45
46
47 FindAndReplaceWidget::FindAndReplaceWidget(GuiView & view)
48         :       view_(view)
49 {
50         setupUi(this);
51         find_work_area_->setGuiView(view_);
52         find_work_area_->init();
53         setFocusProxy(find_work_area_);
54         replace_work_area_->setGuiView(view_);
55         replace_work_area_->init();
56         // We don't want two cursors blinking.
57         replace_work_area_->stopBlinkingCursor();
58 }
59
60
61 bool FindAndReplaceWidget::eventFilter(QObject *obj, QEvent *event)
62 {
63         LYXERR(Debug::DEBUG, "FindAndReplace::eventFilter()" << std::endl);
64         if (obj == find_work_area_ && event->type() == QEvent::KeyPress) {
65                 QKeyEvent *e = static_cast<QKeyEvent *> (event);
66                 if (e->key() == Qt::Key_Escape && e->modifiers() == Qt::NoModifier) {
67                         on_closePB_clicked();
68                         return true;
69                 } else if (e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return) {
70                         if (e->modifiers() == Qt::ShiftModifier) {
71                                 on_findPrevPB_clicked();
72                                 return true;
73                         } else if (e->modifiers() == Qt::NoModifier) {
74                                 on_findNextPB_clicked();
75                                 return true;
76                         }
77                 }
78         }
79         // standard event processing
80         return QWidget::eventFilter(obj, event);
81 }
82
83 static docstring buffer_to_latex(Buffer & buffer) {
84         OutputParams runparams(&buffer.params().encoding());
85         odocstringstream os;
86         runparams.nice = true;
87         runparams.flavor = OutputParams::LATEX;
88         runparams.linelen = 80; //lyxrc.plaintext_linelen;
89         // No side effect of file copying and image conversion
90         runparams.dryrun = true;
91         buffer.texrow().reset();
92         ParagraphList::const_iterator pit = buffer.paragraphs().begin();
93         ParagraphList::const_iterator const end = buffer.paragraphs().end();
94         for (; pit != end; ++pit) {
95                 TeXOnePar(buffer, buffer.text(), pit, os, buffer.texrow(), runparams);
96                 LYXERR(Debug::DEBUG, "searchString up to here: " << os.str());
97         }
98         return os.str();
99 }
100
101 void FindAndReplaceWidget::findAndReplace(
102         bool casesensitive, bool matchword, bool backwards,
103         bool expandmacros, bool ignoreformat, bool replace)
104 {
105         Buffer & buffer = find_work_area_->bufferView().buffer();
106         docstring searchString;
107         if (!ignoreformat) {
108                 searchString = buffer_to_latex(buffer);
109         } else {
110                 ParIterator it = buffer.par_iterator_begin();
111                 ParIterator end = buffer.par_iterator_end();
112                 OutputParams runparams(&buffer.params().encoding());
113                 odocstringstream os;
114                 runparams.nice = true;
115                 runparams.flavor = OutputParams::LATEX;
116                 runparams.linelen = 100000; //lyxrc.plaintext_linelen;
117                 runparams.dryrun = true;
118                 for (; it != end; ++it) {
119                         LYXERR(Debug::DEBUG, "Adding to search string: '" << it->asString(false) << "'");
120                         searchString += it->stringify(pos_type(0), it->size(), AS_STR_INSETS, runparams);
121                 }
122         }
123 //      lyxerr << "Searching for '" << to_utf8(searchString) << "'" << std::endl;
124         if (to_utf8(searchString).empty()) {
125                 buffer.message(_("Nothing to search"));
126                 return;
127         }
128         bool const regexp = to_utf8(searchString).find("\\regexp") != std::string::npos;
129         docstring replaceString;
130         if (replace) {
131                 Buffer & replace_buffer = replace_work_area_->bufferView().buffer();
132                 replaceString = buffer_to_latex(replace_buffer);
133         } else {
134                 replaceString = from_utf8(LYX_FR_NULL_STRING);
135         }
136         FindAndReplaceOptions opt(searchString, casesensitive, matchword, ! backwards,
137                 expandmacros, ignoreformat, regexp, replaceString);
138         LYXERR(Debug::DEBUG, "Dispatching LFUN_WORD_FINDADV" << std::endl);
139         std::ostringstream oss;
140         oss << opt;
141         LYXERR(Debug::DEBUG, "Dispatching LFUN_WORD_FINDADV" << std::endl);
142         dispatch(FuncRequest(LFUN_WORD_FINDADV, from_utf8(oss.str())));
143
144         //      findAdv(&theApp()->currentView()->currentWorkArea()->bufferView(),
145         //                      searchString, len, casesensitive, matchword, ! backwards, expandmacros);
146 }
147
148
149 void FindAndReplaceWidget::findAndReplace(bool backwards, bool replace)
150 {
151         // FIXME: create a Dialog::returnFocus() or something instead of this:
152         view_.setCurrentWorkArea(view_.currentMainWorkArea());
153         // FIXME: This should be an LFUN.
154         findAndReplace(caseCB->isChecked(),
155                 wordsCB->isChecked(),
156                 backwards,
157                 expandMacrosCB->isChecked(),
158                 ignoreFormatCB->isChecked(),
159                 replace);
160         view_.currentMainWorkArea()->redraw();
161         find_work_area_->setFocus();
162 }
163
164
165 void FindAndReplaceWidget::on_regexpInsertCombo_currentIndexChanged(int index)
166 {
167         static char const * regexps[] = {
168                 ".*", ".+", "[a-z]+", "[0-9]+"
169         };
170         //lyxerr << "Index: " << index << std::endl;
171         if (index >= 1 && index < 1 + int(sizeof(regexps)/sizeof(regexps[0]))) {
172                 find_work_area_->setFocus();
173                 Cursor & cur = find_work_area_->bufferView().cursor();
174                 if (! cur.inRegexped())
175                         dispatch(FuncRequest(LFUN_REGEXP_MODE));
176                 dispatch(FuncRequest(LFUN_SELF_INSERT, regexps[index - 1]));
177                 regexpInsertCombo->setCurrentIndex(0);
178         }
179 }
180
181
182 void FindAndReplaceWidget::on_closePB_clicked()
183 {
184         dispatch(FuncRequest(LFUN_DIALOG_TOGGLE, "findreplaceadv"));
185 }
186
187
188 void FindAndReplaceWidget::on_findNextPB_clicked() {
189         findAndReplace(false, false);
190 }
191
192
193 void FindAndReplaceWidget::on_findPrevPB_clicked() {
194         findAndReplace(true, false);
195 }
196
197
198 void FindAndReplaceWidget::on_replaceNextPB_clicked()
199 {
200         findAndReplace(false, true);
201 }
202
203
204 void FindAndReplaceWidget::on_replacePrevPB_clicked()
205 {
206         findAndReplace(true, true);
207 }
208
209
210 void FindAndReplaceWidget::on_replaceallPB_clicked()
211 {
212 }
213
214
215 void FindAndReplaceWidget::showEvent(QShowEvent * /* ev */)
216 {
217         replace_work_area_->setEnabled(true);
218         replace_work_area_->redraw();
219         find_work_area_->setFocus();
220         dispatch(FuncRequest(LFUN_BUFFER_BEGIN));
221         dispatch(FuncRequest(LFUN_BUFFER_END_SELECT));
222         find_work_area_->redraw();
223         find_work_area_->installEventFilter(this);
224 }
225
226
227 void FindAndReplaceWidget::hideEvent(QHideEvent *ev)
228 {
229         find_work_area_->removeEventFilter(this);
230         this->QWidget::hideEvent(ev);
231 }
232
233
234 bool FindAndReplaceWidget::initialiseParams(std::string const & /* params */)
235 {
236         find_work_area_->redraw();
237         replace_work_area_->setEnabled(true);
238         replace_work_area_->redraw();
239         find_work_area_->setFocus();
240         dispatch(FuncRequest(LFUN_BUFFER_BEGIN));
241         dispatch(FuncRequest(LFUN_BUFFER_END_SELECT));
242         return true;
243 }
244
245
246 FindAndReplace::FindAndReplace(GuiView & parent,
247                 Qt::DockWidgetArea area, Qt::WindowFlags flags)
248         : DockView(parent, "Find LyX", qt_("Find LyX Dialog"), area, flags)
249 {
250         widget_ = new FindAndReplaceWidget(parent);
251         setWidget(widget_);
252         setFocusProxy(widget_);
253 }
254
255
256 FindAndReplace::~FindAndReplace()
257 {
258         setFocusProxy(0);
259         delete widget_;
260 }
261
262
263 bool FindAndReplace::initialiseParams(std::string const & params)
264 {
265         return widget_->initialiseParams(params);
266 }
267
268
269 Dialog * createGuiSearchAdv(GuiView & lv)
270 {
271         return new FindAndReplace(lv, Qt::RightDockWidgetArea);
272 }
273
274
275 } // namespace frontend
276 } // namespace lyx
277
278
279 #include "moc_FindAndReplace.cpp"