File indexing completed on 2024-05-12 16:34:03

0001 /* This file is part of the KDE project
0002    Copyright (C) 2011 Cyrille Berger <cberger@cberger.net>
0003 
0004    This library is free software; you can redistribute it and/or
0005    modify it under the terms of the GNU Library General Public
0006    License as published by the Free Software Foundation; either
0007    version 2 of the License, or (at your option) any later version.
0008 
0009    This library is distributed in the hope that it will be useful,
0010    but WITHOUT ANY WARRANTY; without even the implied warranty of
0011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0012    Library General Public License for more details.
0013 
0014    You should have received a copy of the GNU Library General Public License
0015    along with this library; see the file COPYING.LIB.  If not, write to
0016    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0017    Boston, MA 02110-1301, USA.
0018  */
0019 
0020 #include "KoM2MMLForumulaTool.h"
0021 
0022 #ifdef HAVE_M2MML
0023 #include <m2mml.h>
0024 #endif
0025 
0026 #include <string>
0027 
0028 #include <QComboBox>
0029 #include <QHBoxLayout>
0030 #include <QLabel>
0031 #include <QLineEdit>
0032 #include <QSpacerItem>
0033 #include <QWidget>
0034 
0035 #include <KoCanvasBase.h>
0036 #include <KoIcon.h>
0037 #include <KoXmlReader.h>
0038 
0039 #include <AnnotationElement.h>
0040 #include "FormulaDebug.h"
0041 #include "KoFormulaShape.h"
0042 #include "FormulaCommand.h"
0043 #include "FormulaCommandUpdate.h"
0044 #include "3rdparty/itexToMML/itex2MML.h"
0045 
0046 KoM2MMLFormulaTool::KoM2MMLFormulaTool(KoCanvasBase* canvas): KoToolBase(canvas), m_lineEdit(0), m_errorLabel(0), m_formulaShape(0), m_comboBox(0)
0047 {
0048 
0049 }
0050 
0051 void KoM2MMLFormulaTool::activate(KoToolBase::ToolActivation toolActivation, const QSet< KoShape* >& shapes)
0052 {
0053     Q_UNUSED(toolActivation);
0054 
0055     foreach (KoShape *shape, shapes) {
0056         m_formulaShape = dynamic_cast<KoFormulaShape*>( shape );
0057         if( m_formulaShape )
0058             break;
0059     }
0060 
0061     if( m_formulaShape == 0 )  // none found
0062     {
0063         emit done();
0064         return;
0065     }
0066     FormulaElement* element = m_formulaShape->formulaData()->formulaElement();
0067     foreach(BasicElement* elt, element->childElements())
0068     {
0069         if(elt->elementType() == Annotation)
0070         {
0071             AnnotationElement* annot = static_cast<AnnotationElement*>(elt);
0072             m_text = annot->content();
0073             m_mode = annot->attribute("mode");
0074         }
0075     }
0076     
0077     if(m_lineEdit)
0078     {
0079         m_lineEdit->setText(m_text);
0080     }
0081 }
0082 
0083 void KoM2MMLFormulaTool::mouseMoveEvent(KoPointerEvent* event)
0084 {
0085     Q_UNUSED(event);
0086 }
0087 
0088 void KoM2MMLFormulaTool::mousePressEvent(KoPointerEvent* event)
0089 {
0090     Q_UNUSED(event);
0091 }
0092 
0093 void KoM2MMLFormulaTool::mouseReleaseEvent(KoPointerEvent* event)
0094 {
0095     Q_UNUSED(event);
0096 }
0097 
0098 void KoM2MMLFormulaTool::paint(QPainter& painter, const KoViewConverter& converter)
0099 {
0100     Q_UNUSED(painter);
0101     Q_UNUSED(converter);
0102 }
0103 
0104 QWidget* KoM2MMLFormulaTool::createOptionWidget()
0105 {
0106     QWidget* widget = new QWidget;
0107     QVBoxLayout* layout = new QVBoxLayout;
0108     
0109     // Combobox to select between latex or matlab
0110     QLabel* modeLabel = new QLabel(i18n("Mode: "));
0111     m_comboBox = new QComboBox;
0112     
0113     m_comboBox->addItem(i18n("LaTeX"));
0114 #ifdef HAVE_M2MML
0115     m_comboBox->addItem(i18n("Matlab"));
0116     
0117     if(m_mode == "Matlab")
0118     {
0119         m_comboBox->setCurrentIndex(1);
0120     }
0121 #endif
0122     
0123     QHBoxLayout* hlayout = new QHBoxLayout();
0124     hlayout->addWidget(modeLabel);
0125     hlayout->addWidget(m_comboBox);
0126     layout->addLayout(hlayout);
0127     
0128     // Edit line
0129     widget->setLayout(layout);
0130     m_lineEdit = new QLineEdit(widget);
0131     layout->addWidget(m_lineEdit);
0132     
0133     // Error label
0134     m_errorLabel = new QLabel(widget);
0135     layout->addWidget(m_errorLabel);
0136     m_errorLabel->setText("");
0137     
0138     layout->addSpacerItem(new QSpacerItem(0,0));
0139     
0140     connect(m_lineEdit, SIGNAL(editingFinished()), SLOT(textEdited()));
0141     connect(m_lineEdit, SIGNAL(returnPressed()), SLOT(textEdited()));
0142     m_lineEdit->setText(m_text);
0143     
0144     return widget;
0145 }
0146 
0147 // Not sure why but the toStdString/fromStdString in QString are not accessible
0148 inline std::string QStringtoStdString(const QString& str)
0149 { const QByteArray latin1 = str.toLatin1(); return std::string(latin1.constData(), latin1.length()); }
0150 
0151 inline QString QStringfromStdString(const std::string &s)
0152 { return QString::fromLatin1(s.data(), int(s.size())); }
0153 
0154 void KoM2MMLFormulaTool::textEdited()
0155 {
0156     if(!m_formulaShape) return;
0157     if(!m_lineEdit) return;
0158     
0159 #ifdef HAVE_M2MML
0160     if(m_comboBox->currentIndex() == 1)
0161     {
0162         std::string source = QStringtoStdString(m_lineEdit->text());
0163         std::string mathml;
0164         std::string errmsg;
0165         
0166         if(m2mml(source, mathml, &errmsg))
0167         {
0168             setMathML(QStringfromStdString(mathml), "Matlab");
0169         } else {
0170             m_errorLabel->setText(QStringfromStdString(errmsg));
0171         }
0172     } else {
0173 #endif
0174         std::string source = QStringtoStdString(m_lineEdit->text());
0175         source = '$' + source + '$';
0176         char * mathml = itex2MML_parse (source.c_str(), source.size());
0177         
0178         if(mathml)
0179         {
0180             setMathML(mathml, "LaTeX");
0181             itex2MML_free_string(mathml);
0182             mathml = 0;
0183         } else {
0184             m_errorLabel->setText(i18n("Parse error."));
0185         }
0186 #ifdef HAVE_M2MML
0187     }
0188 #endif
0189 }
0190 
0191 void KoM2MMLFormulaTool::setMathML(const QString& mathml, const QString& mode)
0192 {
0193     KoXmlDocument tmpDocument;
0194     tmpDocument.setContent( QString(mathml), false, 0, 0, 0 );
0195     FormulaElement* formulaElement = new FormulaElement();     // create a new root element
0196     formulaElement->readMathML( tmpDocument.documentElement() );     // and load the new formula
0197 
0198     AnnotationElement* annot = new AnnotationElement;
0199     annot->setContent(m_lineEdit->text());
0200     annot->setAttribute("mode", mode);
0201     formulaElement->insertChild(0, annot);
0202     
0203     debugFormula << mathml;
0204     
0205     canvas()->addCommand(new FormulaCommandUpdate(m_formulaShape, new FormulaCommandLoad(m_formulaShape->formulaData(), formulaElement)));
0206     m_errorLabel->setText("");
0207 }
0208 
0209 
0210 KoM2MMLFormulaToolFactory::KoM2MMLFormulaToolFactory()
0211            : KoToolFactoryBase("KoM2MMLFormulaToolFactoryId")
0212 {
0213 #ifdef HAVE_M2MML
0214     setToolTip( i18n( "Edit formula with LaTeX/Matlab syntax" ) );
0215 #else
0216     setToolTip( i18n( "Edit formula with LaTeX syntax" ) );
0217 #endif
0218     setToolType( dynamicToolType() );
0219     setIconName(koIconName("edittext"));
0220     setPriority( 1 );
0221     setActivationShapeId( KoFormulaShapeId );
0222 }
0223 
0224 KoM2MMLFormulaToolFactory::~KoM2MMLFormulaToolFactory()
0225 {}
0226 
0227 KoToolBase* KoM2MMLFormulaToolFactory::createTool( KoCanvasBase* canvas )
0228 {
0229     return new KoM2MMLFormulaTool( canvas );
0230 }