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