]> git.lyx.org Git - lyx.git/blob - src/frontends/qt2/QMathDialog.C
better selection and scrolling behaviour
[lyx.git] / src / frontends / qt2 / QMathDialog.C
1 /**
2  * \file QMathDialog.C
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  *
8  * Full author contact details are available in file CREDITS
9  */
10
11 #include <config.h>
12
13 #ifdef __GNUG__
14 #pragma implementation
15 #endif
16
17 #include "support/filetools.h"
18 #include "gettext.h"
19 #include "debug.h"
20
21 #include "ControlMath.h"
22
23 #include "QMathDialog.h"
24 #include "QMath.h"
25
26 #include "iconpalette.h"
27 #include "QDelimiterDialog.h"
28 #include "QMathMatrixDialog.h"
29
30 #include <qapplication.h>
31 #include <qwidgetstack.h>
32 #include <qcombobox.h>
33 #include <qpushbutton.h>
34 #include <qlistbox.h>
35 #include <qpixmap.h>
36 #include <qscrollview.h>
37 #include <qlayout.h>
38 #include <qpopupmenu.h>
39 #include <qcursor.h>
40
41 using std::min;
42 using std::max;
43 using std::endl;
44
45
46 class QScrollViewSingle : public QScrollView {
47 public:
48         QScrollViewSingle(QWidget * p)
49                 : QScrollView(p), w_(0) {
50                 setResizePolicy(Manual);
51                 setHScrollBarMode(AlwaysOff);
52                 setVScrollBarMode(AlwaysOn);
53                 setBackgroundMode(PaletteBackground);
54                 viewport()->setBackgroundMode(PaletteBackground);
55         }
56
57         void setChild(QWidget * w) {
58                 w_ = w;
59                 setMinimumWidth(verticalScrollBar()->width() + w_->width() + 4);
60                 addChild(w_);
61         }
62 protected:
63         virtual void resizeEvent(QResizeEvent * e) {
64                 QScrollView::resizeEvent(e);
65                 if (!w_)
66                         return;
67
68                 w_->resize(viewport()->width(), w_->height());
69                 // force the resize to get accurate scrollbars
70                 qApp->processEvents();
71                 resizeContents(w_->width(), w_->height());
72         }
73 private:
74         QWidget * w_;
75 };
76
77 namespace {
78
79 char const ** panels[] = {
80         latex_bop, latex_varsz, latex_brel, latex_greek, latex_arrow,
81         latex_dots, latex_deco, latex_misc, latex_ams_ops,
82         latex_ams_rel, latex_ams_nrel, latex_ams_arrows,
83         latex_ams_misc
84 };
85
86 int const nr_panels = sizeof(panels)/sizeof(panels[0]);
87
88 bool panel_initialised[nr_panels];
89
90 } // namespace anon
91
92
93 QMathDialog::QMathDialog(QMath * form)
94         : QMathDialogBase(0, 0, false, 0),
95         form_(form)
96 {
97         // enlarge the symbols ComboBox (no scrollbar)
98         symbolsCO->setSizeLimit(13);
99
100         connect(symbolsCO, SIGNAL(activated(int)), symbolsWS, SLOT(raiseWidget(int)));
101
102         for (int i = 0; *function_names[i]; ++i) {
103                 functionsLB->insertItem(function_names[i]);
104         }
105
106         for (int i = 0; i < nr_panels; ++i) {
107                 QScrollViewSingle * view = new QScrollViewSingle(symbolsWS);
108                 symbolsWS->addWidget(view, i);
109         }
110
111         // aboutToShow() only fires when != 0 in Qt 2 !
112         symbolsWS->raiseWidget(0);
113         addPanel(0);
114         panel_initialised[0] = true;
115
116         connect(symbolsWS, SIGNAL(aboutToShow(int)), this, SLOT(showingPanel(int)));
117
118         QPopupMenu * m = new QPopupMenu(spacePB);
119         m->setCaption(_("LyX: Insert space"));
120         m->insertTearOffHandle();
121         m->insertItem(_("Thin space     \\,"), 1);
122         m->insertItem(_("Medium space   \\:"), 2);
123         m->insertItem(_("Thick space    \\;"), 3);
124         m->insertItem(_("Quadratin space        \\quad"), 4);
125         m->insertItem(_("Double quadratin space \\qquad"), 5);
126         m->insertItem(_("Negative space \\!"), 6);
127         connect(m, SIGNAL(activated(int)), this, SLOT(insertSpace(int)));
128         spacePB->setPopup(m);
129
130         m = new QPopupMenu(sqrtPB);
131         m->setCaption(_("LyX: Insert root"));
132         m->insertTearOffHandle();
133         m->insertItem(_("Square root    \\sqrt"), 1);
134         m->insertItem(_("Cube root      \\root"), 2);
135         m->insertItem(_("Other root     \\root"), 3);
136         connect(m, SIGNAL(activated(int)), this, SLOT(insertRoot(int)));
137         sqrtPB->setPopup(m);
138
139         m = new QPopupMenu(stylePB);
140         m->setCaption(_("LyX: Set math style"));
141         m->insertTearOffHandle();
142         m->insertItem(_("Display style  \\displaystyle"), 1);
143         m->insertItem(_("Normal text style      \\textstyle"), 2);
144         m->insertItem(_("Script (small) style   \\scriptstyle"), 3);
145         m->insertItem(_("Scriptscript (smaller) style   \\scriptscriptstyle"), 4);
146         connect(m, SIGNAL(activated(int)), this, SLOT(insertStyle(int)));
147         stylePB->setPopup(m);
148
149         m = new QPopupMenu(fontPB);
150         m->setCaption(_("LyX: Set math font"));
151         m->insertTearOffHandle();
152         m->insertItem(_("Roman  \\mathrm"), 1);
153         m->insertItem(_("Bold   \\mathbf"), 2);
154         m->insertItem(_("San serif      \\mathsf"), 3);
155         m->insertItem(_("Italic \\mathit"), 4);
156         m->insertItem(_("Typewriter     \\mathtt"), 5);
157         m->insertItem(_("Blackboard     \\mathbb"), 6);
158         m->insertItem(_("Fraktur        \\mathfrak"), 7);
159         m->insertItem(_("Calligraphic   \\mathcal"), 8);
160         m->insertItem(_("Normal text mode       \\textrm"), 9);
161         connect(m, SIGNAL(activated(int)), this, SLOT(insertFont(int)));
162         fontPB->setPopup(m);
163 }
164
165
166 void QMathDialog::showingPanel(int num)
167 {
168         if (panel_initialised[num])
169                 return;
170
171         addPanel(num);
172
173         // Qt needs to catch up. Dunno why.
174         qApp->processEvents();
175
176         panel_initialised[num] = true;
177 }
178
179
180 IconPalette * QMathDialog::makePanel(QWidget * parent, char const ** entries)
181 {
182         IconPalette * p = new IconPalette(parent);
183         for (int i = 0; *entries[i]; ++i) {
184                 p->add(QPixmap(find_xpm(entries[i]).c_str()), entries[i], string("\\") + entries[i]);
185         }
186         connect(p, SIGNAL(button_clicked(string const &)), this, SLOT(symbol_clicked(string const &)));
187
188         return p;
189 }
190
191
192 void QMathDialog::addPanel(int num)
193 {
194         QScrollViewSingle * view = static_cast<QScrollViewSingle*>(symbolsWS->visibleWidget());
195         IconPalette * p = makePanel(view->viewport(), panels[num]);
196         view->setChild(p);
197 }
198
199
200 void QMathDialog::symbol_clicked(string const & str)
201 {
202         form_->insert(str);
203 }
204
205
206 void QMathDialog::fracClicked()
207 {
208         form_->insert("frac");
209 }
210
211
212 void QMathDialog::delimiterClicked()
213 {
214         // FIXME: leak
215         QDelimiterDialog * d = new QDelimiterDialog(form_);
216         d->show();
217 }
218
219
220 void QMathDialog::expandClicked()
221 {
222         int const id = symbolsWS->id(symbolsWS->visibleWidget());
223         IconPalette * p = makePanel(0, panels[id]);
224         string s = "LyX: ";
225         s += symbolsCO->text(id).latin1();
226         p->setCaption(s.c_str());
227         p->resize(40 * 5, p->height());
228         p->show();
229         p->setMaximumSize(p->width(), p->height());
230 }
231
232
233 void QMathDialog::functionSelected(const QString & str)
234 {
235         form_->insert(str.latin1());
236 }
237
238
239 void QMathDialog::matrixClicked()
240 {
241         // FIXME: leak?
242         QMathMatrixDialog * d = new QMathMatrixDialog(form_);
243         d->show();
244 }
245
246
247 void QMathDialog::equationClicked()
248 {
249         form_->toggleDisplay();
250 }
251
252
253 void QMathDialog::subscriptClicked()
254 {
255         form_->subscript();
256 }
257
258
259 void QMathDialog::superscriptClicked()
260 {
261         form_->superscript();
262 }
263
264
265 void QMathDialog::insertSpace(int id)
266 {
267         string str;
268         switch (id) {
269                 case 1: str = ","; break;
270                 case 2: str = ":"; break;
271                 case 3: str = ";"; break;
272                 case 4: str = "quad"; break;
273                 case 5: str = "qquad"; break;
274                 case 6: str = "!"; break;
275                 default: return;
276         }
277         form_->insert(str);
278 }
279
280
281 void QMathDialog::insertRoot(int id)
282 {
283         switch (id) {
284                 case 1:
285                         form_->insert("sqrt");
286                         break;
287                 case 2:
288                         form_->insertCubeRoot();
289                         break;
290                 case 3:
291                         form_->insert("root");
292                         break;
293         }
294 }
295
296
297 void QMathDialog::insertStyle(int id)
298 {
299         string str;
300         switch (id) {
301                 case 1: str = "displaystyle"; break;
302                 case 2: str = "textstyle"; break;
303                 case 3: str = "scriptstyle"; break;
304                 case 4: str = "scriptscriptstyle"; break;
305                 default: return;
306         }
307         form_->insert(str);
308 }
309
310
311 void QMathDialog::insertFont(int id)
312 {
313         string str;
314         switch (id) {
315                 case 1: str = "mathrm"; break;
316                 case 2: str = "mathbf"; break;
317                 case 3: str = "mathsf"; break;
318                 case 4: str = "mathit"; break;
319                 case 5: str = "mathtt"; break;
320                 case 6: str = "mathbb"; break;
321                 case 7: str = "mathfrak"; break;
322                 case 8: str = "mathcal"; break;
323                 case 9: str = "textrm"; break;
324                 default: return;
325         }
326         form_->insert(str);
327 }