2 * \file qt/GuiAlert.cpp
3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
7 * \author Jürgen Spitzmüller
8 * \author Abdelrazak Younes
10 * Full author contact details are available in file CREDITS.
16 #include "InGuiThread.h"
18 #include "frontends/Application.h"
20 #include "qt_helpers.h"
21 #include "LyX.h" // for lyx::use_gui
23 #include "support/gettext.h"
24 #include "support/debug.h"
25 #include "support/docstring.h"
26 #include "support/lstrings.h"
27 #include "support/lassert.h"
28 #include "support/ProgressInterface.h"
30 #include <QApplication>
32 #include <QMessageBox>
34 #include <QInputDialog>
35 #include <QPushButton>
42 // sync with GuiView.cpp
43 #define EXPORT_in_THREAD 1
47 using namespace lyx::support;
53 void noAppDialog(QString const & title, QString const & msg, QMessageBox::Icon mode)
56 const char *argv[] = { "lyx", 0 };
58 QApplication app(argc, (char**)argv);
61 case QMessageBox::Information: QMessageBox::information(0, title, msg); break;
62 case QMessageBox::Warning: QMessageBox::warning(0, title, msg); break;
63 case QMessageBox::Critical: QMessageBox::critical(0, title, msg); break;
72 docstring toPlainText(docstring const & msg)
74 return qstring_to_ucs4(qtHtmlToPlainText(toqstr(msg)));
78 int doPrompt(docstring const & title0, docstring const & question,
79 int default_button, int cancel_button,
80 docstring const & b1, docstring const & b2,
81 docstring const & b3, docstring const & b4)
83 //lyxerr << "PROMPT" << title0 << "FOCUS: " << qApp->focusWidget() << endl;
84 if (!use_gui || lyxerr.debugging()) {
85 lyxerr << toPlainText(title0) << '\n'
86 << "----------------------------------------\n"
87 << toPlainText(question) << endl;
89 lyxerr << "Assuming answer is ";
90 switch (default_button) {
91 case 0: lyxerr << b1 << endl; break;
92 case 1: lyxerr << b2 << endl; break;
93 case 2: lyxerr << b3 << endl; break;
94 case 3: lyxerr << b4 << endl;
97 return default_button;
100 docstring const title = bformat(_("LyX: %1$s"), title0);
102 /// Long operation in progress prevents user from Ok-ing the error dialog
103 bool long_op = theApp()->longOperationStarted();
105 theApp()->stopLongOperation();
107 // For some reason, sometimes Qt uses a hourglass or watch cursor when
108 // displaying the alert. Hence, we ask for the standard cursor shape.
109 qApp->setOverrideCursor(Qt::ArrowCursor);
111 // FIXME replace that with guiApp->currentView()
112 //LYXERR0("FOCUS: " << qApp->focusWidget());
113 QPushButton * b[4] = { 0, 0, 0, 0 };
114 QMessageBox msg_box(QMessageBox::Information,
115 toqstr(title), toqstr(question),
116 QMessageBox::NoButton, qApp->focusWidget());
117 b[0] = msg_box.addButton(b1.empty() ? "OK" : toqstr(b1),
118 QMessageBox::ActionRole);
120 b[1] = msg_box.addButton(toqstr(b2), QMessageBox::ActionRole);
122 b[2] = msg_box.addButton(toqstr(b3), QMessageBox::ActionRole);
124 b[3] = msg_box.addButton(toqstr(b4), QMessageBox::ActionRole);
125 msg_box.setDefaultButton(b[default_button]);
126 msg_box.setEscapeButton(static_cast<QAbstractButton *>(b[cancel_button]));
127 int res = msg_box.exec();
129 qApp->restoreOverrideCursor();
132 theApp()->startLongOperation();
134 // Qt bug: can return -1 on cancel or WM close, despite the docs.
140 int prompt(docstring const & title0, docstring const & question,
141 int default_button, int cancel_button,
142 docstring const & b0, docstring const & b1,
143 docstring const & b2, docstring const & b3)
145 #ifdef EXPORT_in_THREAD
146 return InGuiThread<int>().call(&doPrompt,
150 title0, question, default_button,
151 cancel_button, b0, b1, b2, b3);
154 void doWarning(docstring const & title0, docstring const & message,
155 bool const & askshowagain)
157 lyxerr << "Warning: " << toPlainText(title0) << '\n'
158 << "----------------------------------------\n"
159 << toPlainText(message) << endl;
164 docstring const title = bformat(_("LyX: %1$s"), title0);
167 noAppDialog(toqstr(title), toqstr(message), QMessageBox::Warning);
171 /// Long operation in progress prevents user from Ok-ing the error dialog
172 bool long_op = theApp()->longOperationStarted();
174 theApp()->stopLongOperation();
176 // Don't use a hourglass cursor while displaying the alert
177 qApp->setOverrideCursor(Qt::ArrowCursor);
180 ProgressInterface::instance()->warning(
184 ProgressInterface::instance()->toggleWarning(
190 qApp->restoreOverrideCursor();
193 theApp()->startLongOperation();
196 void warning(docstring const & title0, docstring const & message,
197 bool const & askshowagain)
199 #ifdef EXPORT_in_THREAD
200 InGuiThread<void>().call(&doWarning,
204 title0, message, askshowagain);
207 void doError(docstring const & title0, docstring const & message, bool backtrace)
209 lyxerr << "Error: " << toPlainText(title0) << '\n'
210 << "----------------------------------------\n"
211 << toPlainText(message) << endl;
215 details = toqstr(printCallStack());
220 docstring const title = bformat(_("LyX: %1$s"), title0);
223 noAppDialog(toqstr(title), toqstr(message), QMessageBox::Critical);
227 /// Long operation in progress prevents user from Ok-ing the error dialog
228 bool long_op = theApp()->longOperationStarted();
230 theApp()->stopLongOperation();
232 // Don't use a hourglass cursor while displaying the alert
233 qApp->setOverrideCursor(Qt::ArrowCursor);
235 ProgressInterface::instance()->error(
240 qApp->restoreOverrideCursor();
243 theApp()->startLongOperation();
246 void error(docstring const & title0, docstring const & message, bool backtrace)
248 #ifdef EXPORT_in_THREAD
249 InGuiThread<void>().call(&doError,
253 title0, message, backtrace);
256 void doInformation(docstring const & title0, docstring const & message)
258 if (!use_gui || lyxerr.debugging())
259 lyxerr << toPlainText(title0) << '\n'
260 << "----------------------------------------\n"
261 << toPlainText(message) << endl;
266 docstring const title = bformat(_("LyX: %1$s"), title0);
269 noAppDialog(toqstr(title), toqstr(message), QMessageBox::Information);
273 /// Long operation in progress prevents user from Ok-ing the error dialog
274 bool long_op = theApp()->longOperationStarted();
276 theApp()->stopLongOperation();
278 // Don't use a hourglass cursor while displaying the alert
279 qApp->setOverrideCursor(Qt::ArrowCursor);
281 ProgressInterface::instance()->information(
285 qApp->restoreOverrideCursor();
288 theApp()->startLongOperation();
291 void information(docstring const & title0, docstring const & message)
293 #ifdef EXPORT_in_THREAD
294 InGuiThread<void>().call(&doInformation,
301 bool doAskForText(docstring & response, docstring const & msg,
302 docstring const & dflt)
304 if (!use_gui || lyxerr.debugging()) {
305 lyxerr << "----------------------------------------\n"
306 << toPlainText(msg) << '\n'
307 << "Assuming answer is " << dflt << '\n'
308 << "----------------------------------------" << endl;
315 docstring const title = bformat(_("LyX: %1$s"), msg);
317 /// Long operation in progress prevents user from Ok-ing the error dialog
318 bool long_op = theApp()->longOperationStarted();
320 theApp()->stopLongOperation();
323 QString text = QInputDialog::getText(qApp->focusWidget(),
325 toqstr(char_type('&') + msg),
330 theApp()->startLongOperation();
333 response = qstring_to_ucs4(text);
340 bool askForText(docstring & response, docstring const & msg,
341 docstring const & dflt)
343 #ifdef EXPORT_in_THREAD
344 return InGuiThread<bool>().call(&doAskForText,
348 response, msg, dflt);
352 } // namespace frontend