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