]> git.lyx.org Git - lyx.git/blob - src/frontends/qt4/QDelimiterDialog.cpp
* src/frontends/qt4/ui/TextLayoutUi.ui:
[lyx.git] / src / frontends / qt4 / QDelimiterDialog.cpp
1 /**
2  * \file QDelimiterDialog.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  *
8  * Full author contact details are available in file CREDITS.
9  */
10
11 #include <config.h>
12
13 #include "QDelimiterDialog.h"
14
15 #include "GuiApplication.h"
16 #include "GuiView.h"
17
18
19 #include "qt_helpers.h"
20 #include "controllers/ControlMath.h"
21
22 #include "gettext.h"
23
24 #include <QPixmap>
25 #include <QCheckBox>
26 #include <QListWidgetItem>
27
28 #include <sstream>
29
30 // Set to zero if unicode symbols are preferred.
31 #define USE_PIXMAP 1
32
33 using std::string;
34
35 namespace lyx {
36 namespace frontend {
37
38 namespace {
39
40 QString const bigleft[]  = {"", "bigl", "Bigl", "biggl", "Biggl"};
41
42
43 QString const bigright[] = {"", "bigr", "Bigr", "biggr", "Biggr"};
44
45
46 char const * const biggui[]   = {N_("big[[delimiter size]]"), N_("Big[[delimiter size]]"),
47         N_("bigg[[delimiter size]]"), N_("Bigg[[delimiter size]]"), ""};
48
49
50 // FIXME: It might be better to fix the big delim LFUN to not require
51 // additional '\' prefix.
52 QString fix_name(QString const & str, bool big)
53 {
54         if (str.isEmpty())
55                 return ".";
56         if (!big || str == "(" || str == ")" || str == "[" || str == "]"
57             || str == "|" || str == "/")
58                 return str;
59
60         return "\\" + str;
61 }
62
63 } // namespace anon
64
65
66 typedef QController<ControlMath, QView<QDelimiterDialog> > delimiter_base;
67
68 QMathDelimiter::QMathDelimiter(Dialog & parent)
69         : delimiter_base(parent, _("Math Delimiter"))
70 {}
71
72
73 void QMathDelimiter::build_dialog()
74 {
75         dialog_.reset(new QDelimiterDialog(this,
76                 static_cast<GuiView *>(controller().view())));
77 }
78
79
80 char_type QDelimiterDialog::doMatch(char_type const symbol) const
81 {
82         string const & str = form_->controller().texName(symbol);
83         string match;
84         if (str == "(") match = ")";
85         else if (str == ")") match = "(";
86         else if (str == "[") match = "]";
87         else if (str == "]") match = "[";
88         else if (str == "{") match = "}";
89         else if (str == "}") match = "{";
90         else if (str == "l") match = "r";
91         else if (str == "rceil") match = "lceil";
92         else if (str == "lceil") match = "rceil";
93         else if (str == "rfloor") match = "lfloor";
94         else if (str == "lfloor") match = "rfloor";
95         else if (str == "rangle") match = "langle";
96         else if (str == "langle") match = "rangle";
97         else if (str == "backslash") match = "/";
98         else if (str == "/") match = "backslash";
99         else return symbol;
100
101         return form_->controller().mathSymbol(match).unicode;
102 }
103
104
105 QDelimiterDialog::QDelimiterDialog(QMathDelimiter * form, QWidget * parent)
106         : QDialog(parent), form_(form)
107 {
108         setupUi(this);
109
110         connect(closePB, SIGNAL(clicked()), this, SLOT(accept()));
111
112         setWindowTitle(qt_("LyX: Delimiters"));
113         setFocusProxy(leftLW);
114
115         leftLW->setViewMode(QListView::IconMode);
116         rightLW->setViewMode(QListView::IconMode);
117
118         typedef std::map<char_type, QListWidgetItem *> ListItems;
119         ListItems list_items;
120         // The last element is the empty one.
121         int const end = nr_latex_delimiters - 1;
122         for (int i = 0; i < end; ++i) {
123                 string const delim = latex_delimiters[i];
124                 MathSymbol const & ms = form_->controller().mathSymbol(delim);
125                 QString symbol(ms.fontcode?
126                         QChar(ms.fontcode) : toqstr(docstring(1, ms.unicode)));
127                 QListWidgetItem * lwi = new QListWidgetItem(symbol);
128                 lwi->setToolTip(toqstr(delim));
129                 Font lyxfont;
130                 lyxfont.setFamily(ms.fontfamily);
131                 QFont const & symbol_font = guiApp->guiFontLoader().get(lyxfont);
132                 lwi->setFont(symbol_font);
133                 list_items[ms.unicode] = lwi;
134                 leftLW->addItem(lwi);
135         }
136
137         for (int i = 0; i != leftLW->count(); ++i) {
138                 MathSymbol const & ms = form_->controller().mathSymbol(
139                         fromqstr(leftLW->item(i)->toolTip()));
140                 rightLW->addItem(list_items[doMatch(ms.unicode)]->clone());
141         }
142
143         // The last element is the empty one.
144         leftLW->addItem(qt_("(None)"));
145         rightLW->addItem(qt_("(None)"));
146
147         sizeCO->addItem(qt_("Variable"));
148
149         for (int i = 0; *biggui[i]; ++i)
150                 sizeCO->addItem(qt_(biggui[i]));
151
152         on_leftLW_currentRowChanged(0);
153 }
154
155
156 void QDelimiterDialog::updateTeXCode(int size)
157 {
158         bool const bigsize = size != 0;
159
160         QString left_str = fix_name(leftLW->currentItem()->toolTip(), bigsize);
161         QString right_str = fix_name(rightLW->currentItem()->toolTip(), bigsize);
162
163         if (!bigsize)
164                 tex_code_ = left_str + ' ' + right_str;
165         else {
166                 tex_code_ = bigleft[size] + ' '
167                         + left_str + ' '
168                         + bigright[size] + ' '
169                         + right_str;
170         }
171
172         // Generate TeX-code for GUI display.
173         // FIXME: Instead of reconstructing the TeX code it would be nice to
174         // FIXME: retrieve the LateX code directly from mathed.
175         // In all cases, we want the '\' prefix if needed, so we pass 'true'
176         // to fix_name.
177         left_str = fix_name(leftLW->currentItem()->toolTip(), true);
178         right_str = fix_name(rightLW->currentItem()->toolTip(), true);
179         QString code_str;
180         if (!bigsize)
181                 code_str = "\\left" + left_str + " \\right" + right_str;
182         else {
183                 // There should be nothing in the TeX-code when the delimiter is "None".
184                 if (left_str != ".")
185                         code_str = "\\" + bigleft[size] + left_str + ' ';
186                 if (right_str != ".")
187                         code_str += "\\" + bigright[size] + right_str;
188         }
189
190         texCodeL->setText(qt_("TeX Code: ") + code_str);
191 }
192
193
194 void QDelimiterDialog::on_insertPB_clicked()
195 {
196         if (sizeCO->currentIndex() == 0)
197                 form_->controller().dispatchDelim(fromqstr(tex_code_));
198         else {
199                 QString command = '"' + tex_code_ + '"';
200                 command.replace(' ', "\" \"");
201                 form_->controller().dispatchBigDelim(fromqstr(command));
202         }
203  }
204
205
206 void QDelimiterDialog::on_sizeCO_activated(int index)
207 {
208         updateTeXCode(index);
209 }
210
211
212 void QDelimiterDialog::on_leftLW_itemActivated(QListWidgetItem *)
213 {
214         on_insertPB_clicked();
215         accept();
216 }
217
218
219 void QDelimiterDialog::on_rightLW_itemActivated(QListWidgetItem *)
220 {
221         on_insertPB_clicked();
222         accept();
223 }
224
225
226 void QDelimiterDialog::on_leftLW_currentRowChanged(int item)
227 {
228         if (matchCB->isChecked())
229                 rightLW->setCurrentRow(item);
230
231         updateTeXCode(sizeCO->currentIndex());
232 }
233
234
235 void QDelimiterDialog::on_rightLW_currentRowChanged(int item)
236 {
237         if (matchCB->isChecked())
238                 leftLW->setCurrentRow(item);
239
240         updateTeXCode(sizeCO->currentIndex());
241 }
242
243
244 void QDelimiterDialog::on_matchCB_stateChanged(int state)
245 {
246         if (state == Qt::Checked)
247                 on_leftLW_currentRowChanged(leftLW->currentRow());
248
249         updateTeXCode(sizeCO->currentIndex());
250 }
251
252
253 } // namespace frontend
254 } // namespace lyx
255
256 #include "QDelimiterDialog_moc.cpp"