2 * \file qt4/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/ProgressInterface.h"
29 #include <QApplication>
31 #include <QMessageBox>
33 #include <QInputDialog>
34 #include <QPushButton>
41 // sync with GuiView.cpp
42 #define EXPORT_in_THREAD 1
46 using namespace lyx::support;
54 static docstring const formatted(docstring const & text)
66 size_t const nxtpos1 = text.find(' ', curpos);
67 size_t const nxtpos2 = text.find('\n', curpos);
68 size_t const nxtpos = min(nxtpos1, nxtpos2);
70 docstring const word =
71 nxtpos == docstring::npos ?
73 text.substr(curpos, nxtpos - curpos);
75 bool const newline = (nxtpos2 != docstring::npos &&
78 docstring const line_plus_word =
79 line.empty() ? word : line + char_type(' ') + word;
81 // FIXME: make w be size_t
82 if (int(line_plus_word.length()) >= w) {
83 sout += line + char_type('\n');
85 sout += word + char_type('\n');
92 sout += line_plus_word + char_type('\n');
97 line += char_type(' ');
101 if (nxtpos == docstring::npos) {
114 void noAppDialog(QString const & title, QString const & msg, QMessageBox::Icon mode)
117 const char *argv[] = { "lyx", 0 };
119 QApplication app(argc, (char**)argv);
122 case QMessageBox::Information: QMessageBox::information(0, title, msg); break;
123 case QMessageBox::Warning: QMessageBox::warning(0, title, msg); break;
124 case QMessageBox::Critical: QMessageBox::critical(0, title, msg); break;
133 int doPrompt(docstring const & title0, docstring const & question,
134 int default_button, int cancel_button,
135 docstring const & b1, docstring const & b2,
136 docstring const & b3, docstring const & b4)
138 //lyxerr << "PROMPT" << title0 << "FOCUS: " << qApp->focusWidget() << endl;
139 if (!use_gui || lyxerr.debugging()) {
140 lyxerr << title0 << '\n'
141 << "----------------------------------------\n"
144 lyxerr << "Assuming answer is ";
145 switch (default_button) {
146 case 0: lyxerr << b1 << endl;
147 case 1: lyxerr << b2 << endl;
148 case 2: lyxerr << b3 << endl;
149 case 3: lyxerr << b4 << endl;
152 return default_button;
155 docstring const title = bformat(_("LyX: %1$s"), title0);
157 // For some reason, sometimes Qt uses a hourglass or watch cursor when
158 // displaying the alert. Hence, we ask for the standard cursor shape.
159 qApp->setOverrideCursor(Qt::ArrowCursor);
161 // FIXME replace that with guiApp->currentView()
162 //LYXERR0("FOCUS: " << qApp->focusWidget());
163 QPushButton * b[4] = { 0, 0, 0, 0 };
164 QMessageBox msg_box(QMessageBox::Information,
165 toqstr(title), toqstr(formatted(question)),
166 QMessageBox::NoButton, qApp->focusWidget());
167 b[0] = msg_box.addButton(b1.empty() ? "OK" : toqstr(b1),
168 QMessageBox::ActionRole);
170 b[1] = msg_box.addButton(toqstr(b2), QMessageBox::ActionRole);
172 b[2] = msg_box.addButton(toqstr(b3), QMessageBox::ActionRole);
174 b[3] = msg_box.addButton(toqstr(b4), QMessageBox::ActionRole);
175 msg_box.setDefaultButton(b[default_button]);
176 msg_box.setEscapeButton(static_cast<QAbstractButton *>(b[cancel_button]));
177 int res = msg_box.exec();
179 qApp->restoreOverrideCursor();
181 // Qt bug: can return -1 on cancel or WM close, despite the docs.
187 int prompt(docstring const & title0, docstring const & question,
188 int default_button, int cancel_button,
189 docstring const & b1, docstring const & b2,
190 docstring const & b3, docstring const & b4)
192 #ifdef EXPORT_in_THREAD
193 return InGuiThread<int>().call(&doPrompt,
197 title0, question, default_button,
198 cancel_button, b1, b2, b3, b4);
201 void doWarning(docstring const & title0, docstring const & message,
202 bool const & askshowagain)
204 lyxerr << "Warning: " << title0 << '\n'
205 << "----------------------------------------\n"
211 docstring const title = bformat(_("LyX: %1$s"), title0);
214 noAppDialog(toqstr(title), toqstr(formatted(message)), QMessageBox::Warning);
218 // Don't use a hourglass cursor while displaying the alert
219 qApp->setOverrideCursor(Qt::ArrowCursor);
222 ProgressInterface::instance()->warning(
224 toqstr(formatted(message)));
226 ProgressInterface::instance()->toggleWarning(
229 toqstr(formatted(message)));
232 qApp->restoreOverrideCursor();
235 void warning(docstring const & title0, docstring const & message,
236 bool const & askshowagain)
238 #ifdef EXPORT_in_THREAD
239 InGuiThread<void>().call(&doWarning,
243 title0, message, askshowagain);
246 void doError(docstring const & title0, docstring const & message)
248 lyxerr << "Error: " << title0 << '\n'
249 << "----------------------------------------\n"
255 docstring const title = bformat(_("LyX: %1$s"), title0);
258 noAppDialog(toqstr(title), toqstr(formatted(message)), QMessageBox::Critical);
262 // Don't use a hourglass cursor while displaying the alert
263 qApp->setOverrideCursor(Qt::ArrowCursor);
265 ProgressInterface::instance()->error(
267 toqstr(formatted(message)));
269 qApp->restoreOverrideCursor();
272 void error(docstring const & title0, docstring const & message)
274 #ifdef EXPORT_in_THREAD
275 InGuiThread<void>().call(&doError,
282 void doInformation(docstring const & title0, docstring const & message)
284 if (!use_gui || lyxerr.debugging())
285 lyxerr << title0 << '\n'
286 << "----------------------------------------\n"
292 docstring const title = bformat(_("LyX: %1$s"), title0);
295 noAppDialog(toqstr(title), toqstr(formatted(message)), QMessageBox::Information);
299 // Don't use a hourglass cursor while displaying the alert
300 qApp->setOverrideCursor(Qt::ArrowCursor);
302 ProgressInterface::instance()->information(
304 toqstr(formatted(message)));
306 qApp->restoreOverrideCursor();
309 void information(docstring const & title0, docstring const & message)
311 #ifdef EXPORT_in_THREAD
312 InGuiThread<void>().call(&doInformation,
319 bool doAskForText(docstring & response, docstring const & msg,
320 docstring const & dflt)
322 if (!use_gui || lyxerr.debugging()) {
323 lyxerr << "----------------------------------------\n"
325 << "Assuming answer is " << dflt << '\n'
326 << "----------------------------------------" << endl;
333 docstring const title = bformat(_("LyX: %1$s"), msg);
336 QString text = QInputDialog::getText(qApp->focusWidget(),
338 toqstr(char_type('&') + msg),
343 response = qstring_to_ucs4(text);
350 bool askForText(docstring & response, docstring const & msg,
351 docstring const & dflt)
353 #ifdef EXPORT_in_THREAD
354 return InGuiThread<bool>().call(&doAskForText,
358 response, msg, dflt);
362 } // namespace frontend