]> git.lyx.org Git - lyx.git/blob - src/frontends/qt4/GuiAlert.cpp
Migrate GuiLine to InsetParamsWidget.
[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
17
18 #include "frontends/Application.h"
19
20 #include "qt_helpers.h"
21 #include "LyX.h" // for lyx::use_gui
22 #include "support/gettext.h"
23
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 using namespace std;
41 using namespace lyx::support;
42
43 namespace lyx {
44 namespace frontend {
45
46
47
48
49 static docstring const formatted(docstring const & text)
50 {
51         const int w = 80;
52         docstring sout;
53
54         if (text.empty())
55                 return sout;
56
57         size_t curpos = 0;
58         docstring line;
59
60         while (true) {
61                 size_t const nxtpos1 = text.find(' ',  curpos);
62                 size_t const nxtpos2 = text.find('\n', curpos);
63                 size_t const nxtpos = min(nxtpos1, nxtpos2);
64
65                 docstring const word =
66                         nxtpos == docstring::npos ?
67                         text.substr(curpos) :
68                         text.substr(curpos, nxtpos - curpos);
69
70                 bool const newline = (nxtpos2 != docstring::npos &&
71                                       nxtpos2 < nxtpos1);
72
73                 docstring const line_plus_word =
74                         line.empty() ? word : line + char_type(' ') + word;
75
76                 // FIXME: make w be size_t
77                 if (int(line_plus_word.length()) >= w) {
78                         sout += line + char_type('\n');
79                         if (newline) {
80                                 sout += word + char_type('\n');
81                                 line.erase();
82                         } else {
83                                 line = word;
84                         }
85
86                 } else if (newline) {
87                         sout += line_plus_word + char_type('\n');
88                         line.erase();
89
90                 } else {
91                         if (!line.empty())
92                                 line += char_type(' ');
93                         line += word;
94                 }
95
96                 if (nxtpos == docstring::npos) {
97                         if (!line.empty())
98                                 sout += line;
99                         break;
100                 }
101
102                 curpos = nxtpos + 1;
103         }
104
105         return sout;
106 }
107
108
109 void noAppDialog(QString const & title, QString const & msg, QMessageBox::Icon mode)
110 {
111         int argc = 1;
112         const char *argv[] = { "lyx", 0 };
113
114         QApplication app(argc, (char**)argv);
115         switch (mode)
116         {
117                 case QMessageBox::Information: QMessageBox::information(0, title, msg); break;
118                 case QMessageBox::Warning: QMessageBox::warning(0, title, msg); break;
119                 case QMessageBox::Critical: QMessageBox::critical(0, title, msg); break;
120                 default: break;
121         }
122 }
123
124
125 namespace Alert {
126
127 int prompt(docstring const & title0, docstring const & question,
128                   int default_button, int cancel_button,
129                   docstring const & b1, docstring const & b2,
130                   docstring const & b3, docstring const & b4)
131 {
132         //lyxerr << "PROMPT" << title0 << "FOCUS: " << qApp->focusWidget() << endl;
133         if (!use_gui || lyxerr.debugging()) {
134                 lyxerr << title0 << '\n'
135                        << "----------------------------------------\n"
136                        << question << endl;
137
138                 lyxerr << "Assuming answer is ";
139                 switch (default_button) {
140                 case 0: lyxerr << b1 << endl;
141                 case 1: lyxerr << b2 << endl;
142                 case 2: lyxerr << b3 << endl;
143                 case 3: lyxerr << b4 << endl;
144                 }
145                 if (!use_gui)
146                         return default_button;
147         }
148
149         docstring const title = bformat(_("LyX: %1$s"), title0);
150
151         // For some reason, sometimes Qt uses a hourglass or watch cursor when
152         // displaying the alert. Hence, we ask for the standard cursor shape.
153         qApp->setOverrideCursor(Qt::ArrowCursor);
154
155         // FIXME replace that with guiApp->currentView()
156         //LYXERR0("FOCUS: " << qApp->focusWidget());
157         QPushButton * b[4] = { 0, 0, 0, 0 };
158         QMessageBox msg_box(QMessageBox::Information,
159                         toqstr(title), toqstr(formatted(question)),
160                         QMessageBox::NoButton, qApp->focusWidget());
161         b[0] = msg_box.addButton(b1.empty() ? "OK" : toqstr(b1),
162                                         QMessageBox::ActionRole);
163         if (!b2.empty())
164                 b[1] = msg_box.addButton(toqstr(b2), QMessageBox::ActionRole);
165         if (!b3.empty())
166                 b[2] = msg_box.addButton(toqstr(b3), QMessageBox::ActionRole);
167         if (!b4.empty())
168                 b[3] = msg_box.addButton(toqstr(b4), QMessageBox::ActionRole);
169         msg_box.setDefaultButton(b[default_button]);
170         msg_box.setEscapeButton(static_cast<QAbstractButton *>(b[cancel_button]));
171         int res = msg_box.exec();
172
173         qApp->restoreOverrideCursor();
174
175         // Qt bug: can return -1 on cancel or WM close, despite the docs.
176         if (res == -1)
177                 res = cancel_button;
178         return res;
179 }
180
181
182 void warning(docstring const & title0, docstring const & message,
183              bool const & askshowagain)
184 {
185         lyxerr << "Warning: " << title0 << '\n'
186                << "----------------------------------------\n"
187                << message << endl;
188
189         if (!use_gui)
190                 return;
191
192         docstring const title = bformat(_("LyX: %1$s"), title0);
193
194         if (theApp() == 0) {
195                 noAppDialog(toqstr(title), toqstr(formatted(message)), QMessageBox::Warning);
196                 return;
197         }
198
199         // Don't use a hourglass cursor while displaying the alert
200         qApp->setOverrideCursor(Qt::ArrowCursor);
201
202         if (!askshowagain) {
203                 ProgressInterface::instance()->warning(
204                                 toqstr(title),
205                                 toqstr(formatted(message)));
206         } else {
207                 ProgressInterface::instance()->toggleWarning(
208                                 toqstr(title),
209                                 toqstr(message),
210                                 toqstr(formatted(message)));
211         }
212
213         qApp->restoreOverrideCursor();
214 }
215
216
217 void error(docstring const & title0, docstring const & message)
218 {
219         lyxerr << "Error: " << title0 << '\n'
220                << "----------------------------------------\n"
221                << message << endl;
222
223         if (!use_gui)
224                 return;
225
226         docstring const title = bformat(_("LyX: %1$s"), title0);
227
228         if (theApp() == 0) {
229                 noAppDialog(toqstr(title), toqstr(formatted(message)), QMessageBox::Critical);
230                 return;
231         }
232
233         // Don't use a hourglass cursor while displaying the alert
234         qApp->setOverrideCursor(Qt::ArrowCursor);
235
236         ProgressInterface::instance()->error(
237                 toqstr(title),
238                 toqstr(formatted(message)));
239
240         qApp->restoreOverrideCursor();
241 }
242
243
244 void information(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(formatted(message)), QMessageBox::Information);
258                 return;
259         }
260
261         // Don't use a hourglass cursor while displaying the alert
262         qApp->setOverrideCursor(Qt::ArrowCursor);
263
264         ProgressInterface::instance()->information(
265                 toqstr(title),
266                 toqstr(formatted(message)));
267
268         qApp->restoreOverrideCursor();
269 }
270
271
272 bool askForText(docstring & response, docstring const & msg,
273         docstring const & dflt)
274 {
275         if (!use_gui || lyxerr.debugging()) {
276                 lyxerr << "----------------------------------------\n"
277                        << msg << '\n'
278                        << "Assuming answer is " << dflt << '\n'
279                        << "----------------------------------------" << endl;
280                 if (!use_gui) {
281                         response = dflt;
282                         return true;
283                 }
284         }
285
286         docstring const title = bformat(_("LyX: %1$s"), msg);
287
288         bool ok;
289         QString text = QInputDialog::getText(qApp->focusWidget(),
290                 toqstr(title),
291                 toqstr(char_type('&') + msg),
292                 QLineEdit::Normal,
293                 toqstr(dflt), &ok);
294
295         if (ok) {
296                 response = qstring_to_ucs4(text);
297                 return true;
298         }
299         response.clear();
300         return false;
301 }
302
303
304 } // namespace Alert
305 } // namespace frontend
306 } // namespace lyx