3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
6 * \author Vincent van Ravesteijn
8 * Full author contact details are available in file CREDITS.
13 #include "GuiCompare.h"
16 #include "BufferView.h"
17 #include "BufferList.h"
18 #include "buffer_funcs.h"
20 #include "FuncRequest.h"
23 #include "qt_helpers.h"
25 #include "frontends/alert.h"
27 #include "support/debug.h"
28 #include "support/filetools.h"
29 #include "support/FileName.h"
30 #include "support/gettext.h"
32 #include <QDialogButtonBox>
37 using namespace lyx::support;
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)
48 setModal(Qt::WindowModal);
50 connect(buttonBox, SIGNAL(clicked(QAbstractButton *)),
51 this, SLOT(slotButtonBox(QAbstractButton *)));
53 connect(newFilePB, SIGNAL(clicked()), this, SLOT(selectNewFile()));
54 connect(oldFilePB, SIGNAL(clicked()), this, SLOT(selectOldFile()));
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()));
65 newSettingsRB->setChecked(true);
66 trackingCB->setChecked(true);
68 buttonBox->button(QDialogButtonBox::Ok)->setCursor(Qt::ArrowCursor);
70 bc().setPolicy(ButtonPolicy::OkApplyCancelPolicy);
71 bc().setOK(buttonBox->button(QDialogButtonBox::Ok));
74 GuiCompare::~GuiCompare()
80 void GuiCompare::closeEvent(QCloseEvent *)
86 void GuiCompare::changeAdaptor()
92 bool GuiCompare::isValid()
94 bool const valid = !newFileCB->currentText().isEmpty()
95 && !oldFileCB->currentText().isEmpty();
100 void GuiCompare::updateContents()
102 if (compare_ && compare_->isRunning())
105 QString restore_filename1 = newFileCB->currentText();
106 QString restore_filename2 = oldFileCB->currentText();
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);
118 if (!restore_filename1.isEmpty())
119 newFileCB->setEditText(restore_filename1);
120 else if (lyxview().documentBufferView())
121 newFileCB->setEditText(toqstr(buffer().absFileName()));
123 if (!restore_filename2.isEmpty())
124 oldFileCB->setEditText(restore_filename2);
126 oldFileCB->clearEditText();
129 bc().setValid(isValid());
135 void GuiCompare::selectNewFile()
137 QString name = browse(newFileCB->currentText());
139 newFileCB->setEditText(name);
144 void GuiCompare::selectOldFile()
146 QString name = browse(oldFileCB->currentText());
148 oldFileCB->setEditText(name);
153 QString GuiCompare::browse(QString const & in_name) const
155 QString const title = qt_("Select document");
157 QStringList const & filters = fileFilters(qt_("LyX Documents (*.lyx)"));
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));
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);
174 void GuiCompare::enableControls(bool enable)
176 // Set the hourglass cursor for the dialog, but
177 // never for the cancel button.
178 setCursor(enable ? Qt::ArrowCursor : Qt::WaitCursor);
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);
191 buttonBox->button(QDialogButtonBox::Cancel)->setText(qt_("Close"));
193 buttonBox->button(QDialogButtonBox::Cancel)->setText(qt_("Cancel"));
197 void GuiCompare::error()
199 Alert::error(_("Error"), _("Error while comparing documents."));
203 void GuiCompare::finished(bool aborted)
205 enableControls(true);
214 dest_buffer_->markClean();
215 theBufferList().release(dest_buffer_);
217 progressBar->setValue(0);
218 statusBar->showMessage(qt_("Aborted"), 5000);
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));
230 statusBar->showMessage(qt_("Finished"), 5000);
235 void GuiCompare::progress(int val)
237 progressBar->setValue(progressBar->value() + val);
241 void GuiCompare::progressMax(int max) const
243 progressBar->setMaximum(max);
247 void GuiCompare::setStatusMessage(QString const & msg)
249 statusBar->showMessage(msg);
253 void GuiCompare::slotOK()
255 enableControls(false);
261 void GuiCompare::slotCancel()
263 if (compare_ && compare_->isRunning()) {
264 statusBar->showMessage(qt_("Aborting process..."));
267 GuiDialog::slotClose();
268 progressBar->setValue(0);
269 statusBar->clearMessage();
274 void GuiCompare::slotButtonBox(QAbstractButton * button)
276 switch (buttonBox->standardButton(button)) {
277 case QDialogButtonBox::Ok:
280 case QDialogButtonBox::Cancel:
289 Buffer const * GuiCompare::bufferFromFileName(string const & file) const
292 if (FileName::isAbsolute(file))
294 else if (lyxview().documentBufferView())
295 fname = support::makeAbsPath(file, fromqstr(bufferFilePath()));
298 || (!fname.exists() && !theBufferList().getBuffer(fname))) {
299 LYXERR0( "Unable to read: " << file);
302 return loadIfNeeded(fname);
306 int GuiCompare::run(bool blocking_mode)
308 progressBar->setValue(0);
310 new_buffer_ = bufferFromFileName(fromqstr(newFileCB->currentText()));
311 old_buffer_ = bufferFromFileName(fromqstr(oldFileCB->currentText()));
313 // new buffer that will carry the output
314 FileName initpath(lyxrc.document_path);
315 dest_buffer_ = newUnnamedFile(initpath, to_utf8(_("differences")));
317 if (!new_buffer_ || !old_buffer_ || !dest_buffer_)
320 dest_buffer_->changed(true);
321 dest_buffer_->markDirty();
323 // get the options from the dialog
324 CompareOptions options;
325 options.settings_from_new = newSettingsRB->isChecked();
327 // init the compare object and start it
329 compare_ = new Compare(new_buffer_, old_buffer_, dest_buffer_, options);
331 connect(compare_, SIGNAL(error()), this, SLOT(error()));
332 // Only connect the finished() method to the signal if we're *not* in blocking_mode
333 // (i.e. we want to make it possible for caller to block for the results)
334 if (! blocking_mode) {
335 connect(compare_, SIGNAL(finished(bool)), this, SLOT(finished(bool)));
337 connect(compare_, SIGNAL(progress(int)), this, SLOT(progress(int)));
338 connect(compare_, SIGNAL(progressMax(int)), this, SLOT(progressMax(int)));
339 connect(compare_, SIGNAL(statusMessage(QString)),
340 this, SLOT(setStatusMessage(QString)));
341 compare_->start(QThread::LowPriority);
346 bool GuiCompare::initialiseParams(std::string const &par)
348 //just for the sake of parsing arguments
349 FuncRequest cmd(LFUN_UNKNOWN_ACTION, par);
350 if (cmd.getArg(0) == "run" || cmd.getArg(0) == "run-blocking") {
351 oldFileCB->setEditText(toqstr(cmd.getArg(1)));
352 newFileCB->setEditText(toqstr(cmd.getArg(2)));
354 if (cmd.getArg(0) == "run" ) {
355 // Run asynchronously
360 enableControls(false);
367 // Wait for the Compare function to process in a thread (2 minute timeout)
368 compare_->wait(120000);
374 progressBar->setValue(0);
375 progressBar->setEnabled(false);
376 progressBar->setMaximum(1);
381 Dialog * createGuiCompare(GuiView & lv) { return new GuiCompare(lv); }
384 } // namespace frontend
388 #include "moc_GuiCompare.cpp"