]> git.lyx.org Git - lyx.git/blob - src/frontends/qt4/GuiCompare.cpp
Use <cstdint> instead of <boost/cstdint.hpp>
[lyx.git] / src / frontends / qt4 / GuiCompare.cpp
1 /**
2  * \file GuiCompare.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Vincent van Ravesteijn
7  *
8  * Full author contact details are available in file CREDITS.
9  */
10
11 #include <config.h>
12
13 #include "GuiCompare.h"
14
15 #include "Buffer.h"
16 #include "BufferView.h"
17 #include "BufferList.h"
18 #include "buffer_funcs.h"
19 #include "Compare.h"
20 #include "FuncRequest.h"
21 #include "GuiView.h"
22 #include "LyXRC.h"
23 #include "qt_helpers.h"
24
25 #include "frontends/alert.h"
26
27 #include "support/debug.h"
28 #include "support/filetools.h"
29 #include "support/FileName.h"
30 #include "support/gettext.h"
31
32 #include <QDialogButtonBox>
33 #include <QThread>
34
35
36 using namespace std;
37 using namespace lyx::support;
38
39 namespace lyx {
40 namespace frontend {
41
42
43 GuiCompare::GuiCompare(GuiView & lv)
44         : GuiDialog(lv, "compare", qt_("Compare LyX files")),
45         compare_(0), dest_buffer_(0), old_buffer_(0), new_buffer_(0)
46 {
47         setupUi(this);
48         setModal(Qt::WindowModal);
49
50         connect(buttonBox, SIGNAL(clicked(QAbstractButton *)),
51                 this, SLOT(slotButtonBox(QAbstractButton *)));
52
53         connect(newFilePB, SIGNAL(clicked()), this, SLOT(selectNewFile()));
54         connect(oldFilePB, SIGNAL(clicked()), this, SLOT(selectOldFile()));
55
56         connect(newFileCB, SIGNAL(currentIndexChanged(int)),
57                 this, SLOT(changeAdaptor()));
58         connect(newFileCB, SIGNAL(editTextChanged(const QString &)),
59                 this, SLOT(changeAdaptor()));
60         connect(oldFileCB, SIGNAL(currentIndexChanged(int)),
61                 this, SLOT(changeAdaptor()));
62         connect(oldFileCB, SIGNAL(editTextChanged(const QString &)),
63                 this, SLOT(changeAdaptor()));
64
65         newSettingsRB->setChecked(true);
66         trackingCB->setChecked(true);
67
68         buttonBox->button(QDialogButtonBox::Ok)->setCursor(Qt::ArrowCursor);
69
70         bc().setPolicy(ButtonPolicy::OkApplyCancelPolicy);
71         bc().setOK(buttonBox->button(QDialogButtonBox::Ok));
72 }
73
74 GuiCompare::~GuiCompare()
75 {
76         if (compare_)
77                 delete compare_;
78 }
79
80 void GuiCompare::closeEvent(QCloseEvent *)
81 {
82         slotCancel();
83 }
84
85
86 void GuiCompare::changeAdaptor()
87 {
88         changed();
89 }
90
91
92 bool GuiCompare::isValid()
93 {
94         bool const valid = !newFileCB->currentText().isEmpty()
95                 && !oldFileCB->currentText().isEmpty();
96         return valid;
97 }
98
99
100 void GuiCompare::updateContents()
101 {
102         if (compare_ && compare_->isRunning())
103                 return;
104
105         QString restore_filename1 = newFileCB->currentText();
106         QString restore_filename2 = oldFileCB->currentText();
107         newFileCB->clear();
108         oldFileCB->clear();
109         progressBar->setValue(0);
110         statusBar->clearMessage();
111         BufferList::iterator it = theBufferList().begin();
112         BufferList::iterator const end = theBufferList().end();
113         for (; it != end; ++it) {
114                 QString filename = toqstr((*it)->absFileName());
115                 newFileCB->addItem(filename);
116                 oldFileCB->addItem(filename);
117         }
118         if (!restore_filename1.isEmpty())
119                 newFileCB->setEditText(restore_filename1);
120         else if (lyxview().documentBufferView())
121                 newFileCB->setEditText(toqstr(buffer().absFileName()));
122
123         if (!restore_filename2.isEmpty())
124                 oldFileCB->setEditText(restore_filename2);
125         else
126                 oldFileCB->clearEditText();
127
128         if (isValid()) {
129                 bc().setValid(isValid());
130                 bc().apply();
131         }
132 }
133
134
135 void GuiCompare::selectNewFile()
136 {
137         QString name = browse(newFileCB->currentText());
138         if (!name.isEmpty())
139                 newFileCB->setEditText(name);
140         changed();
141 }
142
143
144 void GuiCompare::selectOldFile()
145 {
146         QString name = browse(oldFileCB->currentText());
147         if (!name.isEmpty())
148                 oldFileCB->setEditText(name);
149         changed();
150 }
151
152
153 QString GuiCompare::browse(QString const & in_name) const
154 {
155         QString const title = qt_("Select document");
156
157         QStringList const & filters = fileFilters(qt_("LyX Documents (*.lyx)"));
158
159         QString filename;
160         if (lyxview().documentBufferView()) {
161                 QString path = bufferFilePath();
162                 filename = browseRelToParent(in_name, path, title, filters, false,
163                         qt_("D&ocuments"), toqstr(lyxrc.document_path));
164         } else {
165                 QString path = toqstr(lyxrc.document_path);
166                 QString rel_filename = browseRelToParent(in_name, path, title, filters, false,
167                         qt_("D&ocuments"), toqstr(lyxrc.document_path));
168                 filename = makeAbsPath(rel_filename, path);
169         }
170         return filename;
171 }
172
173
174 void GuiCompare::enableControls(bool enable)
175 {
176         // Set the hourglass cursor for the dialog, but
177         // never for the cancel button.
178         setCursor(enable ? Qt::ArrowCursor : Qt::WaitCursor);
179
180         newFileLA->setEnabled(enable);
181         newFilePB->setEnabled(enable);
182         newFileCB->setEnabled(enable);
183         oldFileLA->setEnabled(enable);
184         oldFilePB->setEnabled(enable);
185         oldFileCB->setEnabled(enable);
186         buttonBox->button(QDialogButtonBox::Ok)->setEnabled(enable);
187         groupBox->setEnabled(enable);
188         progressBar->setEnabled(!enable);
189
190         if (enable)
191                 buttonBox->button(QDialogButtonBox::Cancel)->setText(qt_("Close"));
192         else
193                 buttonBox->button(QDialogButtonBox::Cancel)->setText(qt_("Cancel"));
194 }
195
196
197 void GuiCompare::error()
198 {
199         Alert::error(_("Error"), _("Error while comparing documents."));
200         finished(true);
201 }
202
203 void GuiCompare::finished(bool aborted)
204 {
205         enableControls(true);
206
207         if (compare_) {
208                 delete compare_;
209                 compare_ = 0;
210         }
211
212         if (aborted) {
213                 if (dest_buffer_) {
214                         dest_buffer_->markClean();
215                         theBufferList().release(dest_buffer_);
216                 }
217                 progressBar->setValue(0);
218                 statusBar->showMessage(qt_("Aborted"), 5000);
219         } else {
220                 hideView();
221                 bc().ok();
222                 if (dest_buffer_) {
223                         dispatch(FuncRequest(LFUN_BUFFER_SWITCH,
224                                 dest_buffer_->absFileName()));
225                         if (trackingCB->isChecked()) {
226                                 dispatch(FuncRequest(LFUN_CHANGES_OUTPUT));
227                                 dispatch(FuncRequest(LFUN_CHANGES_TRACK));
228                         }
229                 }
230                 statusBar->showMessage(qt_("Finished"), 5000);
231         }
232 }
233
234
235 void GuiCompare::progress(int val)
236 {
237         progressBar->setValue(progressBar->value() + val);
238 }
239
240
241 void GuiCompare::progressMax(int max) const
242 {
243         progressBar->setMaximum(max);
244 }
245
246
247 void GuiCompare::setStatusMessage(QString msg)
248 {
249         statusBar->showMessage(msg);
250 }
251
252
253 void GuiCompare::slotOK()
254 {
255         enableControls(false);
256         if (!run())
257                 error();
258 }
259
260
261 void GuiCompare::slotCancel()
262 {
263         if (compare_ && compare_->isRunning()) {
264                 statusBar->showMessage(qt_("Aborting process..."));
265                 compare_->abort();
266         } else {
267                 GuiDialog::slotClose();
268                 progressBar->setValue(0);
269                 statusBar->clearMessage();
270         }
271 }
272
273
274 void GuiCompare::slotButtonBox(QAbstractButton * button)
275 {
276         switch (buttonBox->standardButton(button)) {
277         case QDialogButtonBox::Ok:
278                 slotOK();
279                 break;
280         case QDialogButtonBox::Cancel:
281                 slotCancel();
282                 break;
283         default:
284                 break;
285         }
286 }
287
288
289 Buffer const * GuiCompare::bufferFromFileName(string const & file) const
290 {
291         FileName fname;
292         if (FileName::isAbsolute(file))
293                 fname.set(file);
294         else if (lyxview().documentBufferView())
295                 fname = support::makeAbsPath(file, fromqstr(bufferFilePath()));
296
297         if (fname.empty()
298                         || (!fname.exists() && !theBufferList().getBuffer(fname))) {
299                 LYXERR0( "Unable to read: " << file);
300                 return 0;
301         }
302         return loadIfNeeded(fname);
303 }
304
305
306 int GuiCompare::run()
307 {
308         progressBar->setValue(0);
309
310         new_buffer_ = bufferFromFileName(fromqstr(newFileCB->currentText()));
311         old_buffer_ = bufferFromFileName(fromqstr(oldFileCB->currentText()));
312
313         // new buffer that will carry the output
314         FileName initpath(lyxrc.document_path);
315         dest_buffer_ = newUnnamedFile(initpath, to_utf8(_("differences")));
316
317         if (!new_buffer_ || !old_buffer_ || !dest_buffer_)
318                 return 0;
319
320         dest_buffer_->changed(true);
321         dest_buffer_->markDirty();
322
323         // get the options from the dialog
324         CompareOptions options;
325         options.settings_from_new = newSettingsRB->isChecked();
326
327         // init the compare object and start it
328         compare_ = new Compare(new_buffer_, old_buffer_, dest_buffer_, options);
329         connect(compare_, SIGNAL(error()), this, SLOT(error()));
330         connect(compare_, SIGNAL(finished(bool)), this, SLOT(finished(bool)));
331         connect(compare_, SIGNAL(progress(int)), this, SLOT(progress(int)));
332         connect(compare_, SIGNAL(progressMax(int)), this, SLOT(progressMax(int)));
333         connect(compare_, SIGNAL(statusMessage(QString)),
334                 this, SLOT(setStatusMessage(QString)));
335         compare_->start(QThread::LowPriority);
336         return 1;
337 }
338
339 bool GuiCompare::initialiseParams(std::string const &par)
340 {
341         //just for the sake of parsing arguments
342         FuncRequest cmd(LFUN_UNKNOWN_ACTION, par);
343         if (cmd.getArg(0) == "run") {
344                 oldFileCB->setEditText(toqstr(cmd.getArg(1)));
345                 newFileCB->setEditText(toqstr(cmd.getArg(2)));
346                 slotOK();
347         }
348
349         progressBar->setValue(0);
350         progressBar->setEnabled(false);
351         progressBar->setMaximum(1);
352
353         return true;
354 }
355
356 Dialog * createGuiCompare(GuiView & lv) { return new GuiCompare(lv); }
357
358
359 } // namespace frontend
360 } // namespace lyx
361
362
363 #include "moc_GuiCompare.cpp"