1 /* This file is part of the KDE project
2 Copyright (C) 2011 Cyrille Berger <cberger@cberger.net>
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 Boston, MA 02110-1301, USA.
18 */
19
20 #include "KoM2MMLForumulaTool.h"
21
22 #ifdef HAVE_M2MML
23 #include <m2mml.h>
24 #endif
25
26 #include <string>
27
28 #include <QComboBox>
29 #include <QHBoxLayout>
30 #include <QLabel>
31 #include <QLineEdit>
32 #include <QSpacerItem>
33 #include <QWidget>
34
35 #include <KoCanvasBase.h>
36 #include <KoIcon.h>
37 #include <KoXmlReader.h>
38
39 #include <AnnotationElement.h>
40 #include "FormulaDebug.h"
41 #include "KoFormulaShape.h"
42 #include "FormulaCommand.h"
43 #include "FormulaCommandUpdate.h"
44 #include "3rdparty/itexToMML/itex2MML.h"
45
KoM2MMLFormulaTool(KoCanvasBase * canvas)46 KoM2MMLFormulaTool::KoM2MMLFormulaTool(KoCanvasBase* canvas): KoToolBase(canvas), m_lineEdit(0), m_errorLabel(0), m_formulaShape(0), m_comboBox(0)
47 {
48
49 }
50
activate(KoToolBase::ToolActivation toolActivation,const QSet<KoShape * > & shapes)51 void KoM2MMLFormulaTool::activate(KoToolBase::ToolActivation toolActivation, const QSet< KoShape* >& shapes)
52 {
53 Q_UNUSED(toolActivation);
54
55 foreach (KoShape *shape, shapes) {
56 m_formulaShape = dynamic_cast<KoFormulaShape*>( shape );
57 if( m_formulaShape )
58 break;
59 }
60
61 if( m_formulaShape == 0 ) // none found
62 {
63 emit done();
64 return;
65 }
66 FormulaElement* element = m_formulaShape->formulaData()->formulaElement();
67 foreach(BasicElement* elt, element->childElements())
68 {
69 if(elt->elementType() == Annotation)
70 {
71 AnnotationElement* annot = static_cast<AnnotationElement*>(elt);
72 m_text = annot->content();
73 m_mode = annot->attribute("mode");
74 }
75 }
76
77 if(m_lineEdit)
78 {
79 m_lineEdit->setText(m_text);
80 }
81 }
82
mouseMoveEvent(KoPointerEvent * event)83 void KoM2MMLFormulaTool::mouseMoveEvent(KoPointerEvent* event)
84 {
85 Q_UNUSED(event);
86 }
87
mousePressEvent(KoPointerEvent * event)88 void KoM2MMLFormulaTool::mousePressEvent(KoPointerEvent* event)
89 {
90 Q_UNUSED(event);
91 }
92
mouseReleaseEvent(KoPointerEvent * event)93 void KoM2MMLFormulaTool::mouseReleaseEvent(KoPointerEvent* event)
94 {
95 Q_UNUSED(event);
96 }
97
paint(QPainter & painter,const KoViewConverter & converter)98 void KoM2MMLFormulaTool::paint(QPainter& painter, const KoViewConverter& converter)
99 {
100 Q_UNUSED(painter);
101 Q_UNUSED(converter);
102 }
103
createOptionWidget()104 QWidget* KoM2MMLFormulaTool::createOptionWidget()
105 {
106 QWidget* widget = new QWidget;
107 QVBoxLayout* layout = new QVBoxLayout;
108
109 // Combobox to select between latex or matlab
110 QLabel* modeLabel = new QLabel(i18n("Mode: "));
111 m_comboBox = new QComboBox;
112
113 m_comboBox->addItem(i18n("LaTeX"));
114 #ifdef HAVE_M2MML
115 m_comboBox->addItem(i18n("Matlab"));
116
117 if(m_mode == "Matlab")
118 {
119 m_comboBox->setCurrentIndex(1);
120 }
121 #endif
122
123 QHBoxLayout* hlayout = new QHBoxLayout();
124 hlayout->addWidget(modeLabel);
125 hlayout->addWidget(m_comboBox);
126 layout->addLayout(hlayout);
127
128 // Edit line
129 widget->setLayout(layout);
130 m_lineEdit = new QLineEdit(widget);
131 layout->addWidget(m_lineEdit);
132
133 // Error label
134 m_errorLabel = new QLabel(widget);
135 layout->addWidget(m_errorLabel);
136 m_errorLabel->setText("");
137
138 layout->addSpacerItem(new QSpacerItem(0,0));
139
140 connect(m_lineEdit, SIGNAL(editingFinished()), SLOT(textEdited()));
141 connect(m_lineEdit, SIGNAL(returnPressed()), SLOT(textEdited()));
142 m_lineEdit->setText(m_text);
143
144 return widget;
145 }
146
147 // Not sure why but the toStdString/fromStdString in QString are not accessible
QStringtoStdString(const QString & str)148 inline std::string QStringtoStdString(const QString& str)
149 { const QByteArray latin1 = str.toLatin1(); return std::string(latin1.constData(), latin1.length()); }
150
QStringfromStdString(const std::string & s)151 inline QString QStringfromStdString(const std::string &s)
152 { return QString::fromLatin1(s.data(), int(s.size())); }
153
textEdited()154 void KoM2MMLFormulaTool::textEdited()
155 {
156 if(!m_formulaShape) return;
157 if(!m_lineEdit) return;
158
159 #ifdef HAVE_M2MML
160 if(m_comboBox->currentIndex() == 1)
161 {
162 std::string source = QStringtoStdString(m_lineEdit->text());
163 std::string mathml;
164 std::string errmsg;
165
166 if(m2mml(source, mathml, &errmsg))
167 {
168 setMathML(QStringfromStdString(mathml), "Matlab");
169 } else {
170 m_errorLabel->setText(QStringfromStdString(errmsg));
171 }
172 } else {
173 #endif
174 std::string source = QStringtoStdString(m_lineEdit->text());
175 source = '$' + source + '$';
176 char * mathml = itex2MML_parse (source.c_str(), source.size());
177
178 if(mathml)
179 {
180 setMathML(mathml, "LaTeX");
181 itex2MML_free_string(mathml);
182 mathml = 0;
183 } else {
184 m_errorLabel->setText(i18n("Parse error."));
185 }
186 #ifdef HAVE_M2MML
187 }
188 #endif
189 }
190
setMathML(const QString & mathml,const QString & mode)191 void KoM2MMLFormulaTool::setMathML(const QString& mathml, const QString& mode)
192 {
193 KoXmlDocument tmpDocument;
194 tmpDocument.setContent( QString(mathml), false, 0, 0, 0 );
195 FormulaElement* formulaElement = new FormulaElement(); // create a new root element
196 formulaElement->readMathML( tmpDocument.documentElement() ); // and load the new formula
197
198 AnnotationElement* annot = new AnnotationElement;
199 annot->setContent(m_lineEdit->text());
200 annot->setAttribute("mode", mode);
201 formulaElement->insertChild(0, annot);
202
203 debugFormula << mathml;
204
205 canvas()->addCommand(new FormulaCommandUpdate(m_formulaShape, new FormulaCommandLoad(m_formulaShape->formulaData(), formulaElement)));
206 m_errorLabel->setText("");
207 }
208
209
KoM2MMLFormulaToolFactory()210 KoM2MMLFormulaToolFactory::KoM2MMLFormulaToolFactory()
211 : KoToolFactoryBase("KoM2MMLFormulaToolFactoryId")
212 {
213 #ifdef HAVE_M2MML
214 setToolTip( i18n( "Edit formula with LaTeX/Matlab syntax" ) );
215 #else
216 setToolTip( i18n( "Edit formula with LaTeX syntax" ) );
217 #endif
218 setToolType( dynamicToolType() );
219 setIconName(koIconName("edittext"));
220 setPriority( 1 );
221 setActivationShapeId( KoFormulaShapeId );
222 }
223
~KoM2MMLFormulaToolFactory()224 KoM2MMLFormulaToolFactory::~KoM2MMLFormulaToolFactory()
225 {}
226
createTool(KoCanvasBase * canvas)227 KoToolBase* KoM2MMLFormulaToolFactory::createTool( KoCanvasBase* canvas )
228 {
229 return new KoM2MMLFormulaTool( canvas );
230 }
231