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