]> git.lyx.org Git - lyx.git/blob - src/frontends/qt4/GuiAlert.cpp
Really use qstr to convert a string in a QString
[lyx.git] / src / frontends / qt4 / GuiAlert.cpp
1 /**
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.
5  *
6  * \author John Levon
7  * \author Jürgen Spitzmüller
8  * \author Abdelrazak Younes
9  *
10  * Full author contact details are available in file CREDITS.
11  */
12
13 #include <config.h>
14
15 #include "alert.h"
16 #include "InGuiThread.h"
17
18 #include "frontends/Application.h"
19
20 #include "qt_helpers.h"
21 #include "LyX.h" // for lyx::use_gui
22
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"
28
29 #include <QApplication>
30 #include <QCheckBox>
31 #include <QMessageBox>
32 #include <QLineEdit>
33 #include <QInputDialog>
34 #include <QPushButton>
35 #include <QSettings>
36
37 #include <iomanip>
38 #include <iostream>
39
40
41 // sync with GuiView.cpp
42 #define EXPORT_in_THREAD 1
43
44
45 using namespace std;
46 using namespace lyx::support;
47
48 namespace lyx {
49 namespace frontend {
50
51
52 void noAppDialog(QString const & title, QString const & msg, QMessageBox::Icon mode)
53 {
54         int argc = 1;
55         const char *argv[] = { "lyx", 0 };
56
57         QApplication app(argc, (char**)argv);
58         switch (mode)
59         {
60                 case QMessageBox::Information: QMessageBox::information(0, title, msg); break;
61                 case QMessageBox::Warning: QMessageBox::warning(0, title, msg); break;
62                 case QMessageBox::Critical: QMessageBox::critical(0, title, msg); break;
63                 default: break;
64         }
65 }
66
67
68 namespace Alert {
69
70
71 int doPrompt(docstring const & title0, docstring const & question,
72                   int default_button, int cancel_button,
73                   docstring const & b1, docstring const & b2,
74                   docstring const & b3, docstring const & b4)
75 {
76         //lyxerr << "PROMPT" << title0 << "FOCUS: " << qApp->focusWidget() << endl;
77         if (!use_gui || lyxerr.debugging()) {
78                 lyxerr << title0 << '\n'
79                        << "----------------------------------------\n"
80                        << question << endl;
81
82                 lyxerr << "Assuming answer is ";
83                 switch (default_button) {
84                 case 0: lyxerr << b1 << endl;
85                 case 1: lyxerr << b2 << endl;
86                 case 2: lyxerr << b3 << endl;
87                 case 3: lyxerr << b4 << endl;
88                 }
89                 if (!use_gui)
90                         return default_button;
91         }
92
93         docstring const title = bformat(_("LyX: %1$s"), title0);
94
95         /// Long operation in progress prevents user from Ok-ing the error dialog
96         bool long_op = theApp()->longOperationStarted();
97         if (long_op)
98                 theApp()->stopLongOperation();
99
100         // For some reason, sometimes Qt uses a hourglass or watch cursor when
101         // displaying the alert. Hence, we ask for the standard cursor shape.
102         qApp->setOverrideCursor(Qt::ArrowCursor);
103
104         // FIXME replace that with guiApp->currentView()
105         //LYXERR0("FOCUS: " << qApp->focusWidget());
106         QPushButton * b[4] = { 0, 0, 0, 0 };
107         QMessageBox msg_box(QMessageBox::Information,
108                         toqstr(title), toqstr(question),
109                         QMessageBox::NoButton, qApp->focusWidget());
110         b[0] = msg_box.addButton(b1.empty() ? "OK" : toqstr(b1),
111                                         QMessageBox::ActionRole);
112         if (!b2.empty())
113                 b[1] = msg_box.addButton(toqstr(b2), QMessageBox::ActionRole);
114         if (!b3.empty())
115                 b[2] = msg_box.addButton(toqstr(b3), QMessageBox::ActionRole);
116         if (!b4.empty())
117                 b[3] = msg_box.addButton(toqstr(b4), QMessageBox::ActionRole);
118         msg_box.setDefaultButton(b[default_button]);
119         msg_box.setEscapeButton(static_cast<QAbstractButton *>(b[cancel_button]));
120         int res = msg_box.exec();
121
122         qApp->restoreOverrideCursor();
123
124         if (long_op)
125                 theApp()->startLongOperation();
126
127         // Qt bug: can return -1 on cancel or WM close, despite the docs.
128         if (res == -1)
129                 res = cancel_button;
130         return res;
131 }
132
133 int prompt(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)
137 {
138 #ifdef EXPORT_in_THREAD
139         return InGuiThread<int>().call(&doPrompt,
140 #else
141         return doPrompt(
142 #endif
143                                 title0, question, default_button,
144                                 cancel_button, b1, b2, b3, b4);
145 }
146
147 void doWarning(docstring const & title0, docstring const & message,
148              bool const & askshowagain)
149 {
150         lyxerr << "Warning: " << title0 << '\n'
151                << "----------------------------------------\n"
152                << message << endl;
153
154         if (!use_gui)
155                 return;
156
157         docstring const title = bformat(_("LyX: %1$s"), title0);
158
159         if (theApp() == 0) {
160                 noAppDialog(toqstr(title), toqstr(message), QMessageBox::Warning);
161                 return;
162         }
163
164         /// Long operation in progress prevents user from Ok-ing the error dialog
165         bool long_op = theApp()->longOperationStarted();
166         if (long_op)
167                 theApp()->stopLongOperation();
168
169         // Don't use a hourglass cursor while displaying the alert
170         qApp->setOverrideCursor(Qt::ArrowCursor);
171
172         if (!askshowagain) {
173                 ProgressInterface::instance()->warning(
174                                 toqstr(title),
175                                 toqstr(message));
176         } else {
177                 ProgressInterface::instance()->toggleWarning(
178                                 toqstr(title),
179                                 toqstr(message),
180                                 toqstr(message));
181         }
182
183         qApp->restoreOverrideCursor();
184
185         if (long_op)
186                 theApp()->startLongOperation();
187 }
188
189 void warning(docstring const & title0, docstring const & message,
190              bool const & askshowagain)
191 {
192 #ifdef EXPORT_in_THREAD 
193         InGuiThread<void>().call(&doWarning,
194 #else
195         doWarning(
196 #endif
197                                 title0, message, askshowagain);
198 }
199
200 void doError(docstring const & title0, docstring const & message)
201 {
202         lyxerr << "Error: " << title0 << '\n'
203                << "----------------------------------------\n"
204                << message << endl;
205
206         if (!use_gui)
207                 return;
208
209         docstring const title = bformat(_("LyX: %1$s"), title0);
210
211         if (theApp() == 0) {
212                 noAppDialog(toqstr(title), toqstr(message), QMessageBox::Critical);
213                 return;
214         }
215
216         /// Long operation in progress prevents user from Ok-ing the error dialog
217         bool long_op = theApp()->longOperationStarted();
218         if (long_op)
219                 theApp()->stopLongOperation();
220
221         // Don't use a hourglass cursor while displaying the alert
222         qApp->setOverrideCursor(Qt::ArrowCursor);
223
224         ProgressInterface::instance()->error(
225                 toqstr(title),
226                 toqstr(message));
227
228         qApp->restoreOverrideCursor();
229
230         if (long_op)
231                 theApp()->startLongOperation();
232 }
233
234 void error(docstring const & title0, docstring const & message)
235 {
236 #ifdef EXPORT_in_THREAD
237         InGuiThread<void>().call(&doError, 
238 #else
239         doError(
240 #endif
241                                 title0, message);
242 }
243
244 void doInformation(docstring const & title0, docstring const & message)
245 {
246         if (!use_gui || lyxerr.debugging())
247                 lyxerr << title0 << '\n'
248                        << "----------------------------------------\n"
249                        << message << endl;
250
251         if (!use_gui)
252                 return;
253
254         docstring const title = bformat(_("LyX: %1$s"), title0);
255
256         if (theApp() == 0) {
257                 noAppDialog(toqstr(title), toqstr(message), QMessageBox::Information);
258                 return;
259         }
260
261         /// Long operation in progress prevents user from Ok-ing the error dialog
262         bool long_op = theApp()->longOperationStarted();
263         if (long_op)
264                 theApp()->stopLongOperation();
265
266         // Don't use a hourglass cursor while displaying the alert
267         qApp->setOverrideCursor(Qt::ArrowCursor);
268
269         ProgressInterface::instance()->information(
270                 toqstr(title),
271                 toqstr(message));
272
273         qApp->restoreOverrideCursor();
274
275         if (long_op)
276                 theApp()->startLongOperation();
277 }
278
279 void information(docstring const & title0, docstring const & message)
280 {
281 #ifdef EXPORT_in_THREAD
282         InGuiThread<void>().call(&doInformation,
283 #else
284         doInformation(
285 #endif
286                                 title0, message);
287 }
288
289 bool doAskForText(docstring & response, docstring const & msg,
290         docstring const & dflt)
291 {
292         if (!use_gui || lyxerr.debugging()) {
293                 lyxerr << "----------------------------------------\n"
294                        << msg << '\n'
295                        << "Assuming answer is " << dflt << '\n'
296                        << "----------------------------------------" << endl;
297                 if (!use_gui) {
298                         response = dflt;
299                         return true;
300                 }
301         }
302
303         docstring const title = bformat(_("LyX: %1$s"), msg);
304
305         /// Long operation in progress prevents user from Ok-ing the error dialog
306         bool long_op = theApp()->longOperationStarted();
307         if (long_op)
308                 theApp()->stopLongOperation();
309
310         bool ok;
311         QString text = QInputDialog::getText(qApp->focusWidget(),
312                 toqstr(title),
313                 toqstr(char_type('&') + msg),
314                 QLineEdit::Normal,
315                 toqstr(dflt), &ok);
316
317         if (long_op)
318                 theApp()->startLongOperation();
319
320         if (ok) {
321                 response = qstring_to_ucs4(text);
322                 return true;
323         }
324         response.clear();
325         return false;
326 }
327
328 bool askForText(docstring & response, docstring const & msg,
329         docstring const & dflt)
330 {
331 #ifdef EXPORT_in_THREAD
332         return InGuiThread<bool>().call(&doAskForText,
333 #else
334         return doAskForText(
335 #endif
336                                 response, msg, dflt);
337 }
338
339 } // namespace Alert
340 } // namespace frontend
341 } // namespace lyx