diff --git a/src/actionbar.h b/src/actionbar.h index 07e26e92..e02d2961 100644 --- a/src/actionbar.h +++ b/src/actionbar.h @@ -1,62 +1,62 @@ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. --- Copyright (C) 2012 Martin Kuettler */ #ifndef ACTIONBAR_H #define ACTIONBAR_H #include #include class Worksheet; class WorksheetEntry; class WorksheetToolButton; class ActionBar : public QGraphicsObject { Q_OBJECT public: ActionBar(WorksheetEntry* parent); ~ActionBar() override; WorksheetToolButton* addButton(const QIcon& icon, QString toolTip, - QObject* receiver = 0, - const char* method = 0); + QObject* receiver = nullptr, + const char* method = nullptr); void addSpace(); WorksheetEntry* parentEntry(); QRectF boundingRect() const Q_DECL_OVERRIDE; void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*) Q_DECL_OVERRIDE; public Q_SLOTS: void updatePosition(); private: Worksheet* worksheet(); private: Q_PROPERTY(qreal opacity READ opacity WRITE setOpacity) QList m_buttons; qreal m_pos; qreal m_height; }; #endif // ACTIONBAR_H diff --git a/src/animation.cpp b/src/animation.cpp index f9d8e7cb..421dc802 100644 --- a/src/animation.cpp +++ b/src/animation.cpp @@ -1,113 +1,113 @@ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. --- Copyright (C) 2009 Alexander Rieder */ #include "animation.h" #include #include Animation::Animation(QObject* parent) : QObject(parent) { } Animation::~Animation() { if(m_movie) m_movie->stop(); } void Animation::setMovie(QMovie* movie) { - disconnect(0, 0, this, SLOT(movieFrameChanged())); + disconnect(nullptr, nullptr, this, SLOT(movieFrameChanged())); m_movie=movie; connect(movie, SIGNAL(frameChanged(int)), this, SLOT(movieFrameChanged())); } QMovie* Animation::movie() { return m_movie; } void Animation::setPosition(const QTextCursor& cursor) { m_position=cursor; } QTextCursor Animation::position() { return m_position; } void Animation::movieFrameChanged() { QTextCursor cursor = m_position; cursor.setPosition(m_position.position()+1, QTextCursor::KeepAnchor); const QString& text=cursor.selectedText(); if (text==QString(QChar::ObjectReplacementCharacter)) { // update a bogus property, which will trigger a paint QTextCharFormat format2; format2.setProperty(QTextFormat::UserFormat + 2, m_movie->currentFrameNumber()); cursor.mergeCharFormat(format2); } else { // we got removed from the document qDebug()<<"animation got removed"; disconnect(m_movie.data(), &QMovie::frameChanged, this, &Animation::movieFrameChanged); } } AnimationHelperItem::AnimationHelperItem( ) : m_animation(new Animation()) { } AnimationHelperItem::AnimationHelperItem(const AnimationHelperItem& other) { m_animation=other.m_animation; } AnimationHelperItem::~AnimationHelperItem() { } void AnimationHelperItem::setPosition(const QTextCursor& cursor) { m_animation->setPosition(cursor); } QTextCursor AnimationHelperItem::position() const { return m_animation->position(); } void AnimationHelperItem::setMovie(QMovie* movie) { m_animation->setMovie(movie); } QMovie* AnimationHelperItem::movie() const { return m_animation->movie(); } diff --git a/src/animation.h b/src/animation.h index d7822908..0a0e36cf 100644 --- a/src/animation.h +++ b/src/animation.h @@ -1,75 +1,75 @@ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. --- Copyright (C) 2009 Alexander Rieder */ #ifndef _ANIMATION_H #define _ANIMATION_H #include #include #include #include class QMovie; //Represents an animation placed in a QTextDocument class Animation : public QObject { Q_OBJECT public: - Animation( QObject* parent=0); + Animation( QObject* parent=nullptr); ~Animation() override; void setMovie(QMovie* movie); QMovie* movie(); void setPosition(const QTextCursor& cursor); QTextCursor position(); public Q_SLOTS: void movieFrameChanged(); private: QPointer m_movie; QTextCursor m_position; }; //Helper Object used for storing Animations in the TextCharFormat class AnimationHelperItem { public: AnimationHelperItem( ); AnimationHelperItem( const AnimationHelperItem& other); ~AnimationHelperItem(); QTextCursor position() const; void setPosition(const QTextCursor& cursor); void setMovie(QMovie* movie); QMovie* movie() const; private: QSharedPointer m_animation; }; Q_DECLARE_METATYPE(AnimationHelperItem) #endif /* _ANIMATION_H */ diff --git a/src/animationresultitem.cpp b/src/animationresultitem.cpp index 2f2f2750..066c8f23 100644 --- a/src/animationresultitem.cpp +++ b/src/animationresultitem.cpp @@ -1,167 +1,167 @@ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. --- Copyright (C) 2012 Martin Kuettler */ #include "commandentry.h" #include "animationresultitem.h" #include "lib/result.h" #include "lib/animationresult.h" #include #include #include AnimationResultItem::AnimationResultItem(QGraphicsObject* parent) - : WorksheetImageItem(parent), ResultItem(), m_height(0), m_movie(0) + : WorksheetImageItem(parent), ResultItem(), m_height(0), m_movie(nullptr) { connect(this, SIGNAL(removeResult()), parentEntry(), SLOT(removeResult())); } AnimationResultItem::~AnimationResultItem() { } double AnimationResultItem::setGeometry(double x, double y, double w) { Q_UNUSED(w); setPos(x,y); return m_height; } void AnimationResultItem::populateMenu(QMenu* menu, const QPointF& pos) { addCommonActions(this, menu); menu->addSeparator(); if (m_movie) { if (m_movie->state() == QMovie::Running) menu->addAction(QIcon::fromTheme(QLatin1String("media-playback-pause")), i18n("Pause"), this, SLOT(pauseMovie())); else menu->addAction(QIcon::fromTheme(QLatin1String("media-playback-start")), i18n("Start"), m_movie, SLOT(start())); if (m_movie->state() == QMovie::Running || m_movie->state() == QMovie::Paused) menu->addAction(QIcon::fromTheme(QLatin1String("media-playback-stop")), i18n("Stop"), this, SLOT(stopMovie())); } qDebug() << "populate Menu"; emit menuCreated(menu, mapToParent(pos)); } ResultItem* AnimationResultItem::updateFromResult(Cantor::Result* result) { QMovie* mov; switch(result->type()) { case Cantor::AnimationResult::Type: mov = static_cast(result->data().value()); setMovie(mov); return this; default: deleteLater(); return create(parentEntry(), result); } } QRectF AnimationResultItem::boundingRect() const { return QRectF(0, 0, width(), height()); } double AnimationResultItem::width() const { return WorksheetImageItem::width(); } double AnimationResultItem::height() const { return WorksheetImageItem::height(); } void AnimationResultItem::setMovie(QMovie* movie) { if (m_movie) { m_movie->disconnect(this, SLOT(updateFrame())); m_movie->disconnect(this, SLOT(updateSize())); } m_movie = movie; m_height = 0; if (m_movie) { connect(m_movie, &QMovie::frameChanged, this, &AnimationResultItem::updateFrame); connect(m_movie, &QMovie::resized, this, &AnimationResultItem::updateSize); m_movie->start(); } } void AnimationResultItem::updateFrame() { setImage(m_movie->currentImage()); worksheet()->update(mapRectToScene(boundingRect())); } void AnimationResultItem::updateSize(const QSize& size) { if (m_height != size.height()) { m_height = size.height(); emit sizeChanged(); } } void AnimationResultItem::saveResult() { Cantor::Result* res = result(); const QString& filename=QFileDialog::getSaveFileName(worksheet()->worksheetView(), i18n("Save result"), QString(), res->mimeType()); qDebug()<<"saving result to "<save(filename); } void AnimationResultItem::stopMovie() { if (m_movie) { m_movie->stop(); m_movie->jumpToFrame(0); worksheet()->update(mapRectToScene(boundingRect())); } } void AnimationResultItem::pauseMovie() { if (m_movie) m_movie->setPaused(true); } void AnimationResultItem::deleteLater() { WorksheetImageItem::deleteLater(); } CommandEntry* AnimationResultItem::parentEntry() { return qobject_cast(parentObject()); } Cantor::Result* AnimationResultItem::result() { return parentEntry()->expression()->result(); } diff --git a/src/assistants/advancedplot/advancedplotassistant.cpp b/src/assistants/advancedplot/advancedplotassistant.cpp index 4977fb26..8ee70175 100644 --- a/src/assistants/advancedplot/advancedplotassistant.cpp +++ b/src/assistants/advancedplot/advancedplotassistant.cpp @@ -1,119 +1,119 @@ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. --- Copyright (C) 2009 Alexander Rieder */ #include "advancedplotassistant.h" #include #include #include #include #include #include #include "ui_advancedplotdialog.h" #include "ui_directivecontainer.h" #include "cantor_macros.h" #include "backend.h" #include "extension.h" AdvancedPlotAssistant::AdvancedPlotAssistant(QObject* parent, QList args) : Assistant(parent) { Q_UNUSED(args) } AdvancedPlotAssistant::~AdvancedPlotAssistant() { } void AdvancedPlotAssistant::initActions() { setXMLFile(QLatin1String("cantor_advancedplot_assistant.rc")); QAction* advplot=new QAction(i18n("Advanced Plotting"), actionCollection()); actionCollection()->addAction(QLatin1String("advancedplot_assistant"), advplot); connect(advplot, &QAction::triggered, this, &AdvancedPlotAssistant::requested); } QStringList AdvancedPlotAssistant::run(QWidget* parent) { QPointer dlg=new QDialog(parent); QWidget *widget=new QWidget(dlg); Ui::AdvancedPlotAssistantBase base; base.setupUi(widget); QVBoxLayout *mainLayout = new QVBoxLayout; dlg->setLayout(mainLayout); mainLayout->addWidget(widget); base.buttonBox->button(QDialogButtonBox::Ok)->setIcon(QApplication::style()->standardIcon(QStyle::SP_DialogOkButton)); base.buttonBox->button(QDialogButtonBox::Cancel)->setIcon(QApplication::style()->standardIcon(QStyle::SP_DialogCancelButton)); connect(base.buttonBox, SIGNAL(accepted()), dlg, SLOT(accept())); connect(base.buttonBox, SIGNAL(rejected()), dlg, SLOT(reject())); //Casting the extension to correct type and checking it Cantor::AdvancedPlotExtension * plotter=dynamic_cast (backend()->extension(QLatin1String("AdvancedPlotExtension"))); - if (plotter==NULL) + if (plotter==nullptr) { qDebug()<<"Advanced plotting extension is messed up, that's a bug."; delete dlg; return QStringList(); } //Filling up the form accordingly Cantor::AdvancedPlotExtension::AcceptorBase *acceptor=dynamic_cast(plotter); QVector controls; - if (acceptor!=NULL) + if (acceptor!=nullptr) { foreach (const Cantor::AdvancedPlotExtension::AcceptorBase::widgetProc& wProc, acceptor->widgets()) { - QGroupBox *container=new QGroupBox(NULL); - Cantor::AdvancedPlotExtension::DirectiveProducer *cargo=wProc(NULL); + QGroupBox *container=new QGroupBox(nullptr); + Cantor::AdvancedPlotExtension::DirectiveProducer *cargo=wProc(nullptr); Ui::directiveContainer uicont; uicont.setupUi(container); QVBoxLayout *layout=new QVBoxLayout; layout->addWidget(cargo); container->setLayout(layout); base.directivesTabs->addTab(container,cargo->windowTitle()); controls.push_back(cargo); } } QStringList result; if( dlg->exec()) { QVector list; //FIXME lots of dynamic casts :( for (int i=0;icount();i++) { QGroupBox *group=dynamic_cast(base.directivesTabs->widget(i)); - if (group!=NULL) + if (group!=nullptr) if (group->isChecked()) list.push_back(controls[i]->produceDirective()); } result<plotFunction2d(base.expressionEdit->text(),list); qDeleteAll(list); } delete dlg; return result; } K_PLUGIN_FACTORY_WITH_JSON(advancedplotassistant, "advancedplotassistant.json", registerPlugin();) #include "advancedplotassistant.moc" diff --git a/src/backendchoosedialog.cpp b/src/backendchoosedialog.cpp index ca0f292a..5ebe9a49 100644 --- a/src/backendchoosedialog.cpp +++ b/src/backendchoosedialog.cpp @@ -1,99 +1,99 @@ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. --- Copyright (C) 2009 Alexander Rieder */ #include "backendchoosedialog.h" #include #include #include #include #include "lib/backend.h" #include "settings.h" const char* BackendChooseDialog::descriptionTemplate = I18N_NOOP("

%1

" \ "
Recommended version: %4

" \ "
%2

" \ "
See %3 for more information
"); BackendChooseDialog::BackendChooseDialog(QWidget* parent) : QDialog(parent) { QWidget* w=new QWidget(this); m_ui.setupUi(w); QGridLayout *layout = new QGridLayout; setLayout(layout); layout->addWidget(w); m_ui.backendList->setIconSize(QSize(KIconLoader::SizeMedium, KIconLoader::SizeMedium)); m_ui.backendList->setSortingEnabled(true); connect(m_ui.backendList, &QListWidget::currentItemChanged, this, &BackendChooseDialog::updateDescription); connect(m_ui.backendList, &QListWidget::itemDoubleClicked, this, &BackendChooseDialog::accept); m_ui.buttonBox->button(QDialogButtonBox::Ok); m_ui.buttonBox->button(QDialogButtonBox::Ok)->setIcon(QApplication::style()->standardIcon(QStyle::SP_DialogOkButton)); m_ui.buttonBox->button(QDialogButtonBox::Cancel)->setIcon(QApplication::style()->standardIcon(QStyle::SP_DialogCancelButton)); foreach(Cantor::Backend* backend, Cantor::Backend::availableBackends()) { if(!backend->isEnabled()) //don't show disabled backends continue; QListWidgetItem* item=new QListWidgetItem(m_ui.backendList); item->setText(backend->name()); item->setIcon(QIcon::fromTheme(backend->icon())); m_ui.backendList->addItem(item); - if(m_ui.backendList->currentItem() == 0) + if(m_ui.backendList->currentItem() == nullptr) m_ui.backendList->setCurrentItem(item); if(backend->name()==Settings::self()->defaultBackend()) m_ui.backendList->setCurrentItem(item); } connect(m_ui.buttonBox, &QDialogButtonBox::accepted, this, &BackendChooseDialog::accept); connect(m_ui.buttonBox, &QDialogButtonBox::rejected, this, &BackendChooseDialog::close); connect(this, &BackendChooseDialog::accepted, this, &BackendChooseDialog::onAccept); } BackendChooseDialog::~BackendChooseDialog() { } void BackendChooseDialog::onAccept() { m_backend=m_ui.backendList->currentItem()->text(); if(m_ui.makeDefault->isChecked()) { Settings::self()->setDefaultBackend(m_backend); Settings::self()->save(); } } void BackendChooseDialog::updateDescription() { Cantor::Backend* current=Cantor::Backend::createBackend( m_ui.backendList->currentItem()->text() ); m_ui.descriptionView->setHtml(i18n(BackendChooseDialog::descriptionTemplate, current->name(), current->description(), current->url(), current->version())); } QString BackendChooseDialog::backendName() { return m_backend; } diff --git a/src/backends/maxima/maximabackend.h b/src/backends/maxima/maximabackend.h index 3ecc15ec..a464c1b4 100644 --- a/src/backends/maxima/maximabackend.h +++ b/src/backends/maxima/maximabackend.h @@ -1,47 +1,47 @@ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. --- Copyright (C) 2009 Alexander Rieder */ #ifndef _MAXIMABACKEND_H #define _MAXIMABACKEND_H #include "backend.h" class MaximaBackend : public Cantor::Backend { Q_OBJECT public: - explicit MaximaBackend( QObject* parent = 0,const QList args = QList()); + explicit MaximaBackend( QObject* parent = nullptr,const QList args = QList()); ~MaximaBackend() override; QString id() const Q_DECL_OVERRIDE; QString version() const override; Cantor::Session *createSession() Q_DECL_OVERRIDE; Cantor::Backend::Capabilities capabilities() const Q_DECL_OVERRIDE; bool requirementsFullfilled() const Q_DECL_OVERRIDE; QUrl helpUrl() const Q_DECL_OVERRIDE; QWidget* settingsWidget(QWidget* parent) const Q_DECL_OVERRIDE; KConfigSkeleton* config() const Q_DECL_OVERRIDE; QString description() const Q_DECL_OVERRIDE; }; #endif /* _MAXIMABACKEND_H */ diff --git a/src/backends/maxima/maximaexpression.cpp b/src/backends/maxima/maximaexpression.cpp index 51d4432a..f389c74e 100644 --- a/src/backends/maxima/maximaexpression.cpp +++ b/src/backends/maxima/maximaexpression.cpp @@ -1,643 +1,643 @@ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. --- Copyright (C) 2009-2012 Alexander Rieder */ #include "maximaexpression.h" #include #include "maximasession.h" #include "textresult.h" #include "epsresult.h" #include "imageresult.h" #include "helpresult.h" #include "latexresult.h" #include "settings.h" #include #include #include #include #include #include #include #include MaximaExpression::MaximaExpression( Cantor::Session* session ) : Cantor::Expression(session) { qDebug(); - m_tempFile=0; + m_tempFile=nullptr; } MaximaExpression::~MaximaExpression() { } void MaximaExpression::evaluate() { qDebug()<<"evaluating "<deleteLater(); - m_tempFile=0; + m_tempFile=nullptr; //check if this is a ?command if(command().startsWith(QLatin1Char('?'))||command().startsWith(QLatin1String("describe("))||command().startsWith(QLatin1String("example("))) m_isHelpRequest=true; if(command().contains(QRegExp(QLatin1String("(?:plot2d|plot3d)\\s*\\([^\\)]"))) && MaximaSettings::self()->integratePlots() && !command().contains(QLatin1String("ps_file"))) { m_isPlot=true; #ifdef WITH_EPS m_tempFile=new QTemporaryFile(QDir::tempPath() + QLatin1String("/cantor_maxima-XXXXXX.eps" )); #else m_tempFile=new QTemporaryFile(QDir::tempPath() + QLatin1String("/cantor_maxima-XXXXXX.png")); #endif m_tempFile->open(); disconnect(&m_fileWatch, &KDirWatch::dirty, this, &MaximaExpression::imageChanged); m_fileWatch.addFile(m_tempFile->fileName()); connect(&m_fileWatch, &KDirWatch::dirty, this, &MaximaExpression::imageChanged); } const QString& cmd=command(); bool isComment = true; int commentLevel = 0; bool inString = false; for (int i = 0; i < cmd.size(); ++i) { if (cmd[i] == QLatin1Char('\\')) { ++i; // skip the next character if (commentLevel == 0 && !inString) { isComment = false; } } else if (cmd[i] == QLatin1Char('"') && commentLevel == 0) { inString = !inString; isComment = false; } else if (cmd.mid(i,2) == QLatin1String("/*") && !inString) { ++commentLevel; ++i; } else if (cmd.mid(i,2) == QLatin1String("*/") && !inString) { if (commentLevel == 0) { qDebug() << "Comments mismatched!"; setErrorMessage(i18n("Error: Too many */")); setStatus(Cantor::Expression::Error); return; } ++i; --commentLevel; } else if (isComment && commentLevel == 0 && !cmd[i].isSpace()) { isComment = false; } } if (commentLevel > 0) { qDebug() << "Comments mismatched!"; setErrorMessage(i18n("Error: Too many /*")); setStatus(Cantor::Expression::Error); return; } if (inString) { qDebug() << "String not closed"; setErrorMessage(i18n("Error: expected \" before ;")); setStatus(Cantor::Expression::Error); return; } if(isComment) { setStatus(Cantor::Expression::Done); return; } dynamic_cast(session())->appendExpressionToQueue(this); } void MaximaExpression::interrupt() { qDebug()<<"interrupting"; dynamic_cast(session())->interrupt(this); setStatus(Cantor::Expression::Interrupted); } QString MaximaExpression::internalCommand() { QString cmd=command(); if(m_isPlot) { if(!m_tempFile) { qDebug()<<"plotting without tempFile"; return QString(); } QString fileName = m_tempFile->fileName(); #ifdef WITH_EPS const QString psParam=QLatin1String("[gnuplot_ps_term_command, \"set size 1.0, 1.0; set term postscript eps color solid \"]"); const QString plotParameters = QLatin1String("[ps_file, \"")+ fileName+QLatin1String("\"],")+psParam; #else const QString plotParameters = QLatin1String("[gnuplot_term, \"png size 500,340\"], [gnuplot_out_file, \"")+fileName+QLatin1String("\"]"); #endif cmd.replace(QRegExp(QLatin1String("((plot2d|plot3d)\\s*\\(.*)\\)([;\n]|$)")), QLatin1String("\\1, ")+plotParameters+QLatin1String(");")); } if (!cmd.endsWith(QLatin1Char('$'))) { if (!cmd.endsWith(QLatin1String(";"))) cmd+=QLatin1Char(';'); } //replace all newlines with spaces, as maxima isn't sensitive about //whitespaces, and without newlines the whole command //is executed at once, without outputting an input //prompt after each line cmd.replace(QLatin1Char('\n'), QLatin1Char(' ')); //lisp-quiet doesn't print a prompt after the command //is completed, which causes the parsing to hang. //replace the command with the non-quiet version cmd.replace(QRegExp(QLatin1String("^:lisp-quiet")), QLatin1String(":lisp")); return cmd; } void MaximaExpression::forceDone() { qDebug()<<"forcing Expression state to DONE"; - setResult(0); + setResult(nullptr); setStatus(Cantor::Expression::Done); } void MaximaExpression::addInformation(const QString& information) { qDebug()<<"adding information"; QString inf=information; if(!inf.endsWith(QLatin1Char(';'))) inf+=QLatin1Char(';'); Cantor::Expression::addInformation(inf); dynamic_cast(session())->sendInputToProcess(inf+QLatin1Char('\n')); } //The maxima backend is modified, so that it outputs //xml-style tags around outputs, input prompts etc. //the following are some simple helper functions to faciliate parsing inline void skipWhitespaces(int* idx, const QString& txt) { for(;*idx < txt.size() && (txt[*idx]).isSpace();++(*idx)); } -QStringRef readXmlOpeningTag(int* idx, const QString& txt, bool* isComplete=0) +QStringRef readXmlOpeningTag(int* idx, const QString& txt, bool* isComplete=nullptr) { qDebug()<<"trying to read an opening tag"; if (*idx >= txt.size()) return QStringRef(); skipWhitespaces(idx, txt); if(isComplete) *isComplete=false; if(txt[*idx]!=QLatin1Char('<')) { qDebug()<<"This is NOT AN OPENING TAG."<')) { if(isComplete) *isComplete=true; break; }else length++; } return QStringRef(&txt, startIndex, length); } -QStringRef readXmlTagContent(int* idx, const QString& txt, const QStringRef& name, bool* isComplete=0) +QStringRef readXmlTagContent(int* idx, const QString& txt, const QStringRef& name, bool* isComplete=nullptr) { bool readingClosingTag=false; int contentStartIdx=*idx; int contentLength=0; int currentTagStartIdx=-1; int currentTagLength=0; if(isComplete) *isComplete=false; while(*idx0&&txt[(*idx)-1]==QLatin1Char('<')) { //remove the opening < contentLength--; currentTagStartIdx=*idx+1; currentTagLength=0; readingClosingTag=true; } else if(readingClosingTag) { if(c==QLatin1Char('>')) { const QStringRef currentTagName(&txt, currentTagStartIdx, currentTagLength); if(currentTagName==name) { //eat up the closing > ++(*idx); if(isComplete) (*isComplete)=true; break; } readingClosingTag=false; }else currentTagLength++; } else contentLength++; ++(*idx); } if(contentStartIdx+contentLength>txt.size()) { qDebug()<<"something is wrong with the content-length "<"), idx); int idx2=out.indexOf(QLatin1String(""), idx); idx1=(idx1==-1) ? out.size():idx1; idx2=(idx2==-1) ? out.size():idx2; int newIdx=qMin(idx1, idx2); if(newIdx>idx) { const QString& err=out.mid(idx, newIdx-idx); if(!err.isEmpty()) m_gotErrorContent=true; errorBuffer+=err; qDebug()<<"the unmatched part of the output is: "<0) { textBuffer.append(QLatin1String("\n")); latexBuffer.append(QLatin1String("\n")); } result=parseResult(&idx, out, textBuffer, latexBuffer); numResults++; qDebug()<<"got "< with their html code, so they won't be confused as html tags m_errorBuffer.replace( QLatin1Char('<') , QLatin1String("<")); m_errorBuffer.replace( QLatin1Char('>') , QLatin1String(">")); if(command().startsWith(QLatin1String(":lisp"))||command().startsWith(QLatin1String(":lisp-quiet"))) { if(result) { if(result->type()==Cantor::TextResult::Type) m_errorBuffer.prepend(dynamic_cast(result)->plain()+QLatin1String("\n")); else if(result->type()==Cantor::LatexResult::Type) m_errorBuffer.prepend(dynamic_cast(result)->plain()+QLatin1String("\n")); } Cantor::TextResult* result=new Cantor::TextResult(m_errorBuffer); setResult(result); setStatus(Cantor::Expression::Done); }else if(m_isHelpRequest) //Help Messages are also provided in the errorBuffer. { Cantor::HelpResult* result=new Cantor::HelpResult(m_errorBuffer); setResult(result); setStatus(Cantor::Expression::Done); }else { if(result) { qDebug()<<"result: "<toHtml(); if(result->type()==Cantor::TextResult::Type) m_errorBuffer.prepend(dynamic_cast(result)->plain()+QLatin1String("\n")); else if(result->type()==Cantor::LatexResult::Type) m_errorBuffer.prepend(dynamic_cast(result)->plain()+QLatin1String("\n")); } qDebug()<<"errorBuffer: "< with their html code, so they won't be confused as html tags text.replace( QLatin1Char('<') , QLatin1String("<")); text.replace( QLatin1Char('>') , QLatin1String(">")); QRegExp outputPromptRegexp=QRegExp(QLatin1Char('^')+MaximaSession::MaximaOutputPrompt.pattern()); int idxOfPrompt=outputPromptRegexp.indexIn(text); text.remove(idxOfPrompt, outputPromptRegexp.matchedLength()); //find the number if this output in the MaximaOutputPrompt QString prompt=outputPromptRegexp.cap(0).trimmed(); bool ok; QString idString=prompt.mid(3, prompt.length()-4); int id=idString.toInt(&ok); if(ok) setId(id); else setId(-1); qDebug()<<"prompt: "< element wasn't read completely, there //is no point in trying to render it. Use text for //incomplete results. if(!isLatexComplete ||(latexBuffer.trimmed().isEmpty()&&latex.isEmpty()) ||m_isHelpRequest||isInternal()) { qDebug()<<"using text"; result=new Cantor::TextResult(textBuffer); }else { qDebug()<<"using latex"; //strip away the latex code for the label. //it is contained in an \mbox{} call int i; int pcount=0; for(i=latex.indexOf(QLatin1String("\\mbox{"))+5;isetFormat(Cantor::TextResult::LatexFormat); } } return result; } void MaximaExpression::parseError(const QString& out) { m_errorBuffer.append(out); } void MaximaExpression::imageChanged() { qDebug()<<"the temp image has changed"; if(m_tempFile->size()>0) { #ifdef WITH_EPS setResult( new Cantor::EpsResult( QUrl::fromLocalFile(m_tempFile->fileName()) ) ); #else setResult( new Cantor::ImageResult( QUrl::fromLocalFile(m_tempFile->fileName()) ) ); #endif setStatus(Cantor::Expression::Done); } } QString MaximaExpression::additionalLatexHeaders() { return QString(); } diff --git a/src/backends/maxima/maximakeywords.cpp b/src/backends/maxima/maximakeywords.cpp index 4be5a5c0..acd682a0 100644 --- a/src/backends/maxima/maximakeywords.cpp +++ b/src/backends/maxima/maximakeywords.cpp @@ -1,1872 +1,1872 @@ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. --- Copyright (C) 2009 Alexander Rieder */ #include "maximakeywords.h" #include MaximaKeywords::MaximaKeywords() { } MaximaKeywords::~MaximaKeywords() { } MaximaKeywords* MaximaKeywords::instance() { - static MaximaKeywords* inst=0; - if(inst==0) + static MaximaKeywords* inst=nullptr; + if(inst==nullptr) { inst=new MaximaKeywords(); inst->loadKeywords(); } return inst; } void MaximaKeywords::loadKeywords() { //Begin m_variables initialization m_variables << QLatin1String("_"); m_variables << QLatin1String("__"); m_variables << QLatin1String("%"); m_variables << QLatin1String("%%"); m_variables << QLatin1String("absboxchar"); m_variables << QLatin1String("activecontexts"); m_variables << QLatin1String("additive"); m_variables << QLatin1String("algebraic"); m_variables << QLatin1String("algepsilon"); m_variables << QLatin1String("algexact"); m_variables << QLatin1String("aliases"); m_variables << QLatin1String("all_dotsimp_denoms"); m_variables << QLatin1String("allbut"); m_variables << QLatin1String("allsym"); m_variables << QLatin1String("arrays"); m_variables << QLatin1String("askexp"); m_variables << QLatin1String("assume_pos"); m_variables << QLatin1String("assume_pos_pred"); m_variables << QLatin1String("assumescalar"); m_variables << QLatin1String("atomgrad"); m_variables << QLatin1String("backsubst"); m_variables << QLatin1String("berlefact"); m_variables << QLatin1String("besselexpand"); m_variables << QLatin1String("bftorat"); m_variables << QLatin1String("bftrunc"); m_variables << QLatin1String("boxchar"); m_variables << QLatin1String("breakup"); m_variables << QLatin1String("cauchysum"); m_variables << QLatin1String("cflength"); m_variables << QLatin1String("cframe_flag"); m_variables << QLatin1String("cnonmet_flag"); m_variables << QLatin1String("context"); m_variables << QLatin1String("contexts"); m_variables << QLatin1String("cosnpiflag"); m_variables << QLatin1String("ctaypov"); m_variables << QLatin1String("ctaypt"); m_variables << QLatin1String("ctayswitch"); m_variables << QLatin1String("ctayvar"); m_variables << QLatin1String("ct_coords"); m_variables << QLatin1String("ctorsion_flag"); m_variables << QLatin1String("ctrgsimp"); m_variables << QLatin1String("current_let_rule_package"); m_variables << QLatin1String("debugmode"); m_variables << QLatin1String("default_let_rule_package"); m_variables << QLatin1String("demoivre"); m_variables << QLatin1String("dependencies"); m_variables << QLatin1String("derivabbrev"); m_variables << QLatin1String("derivsubst"); m_variables << QLatin1String("detout"); m_variables << QLatin1String("diagmetric"); m_variables << QLatin1String("dim"); m_variables << QLatin1String("dispflag"); m_variables << QLatin1String("display2d"); m_variables << QLatin1String("display_format_internal"); m_variables << QLatin1String("doallmxops"); m_variables << QLatin1String("domain"); m_variables << QLatin1String("domxexpt"); m_variables << QLatin1String("domxmxops"); m_variables << QLatin1String("domxnctimes"); m_variables << QLatin1String("dontfactor"); m_variables << QLatin1String("doscmxops"); m_variables << QLatin1String("doscmxplus"); m_variables << QLatin1String("dot0nscsimp"); m_variables << QLatin1String("dot0simp"); m_variables << QLatin1String("dot1simp"); m_variables << QLatin1String("dotassoc"); m_variables << QLatin1String("dotconstrules"); m_variables << QLatin1String("dotdistrib"); m_variables << QLatin1String("dotexptsimp"); m_variables << QLatin1String("dotident"); m_variables << QLatin1String("dotscrules"); m_variables << QLatin1String("draw_graph_program"); m_variables << QLatin1String("%edispflag"); m_variables << QLatin1String("%emode"); m_variables << QLatin1String("%enumer"); m_variables << QLatin1String("epsilon_lp"); m_variables << QLatin1String("erfflag"); m_variables << QLatin1String("error"); m_variables << QLatin1String("error_size"); m_variables << QLatin1String("error_syms"); m_variables << QLatin1String("%e_to_numlog"); m_variables << QLatin1String("evflag"); m_variables << QLatin1String("evfun"); m_variables << QLatin1String("expandwrt_denom"); m_variables << QLatin1String("expon"); m_variables << QLatin1String("exponentialize"); m_variables << QLatin1String("expop"); m_variables << QLatin1String("exptdispflag"); m_variables << QLatin1String("exptisolate"); m_variables << QLatin1String("exptsubst"); m_variables << QLatin1String("facexpand"); m_variables << QLatin1String("factlim"); m_variables << QLatin1String("factorflag"); m_variables << QLatin1String("file_output_append"); m_variables << QLatin1String("file_search_demo"); m_variables << QLatin1String("file_search_lisp"); m_variables << QLatin1String("file_search_maxima"); m_variables << QLatin1String("find_root_abs"); m_variables << QLatin1String("find_root_error"); m_variables << QLatin1String("find_root_rel"); m_variables << QLatin1String("flipflag"); m_variables << QLatin1String("float2bf"); m_variables << QLatin1String("fortindent"); m_variables << QLatin1String("fortspaces"); m_variables << QLatin1String("fpprec"); m_variables << QLatin1String("fpprintprec"); m_variables << QLatin1String("functions"); m_variables << QLatin1String("gammalim"); m_variables << QLatin1String("gdet"); m_variables << QLatin1String("genindex"); m_variables << QLatin1String("gensumnum"); m_variables << QLatin1String("GGFCFMAX"); m_variables << QLatin1String("GGFINFINITY"); m_variables << QLatin1String("globalsolve"); m_variables << QLatin1String("gradefs"); m_variables << QLatin1String("grind"); m_variables << QLatin1String("halfangles"); m_variables << QLatin1String("%iargs"); m_variables << QLatin1String("ibase"); m_variables << QLatin1String("icounter"); m_variables << QLatin1String("idummyx"); m_variables << QLatin1String("ieqnprint"); m_variables << QLatin1String("iframe_bracket_form"); m_variables << QLatin1String("igeowedge_flag"); m_variables << QLatin1String("imetric"); m_variables << QLatin1String("inchar"); m_variables << QLatin1String("infeval"); m_variables << QLatin1String("inflag"); m_variables << QLatin1String("infolists"); m_variables << QLatin1String("in_netmath"); m_variables << QLatin1String("integrate_use_rootsof"); m_variables << QLatin1String("integration_constant"); m_variables << QLatin1String("integration_constant_counter"); m_variables << QLatin1String("intfaclim"); m_variables << QLatin1String("isolate_wrt_times"); m_variables << QLatin1String("keepfloat"); m_variables << QLatin1String("labels"); m_variables << QLatin1String("letrat"); m_variables << QLatin1String("let_rule_packages"); m_variables << QLatin1String("lhospitallim"); m_variables << QLatin1String("limsubst"); m_variables << QLatin1String("linechar"); m_variables << QLatin1String("linel"); m_variables << QLatin1String("linenum"); m_variables << QLatin1String("linsolve_params"); m_variables << QLatin1String("linsolvewarn"); m_variables << QLatin1String("lispdisp"); m_variables << QLatin1String("listarith"); m_variables << QLatin1String("listconstvars"); m_variables << QLatin1String("listdummyvars"); m_variables << QLatin1String("lmxchar"); m_variables << QLatin1String("loadprint"); m_variables << QLatin1String("logabs"); m_variables << QLatin1String("logarc"); m_variables << QLatin1String("logconcoeffp"); m_variables << QLatin1String("logexpand"); m_variables << QLatin1String("lognegint"); m_variables << QLatin1String("lognumer"); m_variables << QLatin1String("logsimp"); m_variables << QLatin1String("m1pbranch"); m_variables << QLatin1String("macroexpansion"); m_variables << QLatin1String("maperror"); m_variables << QLatin1String("mapprint"); m_variables << QLatin1String("matrix_element_add"); m_variables << QLatin1String("matrix_element_mult"); m_variables << QLatin1String("matrix_element_transpose"); m_variables << QLatin1String("maxapplydepth"); m_variables << QLatin1String("maxapplyheight"); m_variables << QLatin1String("maxima_tempdir"); m_variables << QLatin1String("maxima_userdir"); m_variables << QLatin1String("maxnegex"); m_variables << QLatin1String("maxposex"); m_variables << QLatin1String("maxpsifracdenom"); m_variables << QLatin1String("maxpsifracnum"); m_variables << QLatin1String("maxpsinegint"); m_variables << QLatin1String("maxpsiposint"); m_variables << QLatin1String("maxtayorder"); m_variables << QLatin1String("method"); m_variables << QLatin1String("mode_check_errorp"); m_variables << QLatin1String("mode_checkp"); m_variables << QLatin1String("mode_check_warnp"); m_variables << QLatin1String("modulus"); m_variables << QLatin1String("multiplicities"); m_variables << QLatin1String("myoptions"); m_variables << QLatin1String("negdistrib"); m_variables << QLatin1String("negsumdispflag"); m_variables << QLatin1String("newtonepsilon"); m_variables << QLatin1String("newtonmaxiter"); m_variables << QLatin1String("niceindicespref"); m_variables << QLatin1String("nolabels"); m_variables << QLatin1String("nonegative_lp"); m_variables << QLatin1String("noundisp"); m_variables << QLatin1String("obase"); m_variables << QLatin1String("opproperties"); m_variables << QLatin1String("opsubst"); m_variables << QLatin1String("optimprefix"); m_variables << QLatin1String("optionset"); m_variables << QLatin1String("outchar"); m_variables << QLatin1String("packagefile"); m_variables << QLatin1String("partswitch"); m_variables << QLatin1String("pfeformat"); m_variables << QLatin1String("%piargs"); m_variables << QLatin1String("piece"); m_variables << QLatin1String("plot_options"); m_variables << QLatin1String("poislim"); m_variables << QLatin1String("poly_coefficient_ring"); m_variables << QLatin1String("poly_elimination_order"); m_variables << QLatin1String("poly_grobner_algorithm"); m_variables << QLatin1String("poly_grobner_debug"); m_variables << QLatin1String("poly_monomial_order"); m_variables << QLatin1String("poly_primary_elimination_order"); m_variables << QLatin1String("poly_return_term_list"); m_variables << QLatin1String("poly_secondary_elimination_order"); m_variables << QLatin1String("poly_top_reduction_only"); m_variables << QLatin1String("powerdisp"); m_variables << QLatin1String("prederror"); m_variables << QLatin1String("primep_number_of_tests"); m_variables << QLatin1String("product_use_gamma"); m_variables << QLatin1String("programmode"); m_variables << QLatin1String("prompt"); m_variables << QLatin1String("psexpand"); m_variables << QLatin1String("radexpand"); m_variables << QLatin1String("radsubstflag"); m_variables << QLatin1String("random_beta_algorithm"); m_variables << QLatin1String("random_binomial_algorithm"); m_variables << QLatin1String("random_chi2_algorithm"); m_variables << QLatin1String("random_exp_algorithm"); m_variables << QLatin1String("random_f_algorithm"); m_variables << QLatin1String("random_gamma_algorithm"); m_variables << QLatin1String("random_geometric_algorithm"); m_variables << QLatin1String("random_hypergeometric_algorithm"); m_variables << QLatin1String("random_negative_binomial_algorithm"); m_variables << QLatin1String("random_normal_algorithm"); m_variables << QLatin1String("random_poisson_algorithm"); m_variables << QLatin1String("random_student_t_algorithm"); m_variables << QLatin1String("ratalgdenom"); m_variables << QLatin1String("ratchristof"); m_variables << QLatin1String("ratdenomdivide"); m_variables << QLatin1String("rateinstein"); m_variables << QLatin1String("ratepsilon"); m_variables << QLatin1String("ratexpand"); m_variables << QLatin1String("ratfac"); m_variables << QLatin1String("ratmx"); m_variables << QLatin1String("ratprint"); m_variables << QLatin1String("ratriemann"); m_variables << QLatin1String("ratsimpexpons"); m_variables << QLatin1String("ratvars"); m_variables << QLatin1String("ratweights"); m_variables << QLatin1String("ratweyl"); m_variables << QLatin1String("ratwtlvl"); m_variables << QLatin1String("realonly"); m_variables << QLatin1String("refcheck"); m_variables << QLatin1String("rmxchar"); m_variables << QLatin1String("%rnum_list"); m_variables << QLatin1String("rombergabs"); m_variables << QLatin1String("rombergit"); m_variables << QLatin1String("rombergmin"); m_variables << QLatin1String("rombergtol"); m_variables << QLatin1String("rootsconmode"); m_variables << QLatin1String("rootsepsilon"); m_variables << QLatin1String("savedef"); m_variables << QLatin1String("savefactors"); m_variables << QLatin1String("scalarmatrixp"); m_variables << QLatin1String("setcheck"); m_variables << QLatin1String("setcheckbreak"); m_variables << QLatin1String("setval"); m_variables << QLatin1String("showtime"); m_variables << QLatin1String("simplify_products"); m_variables << QLatin1String("simpsum"); m_variables << QLatin1String("sinnpiflag"); m_variables << QLatin1String("solvedecomposes"); m_variables << QLatin1String("solveexplicit"); m_variables << QLatin1String("solvefactors"); m_variables << QLatin1String("solve_inconsistent_error"); m_variables << QLatin1String("solvenullwarn"); m_variables << QLatin1String("solveradcan"); m_variables << QLatin1String("solvetrigwarn"); m_variables << QLatin1String("sparse"); m_variables << QLatin1String("sqrtdispflag"); m_variables << QLatin1String("stardisp"); m_variables << QLatin1String("stats_numer"); m_variables << QLatin1String("stringdisp"); m_variables << QLatin1String("sublis_apply_lambda"); m_variables << QLatin1String("sumexpand"); m_variables << QLatin1String("sumsplitfact"); m_variables << QLatin1String("taylordepth"); m_variables << QLatin1String("taylor_logexpand"); m_variables << QLatin1String("taylor_order_coefficients"); m_variables << QLatin1String("taylor_truncate_polynomials"); m_variables << QLatin1String("tensorkill"); m_variables << QLatin1String("testsuite_files"); m_variables << QLatin1String("timer_devalue"); m_variables << QLatin1String("tlimswitch"); m_variables << QLatin1String("transcompile"); m_variables << QLatin1String("transrun"); m_variables << QLatin1String("tr_array_as_ref"); m_variables << QLatin1String("tr_bound_function_applyp"); m_variables << QLatin1String("tr_file_tty_messagesp"); m_variables << QLatin1String("tr_float_can_branch_complex"); m_variables << QLatin1String("tr_function_call_default"); m_variables << QLatin1String("trigexpandplus"); m_variables << QLatin1String("trigexpandtimes"); m_variables << QLatin1String("triginverses"); m_variables << QLatin1String("trigsign"); m_variables << QLatin1String("tr_numer"); m_variables << QLatin1String("tr_optimize_max_loop"); m_variables << QLatin1String("tr_semicompile"); m_variables << QLatin1String("tr_state_vars"); m_variables << QLatin1String("tr_warn_bad_function_calls"); m_variables << QLatin1String("tr_warn_fexpr"); m_variables << QLatin1String("tr_warn_meval"); m_variables << QLatin1String("tr_warn_mode"); m_variables << QLatin1String("tr_warn_undeclared"); m_variables << QLatin1String("tr_warn_undefined_variable"); m_variables << QLatin1String("tr_windy"); m_variables << QLatin1String("ttyoff"); m_variables << QLatin1String("use_fast_arrays"); m_variables << QLatin1String("values"); m_variables << QLatin1String("vect_cross"); m_variables << QLatin1String("verbose"); m_variables << QLatin1String("zerobern"); m_variables << QLatin1String("zeta%pi"); //Finish m_variables initialization //Begin m_functions initialization m_functions << QLatin1String("abasep"); m_functions << QLatin1String("abs"); m_functions << QLatin1String("absint"); m_functions << QLatin1String("absolute_real_time"); m_functions << QLatin1String("acos"); m_functions << QLatin1String("acosh"); m_functions << QLatin1String("acot"); m_functions << QLatin1String("acoth"); m_functions << QLatin1String("acsc"); m_functions << QLatin1String("acsch"); m_functions << QLatin1String("activate"); m_functions << QLatin1String("addcol"); m_functions << QLatin1String("add_edge"); m_functions << QLatin1String("add_edges"); m_functions << QLatin1String("addmatrices"); m_functions << QLatin1String("addrow"); m_functions << QLatin1String("add_vertex"); m_functions << QLatin1String("add_vertices"); m_functions << QLatin1String("adjacency_matrix"); m_functions << QLatin1String("adjoin"); m_functions << QLatin1String("adjoint"); m_functions << QLatin1String("af"); m_functions << QLatin1String("agd"); m_functions << QLatin1String("airy_ai"); m_functions << QLatin1String("airy_bi"); m_functions << QLatin1String("airy_dai"); m_functions << QLatin1String("airy_dbi"); m_functions << QLatin1String("algsys"); m_functions << QLatin1String("alg_type"); m_functions << QLatin1String("alias"); m_functions << QLatin1String("allroots"); m_functions << QLatin1String("alphacharp"); m_functions << QLatin1String("alphanumericp"); m_functions << QLatin1String("antid"); m_functions << QLatin1String("antidiff"); m_functions << QLatin1String("AntiDifference"); m_functions << QLatin1String("append"); m_functions << QLatin1String("appendfile"); m_functions << QLatin1String("apply"); m_functions << QLatin1String("apply1"); m_functions << QLatin1String("apply2"); m_functions << QLatin1String("applyb1"); m_functions << QLatin1String("apropos"); m_functions << QLatin1String("args"); m_functions << QLatin1String("arithmetic"); m_functions << QLatin1String("arithsum"); m_functions << QLatin1String("array"); m_functions << QLatin1String("arrayapply"); m_functions << QLatin1String("arrayinfo"); m_functions << QLatin1String("arraymake"); m_functions << QLatin1String("ascii"); m_functions << QLatin1String("asec"); m_functions << QLatin1String("asech"); m_functions << QLatin1String("asin"); m_functions << QLatin1String("asinh"); m_functions << QLatin1String("askinteger"); m_functions << QLatin1String("asksign"); m_functions << QLatin1String("assoc"); m_functions << QLatin1String("assoc_legendre_p"); m_functions << QLatin1String("assoc_legendre_q"); m_functions << QLatin1String("assume"); m_functions << QLatin1String("asympa"); m_functions << QLatin1String("at"); m_functions << QLatin1String("atan"); m_functions << QLatin1String("atan2"); m_functions << QLatin1String("atanh"); m_functions << QLatin1String("atensimp"); m_functions << QLatin1String("atom"); m_functions << QLatin1String("atvalue"); m_functions << QLatin1String("augcoefmatrix"); m_functions << QLatin1String("augmented_lagrangian_method"); m_functions << QLatin1String("av"); m_functions << QLatin1String("average_degree"); m_functions << QLatin1String("backtrace"); m_functions << QLatin1String("barsplot"); m_functions << QLatin1String("bashindices"); m_functions << QLatin1String("batch"); m_functions << QLatin1String("batchload"); m_functions << QLatin1String("bc2"); m_functions << QLatin1String("bdvac"); m_functions << QLatin1String("belln"); m_functions << QLatin1String("bern"); m_functions << QLatin1String("bernpoly"); m_functions << QLatin1String("bessel"); m_functions << QLatin1String("bessel_i"); m_functions << QLatin1String("bessel_j"); m_functions << QLatin1String("bessel_k"); m_functions << QLatin1String("bessel_y"); m_functions << QLatin1String("beta"); m_functions << QLatin1String("bezout"); m_functions << QLatin1String("bffac"); m_functions << QLatin1String("bfhzeta"); m_functions << QLatin1String("bfloat"); m_functions << QLatin1String("bfloatp"); m_functions << QLatin1String("bfpsi"); m_functions << QLatin1String("bfpsi0"); m_functions << QLatin1String("bfzeta"); m_functions << QLatin1String("biconected_components"); m_functions << QLatin1String("bimetric"); m_functions << QLatin1String("binomial"); m_functions << QLatin1String("bipartition"); m_functions << QLatin1String("block"); m_functions << QLatin1String("blockmatrixp"); m_functions << QLatin1String("bode_gain"); m_functions << QLatin1String("bode_phase"); m_functions << QLatin1String("bothcoef"); m_functions << QLatin1String("box"); m_functions << QLatin1String("boxplot"); m_functions << QLatin1String("break"); m_functions << QLatin1String("bug_report"); m_functions << QLatin1String("build_info"); m_functions << QLatin1String("buildq"); m_functions << QLatin1String("burn"); m_functions << QLatin1String("cabs"); m_functions << QLatin1String("canform"); m_functions << QLatin1String("canten"); m_functions << QLatin1String("cardinality"); m_functions << QLatin1String("carg"); m_functions << QLatin1String("cartan"); m_functions << QLatin1String("cartesian_product"); m_functions << QLatin1String("catch"); m_functions << QLatin1String("cbffac"); m_functions << QLatin1String("cdf_bernoulli"); m_functions << QLatin1String("cdf_beta"); m_functions << QLatin1String("cdf_binomial"); m_functions << QLatin1String("cdf_cauchy"); m_functions << QLatin1String("cdf_chi2"); m_functions << QLatin1String("cdf_continuous_uniform"); m_functions << QLatin1String("cdf_discrete_uniform"); m_functions << QLatin1String("cdf_exp"); m_functions << QLatin1String("cdf_f"); m_functions << QLatin1String("cdf_gamma"); m_functions << QLatin1String("cdf_geometric"); m_functions << QLatin1String("cdf_gumbel"); m_functions << QLatin1String("cdf_hypergeometric"); m_functions << QLatin1String("cdf_laplace"); m_functions << QLatin1String("cdf_logistic"); m_functions << QLatin1String("cdf_lognormal"); m_functions << QLatin1String("cdf_negative_binomial"); m_functions << QLatin1String("cdf_normal"); m_functions << QLatin1String("cdf_pareto"); m_functions << QLatin1String("cdf_poisson"); m_functions << QLatin1String("cdf_rank_sum"); m_functions << QLatin1String("cdf_rayleigh"); m_functions << QLatin1String("cdf_signed_rank"); m_functions << QLatin1String("cdf_student_t"); m_functions << QLatin1String("cdf_weibull"); m_functions << QLatin1String("cdisplay"); m_functions << QLatin1String("ceiling"); m_functions << QLatin1String("central_moment"); m_functions << QLatin1String("cequal"); m_functions << QLatin1String("cequalignore"); m_functions << QLatin1String("cf"); m_functions << QLatin1String("cfdisrep"); m_functions << QLatin1String("cfexpand"); m_functions << QLatin1String("cgeodesic"); m_functions << QLatin1String("cgreaterp"); m_functions << QLatin1String("cgreaterpignore"); m_functions << QLatin1String("changename"); m_functions << QLatin1String("changevar"); m_functions << QLatin1String("chaosgame"); m_functions << QLatin1String("charat"); m_functions << QLatin1String("charfun"); m_functions << QLatin1String("charfun2"); m_functions << QLatin1String("charlist"); m_functions << QLatin1String("charp"); m_functions << QLatin1String("charpoly"); m_functions << QLatin1String("chebyshev_t"); m_functions << QLatin1String("chebyshev_u"); m_functions << QLatin1String("checkdiv"); m_functions << QLatin1String("check_overlaps"); m_functions << QLatin1String("cholesky"); m_functions << QLatin1String("christof"); m_functions << QLatin1String("chromatic_index"); m_functions << QLatin1String("chromatic_number"); m_functions << QLatin1String("cint"); m_functions << QLatin1String("circulant_graph"); m_functions << QLatin1String("clear_edge_weight"); m_functions << QLatin1String("clear_rules"); m_functions << QLatin1String("clear_vertex_label"); m_functions << QLatin1String("clebsch_graph"); m_functions << QLatin1String("clessp"); m_functions << QLatin1String("clesspignore"); m_functions << QLatin1String("close"); m_functions << QLatin1String("closefile"); m_functions << QLatin1String("cmetric"); m_functions << QLatin1String("coeff"); m_functions << QLatin1String("coefmatrix"); m_functions << QLatin1String("cograd"); m_functions << QLatin1String("col"); m_functions << QLatin1String("collapse"); m_functions << QLatin1String("collectterms"); m_functions << QLatin1String("columnop"); m_functions << QLatin1String("columnspace"); m_functions << QLatin1String("columnswap"); m_functions << QLatin1String("columnvector"); m_functions << QLatin1String("combination"); m_functions << QLatin1String("combine"); m_functions << QLatin1String("comp2pui"); m_functions << QLatin1String("compare"); m_functions << QLatin1String("compfile"); m_functions << QLatin1String("compile"); m_functions << QLatin1String("compile_file"); m_functions << QLatin1String("complement_graph"); m_functions << QLatin1String("complete_bipartite_graph"); m_functions << QLatin1String("complete_graph"); m_functions << QLatin1String("components"); m_functions << QLatin1String("concan"); m_functions << QLatin1String("concat"); m_functions << QLatin1String("conjugate"); m_functions << QLatin1String("conmetderiv"); m_functions << QLatin1String("connected_components"); m_functions << QLatin1String("connect_vertices"); m_functions << QLatin1String("cons"); m_functions << QLatin1String("constantp"); m_functions << QLatin1String("constituent"); m_functions << QLatin1String("cont2part"); m_functions << QLatin1String("content"); m_functions << QLatin1String("continuous_freq"); m_functions << QLatin1String("contortion"); m_functions << QLatin1String("contour_plot"); m_functions << QLatin1String("contract"); m_functions << QLatin1String("contract_edge"); m_functions << QLatin1String("contragrad"); m_functions << QLatin1String("contrib_ode"); m_functions << QLatin1String("convert"); m_functions << QLatin1String("coord"); m_functions << QLatin1String("copy"); m_functions << QLatin1String("copy_graph"); m_functions << QLatin1String("copylist"); m_functions << QLatin1String("copymatrix"); m_functions << QLatin1String("cor"); m_functions << QLatin1String("cos"); m_functions << QLatin1String("cosh"); m_functions << QLatin1String("cot"); m_functions << QLatin1String("coth"); m_functions << QLatin1String("cov"); m_functions << QLatin1String("cov1"); m_functions << QLatin1String("covdiff"); m_functions << QLatin1String("covect"); m_functions << QLatin1String("covers"); m_functions << QLatin1String("create_graph"); m_functions << QLatin1String("create_list"); m_functions << QLatin1String("csc"); m_functions << QLatin1String("csch"); m_functions << QLatin1String("csetup"); m_functions << QLatin1String("cspline"); m_functions << QLatin1String("ctaylor"); m_functions << QLatin1String("ct_coordsys"); m_functions << QLatin1String("ctransform"); m_functions << QLatin1String("ctranspose"); m_functions << QLatin1String("cube_graph"); m_functions << QLatin1String("cunlisp"); m_functions << QLatin1String("cv"); m_functions << QLatin1String("cycle_digraph"); m_functions << QLatin1String("cycle_graph"); m_functions << QLatin1String("dblint"); m_functions << QLatin1String("deactivate"); m_functions << QLatin1String("declare"); m_functions << QLatin1String("declare_translated"); m_functions << QLatin1String("declare_weight"); m_functions << QLatin1String("decsym"); m_functions << QLatin1String("defcon"); m_functions << QLatin1String("define"); m_functions << QLatin1String("define_variable"); m_functions << QLatin1String("defint"); m_functions << QLatin1String("defmatch"); m_functions << QLatin1String("defrule"); m_functions << QLatin1String("deftaylor"); m_functions << QLatin1String("degree_sequence"); m_functions << QLatin1String("del"); m_functions << QLatin1String("delete"); m_functions << QLatin1String("deleten"); m_functions << QLatin1String("delta"); m_functions << QLatin1String("demo"); m_functions << QLatin1String("demoivre"); m_functions << QLatin1String("denom"); m_functions << QLatin1String("depends"); m_functions << QLatin1String("derivdegree"); m_functions << QLatin1String("derivlist"); m_functions << QLatin1String("describe"); m_functions << QLatin1String("desolve"); m_functions << QLatin1String("determinant"); m_functions << QLatin1String("dgauss_a"); m_functions << QLatin1String("dgauss_b"); m_functions << QLatin1String("dgeev"); m_functions << QLatin1String("dgesvd"); m_functions << QLatin1String("diag"); m_functions << QLatin1String("diagmatrix"); m_functions << QLatin1String("diag_matrix"); m_functions << QLatin1String("diagmatrixp"); m_functions << QLatin1String("diameter"); m_functions << QLatin1String("diff"); m_functions << QLatin1String("digitcharp"); m_functions << QLatin1String("dimacs_export"); m_functions << QLatin1String("dimacs_import"); m_functions << QLatin1String("dimension"); m_functions << QLatin1String("direct"); m_functions << QLatin1String("discrete_freq"); m_functions << QLatin1String("disjoin"); m_functions << QLatin1String("disjointp"); m_functions << QLatin1String("disolate"); m_functions << QLatin1String("disp"); m_functions << QLatin1String("dispcon"); m_functions << QLatin1String("dispform"); m_functions << QLatin1String("dispfun"); m_functions << QLatin1String("dispJordan"); m_functions << QLatin1String("display"); m_functions << QLatin1String("disprule"); m_functions << QLatin1String("dispterms"); m_functions << QLatin1String("distrib"); m_functions << QLatin1String("divide"); m_functions << QLatin1String("divisors"); m_functions << QLatin1String("divsum"); m_functions << QLatin1String("dkummer_m"); m_functions << QLatin1String("dkummer_u"); m_functions << QLatin1String("dlange"); m_functions << QLatin1String("dodecahedron_graph"); m_functions << QLatin1String("dotproduct"); m_functions << QLatin1String("dotsimp"); m_functions << QLatin1String("dpart"); m_functions << QLatin1String("draw"); m_functions << QLatin1String("draw2d"); m_functions << QLatin1String("draw3d"); m_functions << QLatin1String("draw_graph"); m_functions << QLatin1String("dscalar"); m_functions << QLatin1String("echelon"); m_functions << QLatin1String("edge_coloring"); m_functions << QLatin1String("edges"); m_functions << QLatin1String("eigens_by_jacobi"); m_functions << QLatin1String("eigenvalues"); m_functions << QLatin1String("eigenvectors"); m_functions << QLatin1String("eighth"); m_functions << QLatin1String("einstein"); m_functions << QLatin1String("eivals"); m_functions << QLatin1String("eivects"); m_functions << QLatin1String("elapsed_real_time"); m_functions << QLatin1String("elapsed_run_time"); m_functions << QLatin1String("ele2comp"); m_functions << QLatin1String("ele2polynome"); m_functions << QLatin1String("ele2pui"); m_functions << QLatin1String("elem"); m_functions << QLatin1String("elementp"); m_functions << QLatin1String("eliminate"); m_functions << QLatin1String("elliptic_e"); m_functions << QLatin1String("elliptic_ec"); m_functions << QLatin1String("elliptic_eu"); m_functions << QLatin1String("elliptic_f"); m_functions << QLatin1String("elliptic_kc"); m_functions << QLatin1String("elliptic_pi"); m_functions << QLatin1String("ematrix"); m_functions << QLatin1String("empty_graph"); m_functions << QLatin1String("emptyp"); m_functions << QLatin1String("endcons"); m_functions << QLatin1String("entermatrix"); m_functions << QLatin1String("entertensor"); m_functions << QLatin1String("entier"); m_functions << QLatin1String("equal"); m_functions << QLatin1String("equalp"); m_functions << QLatin1String("equiv_classes"); m_functions << QLatin1String("erf"); m_functions << QLatin1String("errcatch"); m_functions << QLatin1String("error"); m_functions << QLatin1String("errormsg"); m_functions << QLatin1String("euler"); m_functions << QLatin1String("ev"); m_functions << QLatin1String("eval_string"); m_functions << QLatin1String("evenp"); m_functions << QLatin1String("every"); m_functions << QLatin1String("evolution"); m_functions << QLatin1String("evolution2d"); m_functions << QLatin1String("evundiff"); m_functions << QLatin1String("example"); m_functions << QLatin1String("exp"); m_functions << QLatin1String("expand"); m_functions << QLatin1String("expandwrt"); m_functions << QLatin1String("expandwrt_factored"); m_functions << QLatin1String("explose"); m_functions << QLatin1String("exponentialize"); m_functions << QLatin1String("express"); m_functions << QLatin1String("expt"); m_functions << QLatin1String("exsec"); m_functions << QLatin1String("extdiff"); m_functions << QLatin1String("extract_linear_equations"); m_functions << QLatin1String("extremal_subset"); m_functions << QLatin1String("ezgcd"); m_functions << QLatin1String("f90"); m_functions << QLatin1String("facsum"); m_functions << QLatin1String("factcomb"); m_functions << QLatin1String("factor"); m_functions << QLatin1String("factorfacsum"); m_functions << QLatin1String("factorial"); m_functions << QLatin1String("factorout"); m_functions << QLatin1String("factorsum"); m_functions << QLatin1String("facts"); m_functions << QLatin1String("fast_central_elements"); m_functions << QLatin1String("fast_linsolve"); m_functions << QLatin1String("fasttimes"); m_functions << QLatin1String("featurep"); m_functions << QLatin1String("fft"); m_functions << QLatin1String("fib"); m_functions << QLatin1String("fibtophi"); m_functions << QLatin1String("fifth"); m_functions << QLatin1String("filename_merge"); m_functions << QLatin1String("file_search"); m_functions << QLatin1String("file_type"); m_functions << QLatin1String("fillarray"); m_functions << QLatin1String("findde"); m_functions << QLatin1String("find_root"); m_functions << QLatin1String("first"); m_functions << QLatin1String("fix"); m_functions << QLatin1String("flatten"); m_functions << QLatin1String("flength"); m_functions << QLatin1String("float"); m_functions << QLatin1String("floatnump"); m_functions << QLatin1String("floor"); m_functions << QLatin1String("flower_snark"); m_functions << QLatin1String("flush"); m_functions << QLatin1String("flush1deriv"); m_functions << QLatin1String("flushd"); m_functions << QLatin1String("flushnd"); m_functions << QLatin1String("forget"); m_functions << QLatin1String("fortran"); m_functions << QLatin1String("fourcos"); m_functions << QLatin1String("fourexpand"); m_functions << QLatin1String("fourier"); m_functions << QLatin1String("fourint"); m_functions << QLatin1String("fourintcos"); m_functions << QLatin1String("fourintsin"); m_functions << QLatin1String("foursimp"); m_functions << QLatin1String("foursin"); m_functions << QLatin1String("fourth"); m_functions << QLatin1String("fposition"); m_functions << QLatin1String("frame_bracket"); m_functions << QLatin1String("freeof"); m_functions << QLatin1String("freshline"); m_functions << QLatin1String("from_adjacency_matrix"); m_functions << QLatin1String("frucht_graph"); m_functions << QLatin1String("full_listify"); m_functions << QLatin1String("fullmap"); m_functions << QLatin1String("fullmapl"); m_functions << QLatin1String("fullratsimp"); m_functions << QLatin1String("fullratsubst"); m_functions << QLatin1String("fullsetify"); m_functions << QLatin1String("funcsolve"); m_functions << QLatin1String("fundef"); m_functions << QLatin1String("funmake"); m_functions << QLatin1String("funp"); m_functions << QLatin1String("gamma"); m_functions << QLatin1String("gauss_a"); m_functions << QLatin1String("gauss_b"); m_functions << QLatin1String("gaussprob"); m_functions << QLatin1String("gcd"); m_functions << QLatin1String("gcdex"); m_functions << QLatin1String("gcdivide"); m_functions << QLatin1String("gcfac"); m_functions << QLatin1String("gcfactor"); m_functions << QLatin1String("gd"); m_functions << QLatin1String("genfact"); m_functions << QLatin1String("gen_laguerre"); m_functions << QLatin1String("genmatrix"); m_functions << QLatin1String("geometric"); m_functions << QLatin1String("geometric_mean"); m_functions << QLatin1String("geosum"); m_functions << QLatin1String("get"); m_functions << QLatin1String("get_edge_weight"); m_functions << QLatin1String("get_lu_factors"); m_functions << QLatin1String("get_pixel"); m_functions << QLatin1String("get_vertex_label"); m_functions << QLatin1String("gfactor"); m_functions << QLatin1String("gfactorsum"); m_functions << QLatin1String("ggf"); m_functions << QLatin1String("girth"); m_functions << QLatin1String("global_variances"); m_functions << QLatin1String("gnuplot_close"); m_functions << QLatin1String("gnuplot_replot"); m_functions << QLatin1String("gnuplot_reset"); m_functions << QLatin1String("gnuplot_restart"); m_functions << QLatin1String("gnuplot_start"); m_functions << QLatin1String("go"); m_functions << QLatin1String("Gosper"); m_functions << QLatin1String("GosperSum"); m_functions << QLatin1String("gradef"); m_functions << QLatin1String("gramschmidt"); m_functions << QLatin1String("graph6_decode"); m_functions << QLatin1String("graph6_encode"); m_functions << QLatin1String("graph6_export"); m_functions << QLatin1String("graph6_import"); m_functions << QLatin1String("graph_center"); m_functions << QLatin1String("graph_charpoly"); m_functions << QLatin1String("graph_eigenvalues"); m_functions << QLatin1String("graph_order"); m_functions << QLatin1String("graph_periphery"); m_functions << QLatin1String("graph_product"); m_functions << QLatin1String("graph_size"); m_functions << QLatin1String("graph_union"); m_functions << QLatin1String("grid_graph"); m_functions << QLatin1String("grind"); m_functions << QLatin1String("grobner_basis"); m_functions << QLatin1String("grotzch_graph"); m_functions << QLatin1String("hamilton_cycle"); m_functions << QLatin1String("hamilton_path"); m_functions << QLatin1String("hankel"); m_functions << QLatin1String("harmonic"); m_functions << QLatin1String("harmonic_mean"); m_functions << QLatin1String("hav"); m_functions << QLatin1String("heawood_graph"); m_functions << QLatin1String("hermite"); m_functions << QLatin1String("hessian"); m_functions << QLatin1String("hilbert_matrix"); m_functions << QLatin1String("hipow"); m_functions << QLatin1String("histogram"); m_functions << QLatin1String("hodge"); m_functions << QLatin1String("horner"); m_functions << QLatin1String("ic1"); m_functions << QLatin1String("ic2"); m_functions << QLatin1String("ic_convert"); m_functions << QLatin1String("ichr1"); m_functions << QLatin1String("ichr2"); m_functions << QLatin1String("icosahedron_graph"); m_functions << QLatin1String("icurvature"); m_functions << QLatin1String("ident"); m_functions << QLatin1String("identfor"); m_functions << QLatin1String("identity"); m_functions << QLatin1String("idiff"); m_functions << QLatin1String("idim"); m_functions << QLatin1String("idummy"); m_functions << QLatin1String("ieqn"); m_functions << QLatin1String("ifactors"); m_functions << QLatin1String("iframes"); m_functions << QLatin1String("ifs"); m_functions << QLatin1String("ift"); m_functions << QLatin1String("igeodesic_coords"); m_functions << QLatin1String("ilt"); m_functions << QLatin1String("imagpart"); m_functions << QLatin1String("imetric"); m_functions << QLatin1String("implicit_derivative"); m_functions << QLatin1String("implicit_plot"); m_functions << QLatin1String("indexed_tensor"); m_functions << QLatin1String("indices"); m_functions << QLatin1String("induced_subgraph"); m_functions << QLatin1String("inferencep"); m_functions << QLatin1String("inference_result"); m_functions << QLatin1String("infix"); m_functions << QLatin1String("init_atensor"); m_functions << QLatin1String("init_ctensor"); m_functions << QLatin1String("in_neighbors"); m_functions << QLatin1String("innerproduct"); m_functions << QLatin1String("inpart"); m_functions << QLatin1String("inprod"); m_functions << QLatin1String("inrt"); m_functions << QLatin1String("integerp"); m_functions << QLatin1String("integer_partitions"); m_functions << QLatin1String("integrate"); m_functions << QLatin1String("intersect"); m_functions << QLatin1String("intersection"); m_functions << QLatin1String("intervalp"); m_functions << QLatin1String("intopois"); m_functions << QLatin1String("intosum"); m_functions << QLatin1String("invariant1"); m_functions << QLatin1String("invariant2"); m_functions << QLatin1String("inverse_jacobi_cd"); m_functions << QLatin1String("inverse_jacobi_cn"); m_functions << QLatin1String("inverse_jacobi_cs"); m_functions << QLatin1String("inverse_jacobi_dc"); m_functions << QLatin1String("inverse_jacobi_dn"); m_functions << QLatin1String("inverse_jacobi_ds"); m_functions << QLatin1String("inverse_jacobi_nc"); m_functions << QLatin1String("inverse_jacobi_nd"); m_functions << QLatin1String("inverse_jacobi_ns"); m_functions << QLatin1String("inverse_jacobi_sc"); m_functions << QLatin1String("inverse_jacobi_sd"); m_functions << QLatin1String("inverse_jacobi_sn"); m_functions << QLatin1String("invert"); m_functions << QLatin1String("invert_by_lu"); m_functions << QLatin1String("inv_mod"); m_functions << QLatin1String("is"); m_functions << QLatin1String("is_biconnected"); m_functions << QLatin1String("is_bipartite"); m_functions << QLatin1String("is_connected"); m_functions << QLatin1String("is_digraph"); m_functions << QLatin1String("is_edge_in_graph"); m_functions << QLatin1String("is_graph"); m_functions << QLatin1String("is_graph_or_digraph"); m_functions << QLatin1String("ishow"); m_functions << QLatin1String("is_isomorphic"); m_functions << QLatin1String("isolate"); m_functions << QLatin1String("isomorphism"); m_functions << QLatin1String("is_planar"); m_functions << QLatin1String("isqrt"); m_functions << QLatin1String("is_sconnected"); m_functions << QLatin1String("is_tree"); m_functions << QLatin1String("is_vertex_in_graph"); m_functions << QLatin1String("items_inference"); m_functions << QLatin1String("jacobi"); m_functions << QLatin1String("jacobian"); m_functions << QLatin1String("jacobi_cd"); m_functions << QLatin1String("jacobi_cn"); m_functions << QLatin1String("jacobi_cs"); m_functions << QLatin1String("jacobi_dc"); m_functions << QLatin1String("jacobi_dn"); m_functions << QLatin1String("jacobi_ds"); m_functions << QLatin1String("jacobi_nc"); m_functions << QLatin1String("jacobi_nd"); m_functions << QLatin1String("jacobi_ns"); m_functions << QLatin1String("jacobi_p"); m_functions << QLatin1String("jacobi_sc"); m_functions << QLatin1String("jacobi_sd"); m_functions << QLatin1String("jacobi_sn"); m_functions << QLatin1String("JF"); m_functions << QLatin1String("join"); m_functions << QLatin1String("jordan"); m_functions << QLatin1String("julia"); m_functions << QLatin1String("kdels"); m_functions << QLatin1String("kdelta"); m_functions << QLatin1String("kill"); m_functions << QLatin1String("killcontext"); m_functions << QLatin1String("kostka"); m_functions << QLatin1String("kron_delta"); m_functions << QLatin1String("kronecker_product"); m_functions << QLatin1String("kummer_m"); m_functions << QLatin1String("kummer_u"); m_functions << QLatin1String("kurtosis"); m_functions << QLatin1String("kurtosis_bernoulli"); m_functions << QLatin1String("kurtosis_beta"); m_functions << QLatin1String("kurtosis_binomial"); m_functions << QLatin1String("kurtosis_chi2"); m_functions << QLatin1String("kurtosis_continuous_uniform"); m_functions << QLatin1String("kurtosis_discrete_uniform"); m_functions << QLatin1String("kurtosis_exp"); m_functions << QLatin1String("kurtosis_f"); m_functions << QLatin1String("kurtosis_gamma"); m_functions << QLatin1String("kurtosis_geometric"); m_functions << QLatin1String("kurtosis_gumbel"); m_functions << QLatin1String("kurtosis_hypergeometric"); m_functions << QLatin1String("kurtosis_laplace"); m_functions << QLatin1String("kurtosis_logistic"); m_functions << QLatin1String("kurtosis_lognormal"); m_functions << QLatin1String("kurtosis_negative_binomial"); m_functions << QLatin1String("kurtosis_normal"); m_functions << QLatin1String("kurtosis_pareto"); m_functions << QLatin1String("kurtosis_poisson"); m_functions << QLatin1String("kurtosis_rayleigh"); m_functions << QLatin1String("kurtosis_student_t"); m_functions << QLatin1String("kurtosis_weibull"); m_functions << QLatin1String("labels"); m_functions << QLatin1String("lagrange"); m_functions << QLatin1String("laguerre"); m_functions << QLatin1String("lambda"); m_functions << QLatin1String("laplace"); m_functions << QLatin1String("laplacian_matrix"); m_functions << QLatin1String("last"); m_functions << QLatin1String("lbfgs"); m_functions << QLatin1String("lc2kdt"); m_functions << QLatin1String("lcharp"); m_functions << QLatin1String("lc_l"); m_functions << QLatin1String("lcm"); m_functions << QLatin1String("lc_u"); m_functions << QLatin1String("ldefint"); m_functions << QLatin1String("ldisp"); m_functions << QLatin1String("ldisplay"); m_functions << QLatin1String("legendre_p"); m_functions << QLatin1String("legendre_q"); m_functions << QLatin1String("leinstein"); m_functions << QLatin1String("length"); m_functions << QLatin1String("let"); m_functions << QLatin1String("letrules"); m_functions << QLatin1String("letsimp"); m_functions << QLatin1String("levi_civita"); m_functions << QLatin1String("lfreeof"); m_functions << QLatin1String("lgtreillis"); m_functions << QLatin1String("lhs"); m_functions << QLatin1String("li"); m_functions << QLatin1String("liediff"); m_functions << QLatin1String("limit"); m_functions << QLatin1String("Lindstedt"); m_functions << QLatin1String("linear"); m_functions << QLatin1String("linearinterpol"); m_functions << QLatin1String("linear_program"); m_functions << QLatin1String("line_graph"); m_functions << QLatin1String("linsolve"); m_functions << QLatin1String("listarray"); m_functions << QLatin1String("list_correlations"); m_functions << QLatin1String("listify"); m_functions << QLatin1String("list_nc_monomials"); m_functions << QLatin1String("listoftens"); m_functions << QLatin1String("listofvars"); m_functions << QLatin1String("listp"); m_functions << QLatin1String("lmax"); m_functions << QLatin1String("lmin"); m_functions << QLatin1String("load"); m_functions << QLatin1String("loadfile"); m_functions << QLatin1String("local"); m_functions << QLatin1String("locate_matrix_entry"); m_functions << QLatin1String("log"); m_functions << QLatin1String("logand"); m_functions << QLatin1String("logarc"); m_functions << QLatin1String("logcontract"); m_functions << QLatin1String("logor"); m_functions << QLatin1String("logxor"); m_functions << QLatin1String("lopow"); m_functions << QLatin1String("lorentz_gauge"); m_functions << QLatin1String("lowercasep"); m_functions << QLatin1String("lpart"); m_functions << QLatin1String("lratsubst"); m_functions << QLatin1String("lreduce"); m_functions << QLatin1String("lriemann"); m_functions << QLatin1String("lsquares_estimates"); m_functions << QLatin1String("lsquares_estimates_approximate"); m_functions << QLatin1String("lsquares_estimates_exact"); m_functions << QLatin1String("lsquares_mse"); m_functions << QLatin1String("lsquares_residual_mse"); m_functions << QLatin1String("lsquares_residuals"); m_functions << QLatin1String("lsum"); m_functions << QLatin1String("ltreillis"); m_functions << QLatin1String("lu_backsub"); m_functions << QLatin1String("lu_factor"); m_functions << QLatin1String("macroexpand"); m_functions << QLatin1String("macroexpand1"); m_functions << QLatin1String("make_array"); m_functions << QLatin1String("makebox"); m_functions << QLatin1String("makefact"); m_functions << QLatin1String("makegamma"); m_functions << QLatin1String("make_level_picture"); m_functions << QLatin1String("makelist"); m_functions << QLatin1String("makeOrders"); m_functions << QLatin1String("make_poly_continent"); m_functions << QLatin1String("make_poly_country"); m_functions << QLatin1String("make_polygon"); m_functions << QLatin1String("make_random_state"); m_functions << QLatin1String("make_rgb_picture"); m_functions << QLatin1String("makeset"); m_functions << QLatin1String("make_transform"); m_functions << QLatin1String("mandelbrot"); m_functions << QLatin1String("map"); m_functions << QLatin1String("mapatom"); m_functions << QLatin1String("maplist"); m_functions << QLatin1String("matchdeclare"); m_functions << QLatin1String("matchfix"); m_functions << QLatin1String("mat_cond"); m_functions << QLatin1String("mat_fullunblocker"); m_functions << QLatin1String("mat_function"); m_functions << QLatin1String("mat_norm"); m_functions << QLatin1String("matrix"); m_functions << QLatin1String("matrixmap"); m_functions << QLatin1String("matrixp"); m_functions << QLatin1String("matrix_size"); m_functions << QLatin1String("mattrace"); m_functions << QLatin1String("mat_trace"); m_functions << QLatin1String("mat_unblocker"); m_functions << QLatin1String("max"); m_functions << QLatin1String("max_clique"); m_functions << QLatin1String("max_degree"); m_functions << QLatin1String("max_flow"); m_functions << QLatin1String("maxi"); m_functions << QLatin1String("maximize_lp"); m_functions << QLatin1String("max_independent_set"); m_functions << QLatin1String("max_matching"); m_functions << QLatin1String("maybe"); m_functions << QLatin1String("mean"); m_functions << QLatin1String("mean_bernoulli"); m_functions << QLatin1String("mean_beta"); m_functions << QLatin1String("mean_binomial"); m_functions << QLatin1String("mean_chi2"); m_functions << QLatin1String("mean_continuous_uniform"); m_functions << QLatin1String("mean_deviation"); m_functions << QLatin1String("mean_discrete_uniform"); m_functions << QLatin1String("mean_exp"); m_functions << QLatin1String("mean_f"); m_functions << QLatin1String("mean_gamma"); m_functions << QLatin1String("mean_geometric"); m_functions << QLatin1String("mean_gumbel"); m_functions << QLatin1String("mean_hypergeometric"); m_functions << QLatin1String("mean_laplace"); m_functions << QLatin1String("mean_logistic"); m_functions << QLatin1String("mean_lognormal"); m_functions << QLatin1String("mean_negative_binomial"); m_functions << QLatin1String("mean_normal"); m_functions << QLatin1String("mean_pareto"); m_functions << QLatin1String("mean_poisson"); m_functions << QLatin1String("mean_rayleigh"); m_functions << QLatin1String("mean_student_t"); m_functions << QLatin1String("mean_weibull"); m_functions << QLatin1String("median"); m_functions << QLatin1String("median_deviation"); m_functions << QLatin1String("member"); m_functions << QLatin1String("metricexpandall"); m_functions << QLatin1String("min"); m_functions << QLatin1String("min_degree"); m_functions << QLatin1String("minfactorial"); m_functions << QLatin1String("mini"); m_functions << QLatin1String("minimalPoly"); m_functions << QLatin1String("minimize_lp"); m_functions << QLatin1String("minimum_spanning_tree"); m_functions << QLatin1String("minor"); m_functions << QLatin1String("mnewton"); m_functions << QLatin1String("mod"); m_functions << QLatin1String("mode_declare"); m_functions << QLatin1String("mode_identity"); m_functions << QLatin1String("ModeMatrix"); m_functions << QLatin1String("moebius"); m_functions << QLatin1String("mon2schur"); m_functions << QLatin1String("mono"); m_functions << QLatin1String("monomial_dimensions"); m_functions << QLatin1String("multi_elem"); m_functions << QLatin1String("multinomial"); m_functions << QLatin1String("multinomial_coeff"); m_functions << QLatin1String("multi_orbit"); m_functions << QLatin1String("multi_pui"); m_functions << QLatin1String("multsym"); m_functions << QLatin1String("multthru"); m_functions << QLatin1String("mycielski_graph"); m_functions << QLatin1String("nary"); m_functions << QLatin1String("nc_degree"); m_functions << QLatin1String("ncexpt"); m_functions << QLatin1String("ncharpoly"); m_functions << QLatin1String("negative_picture"); m_functions << QLatin1String("neighbors"); m_functions << QLatin1String("newcontext"); m_functions << QLatin1String("newdet"); m_functions << QLatin1String("new_graph"); m_functions << QLatin1String("newline"); m_functions << QLatin1String("newton"); m_functions << QLatin1String("next_prime"); m_functions << QLatin1String("niceindices"); m_functions << QLatin1String("ninth"); m_functions << QLatin1String("noncentral_moment"); m_functions << QLatin1String("nonmetricity"); m_functions << QLatin1String("nonnegintegerp"); m_functions << QLatin1String("nonscalarp"); m_functions << QLatin1String("nonzeroandfreeof"); m_functions << QLatin1String("notequal"); m_functions << QLatin1String("nounify"); m_functions << QLatin1String("nptetrad"); m_functions << QLatin1String("nroots"); m_functions << QLatin1String("nterms"); m_functions << QLatin1String("ntermst"); m_functions << QLatin1String("nthroot"); m_functions << QLatin1String("nullity"); m_functions << QLatin1String("nullspace"); m_functions << QLatin1String("num"); m_functions << QLatin1String("numbered_boundaries"); m_functions << QLatin1String("numberp"); m_functions << QLatin1String("num_distinct_partitions"); m_functions << QLatin1String("numerval"); m_functions << QLatin1String("numfactor"); m_functions << QLatin1String("num_partitions"); m_functions << QLatin1String("nusum"); m_functions << QLatin1String("odd_girth"); m_functions << QLatin1String("oddp"); m_functions << QLatin1String("ode2"); m_functions << QLatin1String("ode_check"); m_functions << QLatin1String("odelin"); m_functions << QLatin1String("op"); m_functions << QLatin1String("opena"); m_functions << QLatin1String("openr"); m_functions << QLatin1String("openw"); m_functions << QLatin1String("operatorp"); m_functions << QLatin1String("opsubst"); m_functions << QLatin1String("optimize"); m_functions << QLatin1String("orbit"); m_functions << QLatin1String("orbits"); m_functions << QLatin1String("ordergreat"); m_functions << QLatin1String("ordergreatp"); m_functions << QLatin1String("orderless"); m_functions << QLatin1String("orderlessp"); m_functions << QLatin1String("orthogonal_complement"); m_functions << QLatin1String("orthopoly_recur"); m_functions << QLatin1String("orthopoly_weight"); m_functions << QLatin1String("outermap"); m_functions << QLatin1String("out_neighbors"); m_functions << QLatin1String("outofpois"); m_functions << QLatin1String("pade"); m_functions << QLatin1String("parGosper"); m_functions << QLatin1String("parse_string"); m_functions << QLatin1String("part"); m_functions << QLatin1String("part2cont"); m_functions << QLatin1String("partfrac"); m_functions << QLatin1String("partition"); m_functions << QLatin1String("partition_set"); m_functions << QLatin1String("partpol"); m_functions << QLatin1String("path_digraph"); m_functions << QLatin1String("path_graph"); m_functions << QLatin1String("pdf_bernoulli"); m_functions << QLatin1String("pdf_beta"); m_functions << QLatin1String("pdf_binomial"); m_functions << QLatin1String("pdf_cauchy"); m_functions << QLatin1String("pdf_chi2"); m_functions << QLatin1String("pdf_continuous_uniform"); m_functions << QLatin1String("pdf_discrete_uniform"); m_functions << QLatin1String("pdf_exp"); m_functions << QLatin1String("pdf_f"); m_functions << QLatin1String("pdf_gamma"); m_functions << QLatin1String("pdf_geometric"); m_functions << QLatin1String("pdf_gumbel"); m_functions << QLatin1String("pdf_hypergeometric"); m_functions << QLatin1String("pdf_laplace"); m_functions << QLatin1String("pdf_logistic"); m_functions << QLatin1String("pdf_lognormal"); m_functions << QLatin1String("pdf_negative_binomial"); m_functions << QLatin1String("pdf_normal"); m_functions << QLatin1String("pdf_pareto"); m_functions << QLatin1String("pdf_poisson"); m_functions << QLatin1String("pdf_rank_sum"); m_functions << QLatin1String("pdf_rayleigh"); m_functions << QLatin1String("pdf_signed_rank"); m_functions << QLatin1String("pdf_student_t"); m_functions << QLatin1String("pdf_weibull"); m_functions << QLatin1String("pearson_skewness"); m_functions << QLatin1String("permanent"); m_functions << QLatin1String("permut"); m_functions << QLatin1String("permutation"); m_functions << QLatin1String("permutations"); m_functions << QLatin1String("petersen_graph"); m_functions << QLatin1String("petrov"); m_functions << QLatin1String("pickapart"); m_functions << QLatin1String("picture_equalp"); m_functions << QLatin1String("picturep"); m_functions << QLatin1String("piechart"); m_functions << QLatin1String("planar_embedding"); m_functions << QLatin1String("playback"); m_functions << QLatin1String("plog"); m_functions << QLatin1String("plot2d"); m_functions << QLatin1String("plot3d"); m_functions << QLatin1String("plotdf"); m_functions << QLatin1String("plsquares"); m_functions << QLatin1String("pochhammer"); m_functions << QLatin1String("poisdiff"); m_functions << QLatin1String("poisexpt"); m_functions << QLatin1String("poisint"); m_functions << QLatin1String("poismap"); m_functions << QLatin1String("poisplus"); m_functions << QLatin1String("poissimp"); m_functions << QLatin1String("poissubst"); m_functions << QLatin1String("poistimes"); m_functions << QLatin1String("poistrim"); m_functions << QLatin1String("polarform"); m_functions << QLatin1String("polartorect"); m_functions << QLatin1String("poly_add"); m_functions << QLatin1String("poly_buchberger"); m_functions << QLatin1String("poly_buchberger_criterion"); m_functions << QLatin1String("poly_colon_ideal"); m_functions << QLatin1String("poly_content"); m_functions << QLatin1String("polydecomp"); m_functions << QLatin1String("poly_depends_p"); m_functions << QLatin1String("poly_elimination_ideal"); m_functions << QLatin1String("poly_exact_divide"); m_functions << QLatin1String("poly_expand"); m_functions << QLatin1String("poly_expt"); m_functions << QLatin1String("poly_gcd"); m_functions << QLatin1String("poly_grobner"); m_functions << QLatin1String("poly_grobner_equal"); m_functions << QLatin1String("poly_grobner_member"); m_functions << QLatin1String("poly_grobner_subsetp"); m_functions << QLatin1String("poly_ideal_intersection"); m_functions << QLatin1String("poly_ideal_polysaturation"); m_functions << QLatin1String("poly_ideal_polysaturation1"); m_functions << QLatin1String("poly_ideal_saturation"); m_functions << QLatin1String("poly_ideal_saturation1"); m_functions << QLatin1String("poly_lcm"); m_functions << QLatin1String("poly_minimization"); m_functions << QLatin1String("polymod"); m_functions << QLatin1String("poly_multiply"); m_functions << QLatin1String("polynome2ele"); m_functions << QLatin1String("polynomialp"); m_functions << QLatin1String("poly_normal_form"); m_functions << QLatin1String("poly_normalize"); m_functions << QLatin1String("poly_normalize_list"); m_functions << QLatin1String("poly_polysaturation_extension"); m_functions << QLatin1String("poly_primitive_part"); m_functions << QLatin1String("poly_pseudo_divide"); m_functions << QLatin1String("poly_reduced_grobner"); m_functions << QLatin1String("poly_reduction"); m_functions << QLatin1String("poly_saturation_extension"); m_functions << QLatin1String("poly_s_polynomial"); m_functions << QLatin1String("poly_subtract"); m_functions << QLatin1String("polytocompanion"); m_functions << QLatin1String("potential"); m_functions << QLatin1String("power_mod"); m_functions << QLatin1String("powers"); m_functions << QLatin1String("powerseries"); m_functions << QLatin1String("powerset"); m_functions << QLatin1String("prev_prime"); m_functions << QLatin1String("primep"); m_functions << QLatin1String("print"); m_functions << QLatin1String("printf"); m_functions << QLatin1String("print_graph"); m_functions << QLatin1String("printpois"); m_functions << QLatin1String("printprops"); m_functions << QLatin1String("prodrac"); m_functions << QLatin1String("product"); m_functions << QLatin1String("properties"); m_functions << QLatin1String("propvars"); m_functions << QLatin1String("psi"); m_functions << QLatin1String("ptriangularize"); m_functions << QLatin1String("pui"); m_functions << QLatin1String("pui2comp"); m_functions << QLatin1String("pui2ele"); m_functions << QLatin1String("pui2polynome"); m_functions << QLatin1String("pui_direct"); m_functions << QLatin1String("puireduc"); m_functions << QLatin1String("put"); m_functions << QLatin1String("qput"); m_functions << QLatin1String("qrange"); m_functions << QLatin1String("quad_qag"); m_functions << QLatin1String("quad_qagi"); m_functions << QLatin1String("quad_qags"); m_functions << QLatin1String("quad_qawc"); m_functions << QLatin1String("quad_qawf"); m_functions << QLatin1String("quad_qawo"); m_functions << QLatin1String("quad_qaws"); m_functions << QLatin1String("quantile"); m_functions << QLatin1String("quantile_bernoulli"); m_functions << QLatin1String("quantile_beta"); m_functions << QLatin1String("quantile_binomial"); m_functions << QLatin1String("quantile_cauchy"); m_functions << QLatin1String("quantile_chi2"); m_functions << QLatin1String("quantile_continuous_uniform"); m_functions << QLatin1String("quantile_discrete_uniform"); m_functions << QLatin1String("quantile_exp"); m_functions << QLatin1String("quantile_f"); m_functions << QLatin1String("quantile_gamma"); m_functions << QLatin1String("quantile_geometric"); m_functions << QLatin1String("quantile_gumbel"); m_functions << QLatin1String("quantile_hypergeometric"); m_functions << QLatin1String("quantile_laplace"); m_functions << QLatin1String("quantile_logistic"); m_functions << QLatin1String("quantile_lognormal"); m_functions << QLatin1String("quantile_negative_binomial"); m_functions << QLatin1String("quantile_normal"); m_functions << QLatin1String("quantile_pareto"); m_functions << QLatin1String("quantile_poisson"); m_functions << QLatin1String("quantile_rayleigh"); m_functions << QLatin1String("quantile_student_t"); m_functions << QLatin1String("quantile_weibull"); m_functions << QLatin1String("quartile_skewness"); m_functions << QLatin1String("quit"); m_functions << QLatin1String("qunit"); m_functions << QLatin1String("quotient"); m_functions << QLatin1String("radcan"); m_functions << QLatin1String("radius"); m_functions << QLatin1String("random"); m_functions << QLatin1String("random_bernoulli"); m_functions << QLatin1String("random_beta"); m_functions << QLatin1String("random_binomial"); m_functions << QLatin1String("random_cauchy"); m_functions << QLatin1String("random_chi2"); m_functions << QLatin1String("random_continuous_uniform"); m_functions << QLatin1String("random_digraph"); m_functions << QLatin1String("random_discrete_uniform"); m_functions << QLatin1String("random_exp"); m_functions << QLatin1String("random_f"); m_functions << QLatin1String("random_gamma"); m_functions << QLatin1String("random_geometric"); m_functions << QLatin1String("random_graph"); m_functions << QLatin1String("random_graph1"); m_functions << QLatin1String("random_gumbel"); m_functions << QLatin1String("random_hypergeometric"); m_functions << QLatin1String("random_laplace"); m_functions << QLatin1String("random_logistic"); m_functions << QLatin1String("random_lognormal"); m_functions << QLatin1String("random_negative_binomial"); m_functions << QLatin1String("random_network"); m_functions << QLatin1String("random_normal"); m_functions << QLatin1String("random_pareto"); m_functions << QLatin1String("random_permutation"); m_functions << QLatin1String("random_poisson"); m_functions << QLatin1String("random_rayleigh"); m_functions << QLatin1String("random_regular_graph"); m_functions << QLatin1String("random_student_t"); m_functions << QLatin1String("random_tournament"); m_functions << QLatin1String("random_tree"); m_functions << QLatin1String("random_weibull"); m_functions << QLatin1String("range"); m_functions << QLatin1String("rank"); m_functions << QLatin1String("rat"); m_functions << QLatin1String("ratcoef"); m_functions << QLatin1String("ratdenom"); m_functions << QLatin1String("ratdiff"); m_functions << QLatin1String("ratdisrep"); m_functions << QLatin1String("ratexpand"); m_functions << QLatin1String("rational"); m_functions << QLatin1String("rationalize"); m_functions << QLatin1String("ratnumer"); m_functions << QLatin1String("ratnump"); m_functions << QLatin1String("ratp"); m_functions << QLatin1String("ratsimp"); m_functions << QLatin1String("ratsubst"); m_functions << QLatin1String("ratvars"); m_functions << QLatin1String("ratweight"); m_functions << QLatin1String("read"); m_functions << QLatin1String("read_hashed_array"); m_functions << QLatin1String("readline"); m_functions << QLatin1String("read_lisp_array"); m_functions << QLatin1String("read_list"); m_functions << QLatin1String("read_matrix"); m_functions << QLatin1String("read_maxima_array"); m_functions << QLatin1String("read_nested_list"); m_functions << QLatin1String("readonly"); m_functions << QLatin1String("read_xpm"); m_functions << QLatin1String("realpart"); m_functions << QLatin1String("realroots"); m_functions << QLatin1String("rearray"); m_functions << QLatin1String("rectform"); m_functions << QLatin1String("recttopolar"); m_functions << QLatin1String("rediff"); m_functions << QLatin1String("reduce_consts"); m_functions << QLatin1String("reduce_order"); m_functions << QLatin1String("region_boundaries"); m_functions << QLatin1String("rem"); m_functions << QLatin1String("remainder"); m_functions << QLatin1String("remarray"); m_functions << QLatin1String("rembox"); m_functions << QLatin1String("remcomps"); m_functions << QLatin1String("remcon"); m_functions << QLatin1String("remcoord"); m_functions << QLatin1String("remfun"); m_functions << QLatin1String("remfunction"); m_functions << QLatin1String("remlet"); m_functions << QLatin1String("remove"); m_functions << QLatin1String("remove_edge"); m_functions << QLatin1String("remove_vertex"); m_functions << QLatin1String("rempart"); m_functions << QLatin1String("remrule"); m_functions << QLatin1String("remsym"); m_functions << QLatin1String("remvalue"); m_functions << QLatin1String("rename"); m_functions << QLatin1String("reset"); m_functions << QLatin1String("residue"); m_functions << QLatin1String("resolvante"); m_functions << QLatin1String("resolvante_alternee1"); m_functions << QLatin1String("resolvante_bipartite"); m_functions << QLatin1String("resolvante_diedrale"); m_functions << QLatin1String("resolvante_klein"); m_functions << QLatin1String("resolvante_klein3"); m_functions << QLatin1String("resolvante_produit_sym"); m_functions << QLatin1String("resolvante_unitaire"); m_functions << QLatin1String("resolvante_vierer"); m_functions << QLatin1String("rest"); m_functions << QLatin1String("resultant"); m_functions << QLatin1String("return"); m_functions << QLatin1String("reveal"); m_functions << QLatin1String("reverse"); m_functions << QLatin1String("revert"); m_functions << QLatin1String("revert2"); m_functions << QLatin1String("rgb2level"); m_functions << QLatin1String("rhs"); m_functions << QLatin1String("ricci"); m_functions << QLatin1String("riemann"); m_functions << QLatin1String("rinvariant"); m_functions << QLatin1String("risch"); m_functions << QLatin1String("rk"); m_functions << QLatin1String("rncombine"); m_functions << QLatin1String("romberg"); m_functions << QLatin1String("room"); m_functions << QLatin1String("rootscontract"); m_functions << QLatin1String("row"); m_functions << QLatin1String("rowop"); m_functions << QLatin1String("rowswap"); m_functions << QLatin1String("rreduce"); m_functions << QLatin1String("run_testsuite"); m_functions << QLatin1String("save"); m_functions << QLatin1String("scalarp"); m_functions << QLatin1String("scaled_bessel_i"); m_functions << QLatin1String("scaled_bessel_i0"); m_functions << QLatin1String("scaled_bessel_i1"); m_functions << QLatin1String("scalefactors"); m_functions << QLatin1String("scanmap"); m_functions << QLatin1String("scatterplot"); m_functions << QLatin1String("schur2comp"); m_functions << QLatin1String("sconcat"); m_functions << QLatin1String("scopy"); m_functions << QLatin1String("scsimp"); m_functions << QLatin1String("scurvature"); m_functions << QLatin1String("sdowncase"); m_functions << QLatin1String("sec"); m_functions << QLatin1String("sech"); m_functions << QLatin1String("second"); m_functions << QLatin1String("sequal"); m_functions << QLatin1String("sequalignore"); m_functions << QLatin1String("setdifference"); m_functions << QLatin1String("set_edge_weight"); m_functions << QLatin1String("setelmx"); m_functions << QLatin1String("setequalp"); m_functions << QLatin1String("setify"); m_functions << QLatin1String("setp"); m_functions << QLatin1String("set_partitions"); m_functions << QLatin1String("set_plot_option"); m_functions << QLatin1String("set_random_state"); m_functions << QLatin1String("setunits"); m_functions << QLatin1String("setup_autoload"); m_functions << QLatin1String("set_up_dot_simplifications"); m_functions << QLatin1String("set_vertex_label"); m_functions << QLatin1String("seventh"); m_functions << QLatin1String("sexplode"); m_functions << QLatin1String("sf"); m_functions << QLatin1String("shortest_path"); m_functions << QLatin1String("show"); m_functions << QLatin1String("showcomps"); m_functions << QLatin1String("showratvars"); m_functions << QLatin1String("sign"); m_functions << QLatin1String("signum"); m_functions << QLatin1String("similaritytransform"); m_functions << QLatin1String("simple_linear_regression"); m_functions << QLatin1String("simplify_sum"); m_functions << QLatin1String("simplode"); m_functions << QLatin1String("simpmetderiv"); m_functions << QLatin1String("simtran"); m_functions << QLatin1String("sin"); m_functions << QLatin1String("sinh"); m_functions << QLatin1String("sinsert"); m_functions << QLatin1String("sinvertcase"); m_functions << QLatin1String("sixth"); m_functions << QLatin1String("skewness"); m_functions << QLatin1String("skewness_bernoulli"); m_functions << QLatin1String("skewness_beta"); m_functions << QLatin1String("skewness_binomial"); m_functions << QLatin1String("skewness_chi2"); m_functions << QLatin1String("skewness_continuous_uniform"); m_functions << QLatin1String("skewness_discrete_uniform"); m_functions << QLatin1String("skewness_exp"); m_functions << QLatin1String("skewness_f"); m_functions << QLatin1String("skewness_gamma"); m_functions << QLatin1String("skewness_geometric"); m_functions << QLatin1String("skewness_gumbel"); m_functions << QLatin1String("skewness_hypergeometric"); m_functions << QLatin1String("skewness_laplace"); m_functions << QLatin1String("skewness_logistic"); m_functions << QLatin1String("skewness_lognormal"); m_functions << QLatin1String("skewness_negative_binomial"); m_functions << QLatin1String("skewness_normal"); m_functions << QLatin1String("skewness_pareto"); m_functions << QLatin1String("skewness_poisson"); m_functions << QLatin1String("skewness_rayleigh"); m_functions << QLatin1String("skewness_student_t"); m_functions << QLatin1String("skewness_weibull"); m_functions << QLatin1String("slength"); m_functions << QLatin1String("smake"); m_functions << QLatin1String("smismatch"); m_functions << QLatin1String("solve"); m_functions << QLatin1String("solve_rec"); m_functions << QLatin1String("solve_rec_rat"); m_functions << QLatin1String("some"); m_functions << QLatin1String("somrac"); m_functions << QLatin1String("sort"); m_functions << QLatin1String("sparse6_decode"); m_functions << QLatin1String("sparse6_encode"); m_functions << QLatin1String("sparse6_export"); m_functions << QLatin1String("sparse6_import"); m_functions << QLatin1String("specint"); m_functions << QLatin1String("spherical_bessel_j"); m_functions << QLatin1String("spherical_bessel_y"); m_functions << QLatin1String("spherical_hankel1"); m_functions << QLatin1String("spherical_hankel2"); m_functions << QLatin1String("spherical_harmonic"); m_functions << QLatin1String("splice"); m_functions << QLatin1String("split"); m_functions << QLatin1String("sposition"); m_functions << QLatin1String("sprint"); m_functions << QLatin1String("sqfr"); m_functions << QLatin1String("sqrt"); m_functions << QLatin1String("sqrtdenest"); m_functions << QLatin1String("sremove"); m_functions << QLatin1String("sremovefirst"); m_functions << QLatin1String("sreverse"); m_functions << QLatin1String("ssearch"); m_functions << QLatin1String("ssort"); m_functions << QLatin1String("sstatus"); m_functions << QLatin1String("ssubst"); m_functions << QLatin1String("ssubstfirst"); m_functions << QLatin1String("staircase"); m_functions << QLatin1String("status"); m_functions << QLatin1String("std"); m_functions << QLatin1String("std1"); m_functions << QLatin1String("std_bernoulli"); m_functions << QLatin1String("std_beta"); m_functions << QLatin1String("std_binomial"); m_functions << QLatin1String("std_chi2"); m_functions << QLatin1String("std_continuous_uniform"); m_functions << QLatin1String("std_discrete_uniform"); m_functions << QLatin1String("std_exp"); m_functions << QLatin1String("std_f"); m_functions << QLatin1String("std_gamma"); m_functions << QLatin1String("std_geometric"); m_functions << QLatin1String("std_gumbel"); m_functions << QLatin1String("std_hypergeometric"); m_functions << QLatin1String("std_laplace"); m_functions << QLatin1String("std_logistic"); m_functions << QLatin1String("std_lognormal"); m_functions << QLatin1String("std_negative_binomial"); m_functions << QLatin1String("std_normal"); m_functions << QLatin1String("std_pareto"); m_functions << QLatin1String("std_poisson"); m_functions << QLatin1String("std_rayleigh"); m_functions << QLatin1String("std_student_t"); m_functions << QLatin1String("std_weibull"); m_functions << QLatin1String("stirling"); m_functions << QLatin1String("stirling1"); m_functions << QLatin1String("stirling2"); m_functions << QLatin1String("strim"); m_functions << QLatin1String("striml"); m_functions << QLatin1String("strimr"); m_functions << QLatin1String("string"); m_functions << QLatin1String("stringout"); m_functions << QLatin1String("stringp"); m_functions << QLatin1String("strong_components"); m_functions << QLatin1String("sublis"); m_functions << QLatin1String("sublist"); m_functions << QLatin1String("sublist_indices"); m_functions << QLatin1String("submatrix"); m_functions << QLatin1String("subsample"); m_functions << QLatin1String("subset"); m_functions << QLatin1String("subsetp"); m_functions << QLatin1String("subst"); m_functions << QLatin1String("substinpart"); m_functions << QLatin1String("substpart"); m_functions << QLatin1String("substring"); m_functions << QLatin1String("subvar"); m_functions << QLatin1String("subvarp"); m_functions << QLatin1String("sum"); m_functions << QLatin1String("sumcontract"); m_functions << QLatin1String("summand_to_rec"); m_functions << QLatin1String("supcase"); m_functions << QLatin1String("supcontext"); m_functions << QLatin1String("symbolp"); m_functions << QLatin1String("symmdifference"); m_functions << QLatin1String("symmetric"); m_functions << QLatin1String("system"); m_functions << QLatin1String("take_channel"); m_functions << QLatin1String("take_inference"); m_functions << QLatin1String("tan"); m_functions << QLatin1String("tanh"); m_functions << QLatin1String("taylor"); m_functions << QLatin1String("taylorinfo"); m_functions << QLatin1String("taylorp"); m_functions << QLatin1String("taylor_simplifier"); m_functions << QLatin1String("taytorat"); m_functions << QLatin1String("tcl_output"); m_functions << QLatin1String("tcontract"); m_functions << QLatin1String("tellrat"); m_functions << QLatin1String("tellsimp"); m_functions << QLatin1String("tellsimpafter"); m_functions << QLatin1String("tentex"); m_functions << QLatin1String("tenth"); m_functions << QLatin1String("test_mean"); m_functions << QLatin1String("test_means_difference"); m_functions << QLatin1String("test_normality"); m_functions << QLatin1String("test_rank_sum"); m_functions << QLatin1String("test_sign"); m_functions << QLatin1String("test_signed_rank"); m_functions << QLatin1String("test_variance"); m_functions << QLatin1String("test_variance_ratio"); m_functions << QLatin1String("tex"); m_functions << QLatin1String("texput"); m_functions << QLatin1String("%th"); m_functions << QLatin1String("third"); m_functions << QLatin1String("throw"); m_functions << QLatin1String("time"); m_functions << QLatin1String("timedate"); m_functions << QLatin1String("timer"); m_functions << QLatin1String("timer_info"); m_functions << QLatin1String("tldefint"); m_functions << QLatin1String("tlimit"); m_functions << QLatin1String("todd_coxeter"); m_functions << QLatin1String("toeplitz"); m_functions << QLatin1String("tokens"); m_functions << QLatin1String("to_lisp"); m_functions << QLatin1String("topological_sort"); m_functions << QLatin1String("totaldisrep"); m_functions << QLatin1String("totalfourier"); m_functions << QLatin1String("totient"); m_functions << QLatin1String("tpartpol"); m_functions << QLatin1String("trace"); m_functions << QLatin1String("tracematrix"); m_functions << QLatin1String("trace_options"); m_functions << QLatin1String("translate"); m_functions << QLatin1String("translate_file"); m_functions << QLatin1String("transpose"); m_functions << QLatin1String("tree_reduce"); m_functions << QLatin1String("treillis"); m_functions << QLatin1String("treinat"); m_functions << QLatin1String("triangularize"); m_functions << QLatin1String("trigexpand"); m_functions << QLatin1String("trigrat"); m_functions << QLatin1String("trigreduce"); m_functions << QLatin1String("trigsimp"); m_functions << QLatin1String("trunc"); m_functions << QLatin1String("tr_warnings_get"); m_functions << QLatin1String("ueivects"); m_functions << QLatin1String("uforget"); m_functions << QLatin1String("ultraspherical"); m_functions << QLatin1String("underlying_graph"); m_functions << QLatin1String("undiff"); m_functions << QLatin1String("union"); m_functions << QLatin1String("unique"); m_functions << QLatin1String("uniteigenvectors"); m_functions << QLatin1String("unit_step"); m_functions << QLatin1String("unitvector"); m_functions << QLatin1String("unknown"); m_functions << QLatin1String("unorder"); m_functions << QLatin1String("unsum"); m_functions << QLatin1String("untellrat"); m_functions << QLatin1String("untimer"); m_functions << QLatin1String("untrace"); m_functions << QLatin1String("uppercasep"); m_functions << QLatin1String("uricci"); m_functions << QLatin1String("uriemann"); m_functions << QLatin1String("uvect"); m_functions << QLatin1String("vandermonde_matrix"); m_functions << QLatin1String("var"); m_functions << QLatin1String("var1"); m_functions << QLatin1String("var_bernoulli"); m_functions << QLatin1String("var_beta"); m_functions << QLatin1String("var_binomial"); m_functions << QLatin1String("var_chi2"); m_functions << QLatin1String("var_continuous_uniform"); m_functions << QLatin1String("var_discrete_uniform"); m_functions << QLatin1String("var_exp"); m_functions << QLatin1String("var_f"); m_functions << QLatin1String("var_gamma"); m_functions << QLatin1String("var_geometric"); m_functions << QLatin1String("var_gumbel"); m_functions << QLatin1String("var_hypergeometric"); m_functions << QLatin1String("var_laplace"); m_functions << QLatin1String("var_logistic"); m_functions << QLatin1String("var_lognormal"); m_functions << QLatin1String("var_negative_binomial"); m_functions << QLatin1String("var_normal"); m_functions << QLatin1String("var_pareto"); m_functions << QLatin1String("var_poisson"); m_functions << QLatin1String("var_rayleigh"); m_functions << QLatin1String("var_student_t"); m_functions << QLatin1String("var_weibull"); m_functions << QLatin1String("vectorpotential"); m_functions << QLatin1String("vectorsimp"); m_functions << QLatin1String("verbify"); m_functions << QLatin1String("vers"); m_functions << QLatin1String("vertex_coloring"); m_functions << QLatin1String("vertex_degree"); m_functions << QLatin1String("vertex_distance"); m_functions << QLatin1String("vertex_eccentricity"); m_functions << QLatin1String("vertex_in_degree"); m_functions << QLatin1String("vertex_out_degree"); m_functions << QLatin1String("vertices"); m_functions << QLatin1String("vertices_to_cycle"); m_functions << QLatin1String("vertices_to_path"); m_functions << QLatin1String("weyl"); m_functions << QLatin1String("wheel_graph"); m_functions << QLatin1String("with_stdout"); m_functions << QLatin1String("write_data"); m_functions << QLatin1String("writefile"); m_functions << QLatin1String("wronskian"); m_functions << QLatin1String("xgraph_curves"); m_functions << QLatin1String("xreduce"); m_functions << QLatin1String("xthru"); m_functions << QLatin1String("Zeilberger"); m_functions << QLatin1String("zeroequiv"); m_functions << QLatin1String("zerofor"); m_functions << QLatin1String("zeromatrix"); m_functions << QLatin1String("zeromatrixp"); m_functions << QLatin1String("zeta"); m_functions << QLatin1String("zlange"); //Finish m_functions initialization //Begin m_keywords initialization m_keywords << QLatin1String("and"); m_keywords << QLatin1String("do"); m_keywords << QLatin1String("else"); m_keywords << QLatin1String("elseif"); m_keywords << QLatin1String("false"); m_keywords << QLatin1String("for"); m_keywords << QLatin1String("if"); m_keywords << QLatin1String("in"); m_keywords << QLatin1String("not"); m_keywords << QLatin1String("or"); m_keywords << QLatin1String("step"); m_keywords << QLatin1String("then"); m_keywords << QLatin1String("thru"); m_keywords << QLatin1String("true"); m_keywords << QLatin1String("while"); //Finish m_keywords initialization } const QStringList& MaximaKeywords::variables() const { return m_variables; } const QStringList& MaximaKeywords::functions() const { return m_functions; } const QStringList& MaximaKeywords::keywords() const { return m_keywords; } diff --git a/src/backends/maxima/maximasession.cpp b/src/backends/maxima/maximasession.cpp index d4814b31..ed803264 100644 --- a/src/backends/maxima/maximasession.cpp +++ b/src/backends/maxima/maximasession.cpp @@ -1,447 +1,447 @@ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. --- Copyright (C) 2009-2012 Alexander Rieder */ #include "maximasession.h" #include "maximaexpression.h" #include "maximacompletionobject.h" #include "maximasyntaxhelpobject.h" #include "maximahighlighter.h" #include "maximavariablemodel.h" #include "result.h" #include "settings.h" #include #include #include #include #include #ifdef Q_OS_WIN #include #else #include #include #endif //NOTE: the \\s in the expressions is needed, because Maxima seems to sometimes insert newlines/spaces between the letters //maybe this is caused by some behaviour if the Prompt is split into multiple "readStdout" calls //the Expressions are encapsulated in () to allow capturing for the text const QRegExp MaximaSession::MaximaOutputPrompt=QRegExp(QLatin1String("(\\(\\s*%\\s*O\\s*[0-9\\s]*\\))")); //Text, maxima outputs, before any output static QString initCmd=QLatin1String(":lisp($load \"%1\")"); MaximaSession::MaximaSession( Cantor::Backend* backend ) : Session(backend), m_initState(MaximaSession::NotInitialized), - m_process(0), + m_process(nullptr), m_justRestarted(false), m_variableModel(new MaximaVariableModel(this)) { } MaximaSession::~MaximaSession() { } void MaximaSession::login() { qDebug()<<"login"; emit loginStarted(); if (m_process) m_process->deleteLater(); #ifndef Q_OS_WIN m_process=new KPtyProcess(this); m_process->setPtyChannels(KPtyProcess::StdinChannel|KPtyProcess::StdoutChannel); m_process->pty()->setEcho(false); connect(m_process->pty(), SIGNAL(readyRead()), this, SLOT(readStdOut())); #else m_process=new KProcess(this); m_process->setOutputChannelMode(KProcess::SeparateChannels); connect(m_process, SIGNAL(readyReadStandardOutput()), this, SLOT(readStdOut())); #endif m_process->setProgram(MaximaSettings::self()->path().toLocalFile()); m_process->start(); connect(m_process, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(restartMaxima())); connect(m_process, SIGNAL(readyReadStandardError()), this, SLOT(readStdErr())); connect(m_process, SIGNAL(error(QProcess::ProcessError)), this, SLOT(reportProcessError(QProcess::ProcessError))); const QString initFile = QStandardPaths::locate(QStandardPaths::GenericDataLocation, QLatin1String("cantor/maximabackend/cantor-initmaxima.lisp")); write(initCmd.arg(initFile)); Cantor::Expression* expr=evaluateExpression(QLatin1String("print(____END_OF_INIT____);"), Cantor::Expression::DeleteOnFinish); expr->setInternal(true); //check if we actually landed in the queue and there wasn't some //error beforehand instead if(m_expressionQueue.contains(dynamic_cast(expr))) { //move this expression to the front m_expressionQueue.prepend(m_expressionQueue.takeLast()); } //reset the typesetting state setTypesettingEnabled(isTypesettingEnabled()); m_initState=MaximaSession::Initializing; if(!MaximaSettings::self()->autorunScripts().isEmpty()){ QString autorunScripts = MaximaSettings::self()->autorunScripts().join(QLatin1String("\n")); evaluateExpression(autorunScripts, MaximaExpression::DeleteOnFinish); } runFirstExpression(); emit loginDone(); } void MaximaSession::logout() { qDebug()<<"logout"; if(!m_process) return; disconnect(m_process, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(restartMaxima())); if(status()==Cantor::Session::Done) { write(QLatin1String("quit();\n")); #ifdef Q_OS_WIN //Give maxima time to clean up qDebug()<<"waiting for maxima to finish"; m_process->waitForFinished(); #endif } else { m_expressionQueue.clear(); } //if it is still running, kill just kill it if(m_process->state()!=QProcess::NotRunning) { m_process->kill(); } qDebug()<<"done logging out"; delete m_process; - m_process=0; + m_process=nullptr; qDebug()<<"destroyed maxima"; m_expressionQueue.clear(); } Cantor::Expression* MaximaSession::evaluateExpression(const QString& cmd, Cantor::Expression::FinishingBehavior behave) { MaximaExpression* expr = new MaximaExpression(this); expr->setFinishingBehavior(behave); expr->setCommand(cmd); expr->evaluate(); return expr; } void MaximaSession::appendExpressionToQueue(MaximaExpression* expr) { m_expressionQueue.append(expr); qDebug()<<"queue: "<readAllStandardError()); if(m_expressionQueue.size()>0) { MaximaExpression* expr=m_expressionQueue.first(); expr->parseError(out); } } void MaximaSession::readStdOut() { qDebug()<<"reading stdOut"; if (!m_process) return; #ifndef Q_OS_WIN QString out=QLatin1String(m_process->pty()->readAll()); #else QString out=m_process->readAllStandardOutput(); #endif out.remove(QLatin1Char('\r')); qDebug()<<"out: "<parseOutput(m_cache); else parsingSuccessful=false; if(parsingSuccessful) { qDebug()<<"parsing successful. dropping "<setInternal(true); //TODO: what for? connect(e, SIGNAL(statusChanged(Cantor::Expression::Status)), this, SIGNAL(ready())); } void MaximaSession::reportProcessError(QProcess::ProcessError e) { qDebug()<<"process error"<command().contains( QLatin1String("____END_OF_INIT____"))) { qDebug()<<"initialized"; m_expressionQueue.removeFirst(); m_initState=MaximaSession::Initialized; m_cache.clear(); runFirstExpression(); //QTimer::singleShot(0, this, SLOT(killLabels())); killLabels(); changeStatus(Cantor::Session::Done); return; } if(status!=Cantor::Expression::Computing) //The session is ready for the next command { qDebug()<<"expression finished"; disconnect(expression, SIGNAL(statusChanged(Cantor::Expression::Status)), this, SLOT(currentExpressionChangedStatus(Cantor::Expression::Status))); qDebug()<<"running next command"; m_expressionQueue.removeFirst(); if(m_expressionQueue.isEmpty()) { //if we are done with all the commands in the queue, //use the opportunity to update the variablemodel (if the last command wasn't already an update, as infinite loops aren't fun) QRegExp exp=QRegExp(QRegExp::escape(MaximaVariableModel::inspectCommand).arg(QLatin1String("(values|functions)"))); QRegExp exp2=QRegExp(QRegExp::escape(MaximaVariableModel::variableInspectCommand).arg(QLatin1String("(values|functions)"))); if(MaximaSettings::variableManagement()&&!exp.exactMatch(expression->command())&&!exp2.exactMatch(expression->command())) { m_variableModel->checkForNewFunctions(); m_variableModel->checkForNewVariables(); }else { changeStatus(Cantor::Session::Done); } }else { runFirstExpression(); } } } void MaximaSession::runFirstExpression() { if(m_initState==MaximaSession::NotInitialized) { qDebug()<<"not ready to run expression"; return; } qDebug()<<"running next expression"; if (!m_process) return; if(!m_expressionQueue.isEmpty()) { MaximaExpression* expr=m_expressionQueue.first(); QString command=expr->internalCommand(); connect(expr, SIGNAL(statusChanged(Cantor::Expression::Status)), this, SLOT(currentExpressionChangedStatus(Cantor::Expression::Status))); if(command.isEmpty()) { qDebug()<<"empty command"; expr->forceDone(); } else { m_cache.clear(); write(command + QLatin1Char('\n')); } } } void MaximaSession::interrupt() { if(!m_expressionQueue.isEmpty()) m_expressionQueue.first()->interrupt(); m_expressionQueue.clear(); changeStatus(Cantor::Session::Done); } void MaximaSession::interrupt(MaximaExpression* expr) { Q_ASSERT(!m_expressionQueue.isEmpty()); if(expr==m_expressionQueue.first()) { - disconnect(expr, 0, this, 0); + disconnect(expr, nullptr, this, nullptr); //TODO for non unix platforms sending signals probably won't work const int pid=m_process->pid(); kill(pid, SIGINT); qDebug()<<"done interrupting"; }else { m_expressionQueue.removeAll(expr); } } void MaximaSession::sendInputToProcess(const QString& input) { qDebug()<<"WARNING: use this method only if you know what you're doing. Use evaluateExpression to run commands"; qDebug()<<"running "<setInternal(true); Cantor::Session::setTypesettingEnabled(enable); } Cantor::CompletionObject* MaximaSession::completionFor(const QString& command, int index) { return new MaximaCompletionObject(command, index, this); } Cantor::SyntaxHelpObject* MaximaSession::syntaxHelpFor(const QString& command) { return new MaximaSyntaxHelpObject(command, this); } QSyntaxHighlighter* MaximaSession::syntaxHighlighter(QObject* parent) { return new MaximaHighlighter(parent, this); } QAbstractItemModel* MaximaSession::variableModel() { return m_variableModel; } void MaximaSession::write(const QString& exp) { qDebug()<<"sending expression to maxima process: " << exp << endl; #ifndef Q_OS_WIN m_process->pty()->write(exp.toUtf8()); #else m_process->write(exp.toUtf8()); #endif } diff --git a/src/backends/maxima/maximasyntaxhelpobject.cpp b/src/backends/maxima/maximasyntaxhelpobject.cpp index 60e01668..5ec622b0 100644 --- a/src/backends/maxima/maximasyntaxhelpobject.cpp +++ b/src/backends/maxima/maximasyntaxhelpobject.cpp @@ -1,109 +1,109 @@ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. --- Copyright (C) 2009-2012 Alexander Rieder */ #include "maximasyntaxhelpobject.h" #include "maximakeywords.h" #include "maximasession.h" #include "maximaexpression.h" #include "result.h" #include MaximaSyntaxHelpObject::MaximaSyntaxHelpObject(const QString& cmd, MaximaSession* session) : Cantor::SyntaxHelpObject(cmd, session) { - m_expression=0; + m_expression=nullptr; } MaximaSyntaxHelpObject::~MaximaSyntaxHelpObject() { } void MaximaSyntaxHelpObject::fetchInformation() { if(m_expression) { m_expression->setFinishingBehavior(Cantor::Expression::DeleteOnFinish); } bool isValid=false; foreach(const QString& func, MaximaKeywords::instance()->functions()) { if(command()==func) { isValid=true; break; } } if(isValid) { //use the lisp command, instead of directly calling the //maxima function "describe" to avoid generating a new //output label that would mess up history QString cmd=QLatin1String(":lisp(cl-info::info-exact \"%1\")"); m_expression=session()->evaluateExpression(cmd.arg(command())); connect(m_expression, &Cantor::Expression::statusChanged, this, &MaximaSyntaxHelpObject::expressionChangedStatus); }else { qDebug()<<"invalid syntax request"; emit done(); } } void MaximaSyntaxHelpObject::expressionChangedStatus(Cantor::Expression::Status status) { if(status==Cantor::Expression::Done) { qDebug()<<"expr done"; QString text=m_expression->result()->toHtml(); QStringList lines=text.split(QLatin1Char('\n')); QString syntax; foreach(QString line, lines) // krazy:exclude=foreach { line=line.trimmed(); if(line.endsWith(QLatin1Char('\r'))) line.chop(1); if(line.startsWith(QLatin1String("-- Function:"))) { line.remove(QLatin1String("-- Function:")); line.remove(QLatin1String("
")); syntax+=line.trimmed()+QLatin1Char('\n'); }else break; } setHtml(QLatin1String("

")+syntax+QLatin1String("

")); emit done(); m_expression->deleteLater(); - m_expression=0; + m_expression=nullptr; }else { qDebug()<<"not done: "< */ #include "testmaxima.h" #include "session.h" #include "backend.h" #include "expression.h" #include "result.h" #include "imageresult.h" #include "epsresult.h" #include "syntaxhelpobject.h" #include #include QString TestMaxima::backendName() { return QLatin1String("maxima"); } void TestMaxima::testSimpleCommand() { Cantor::Expression* e=evalExp( QLatin1String("2+2") ); - QVERIFY( e!=0 ); - QVERIFY( e->result()!=0 ); + QVERIFY( e!=nullptr ); + QVERIFY( e->result()!=nullptr ); QCOMPARE( cleanOutput( e->result()->toHtml() ), QLatin1String("4") ); } void TestMaxima::testMultilineCommand() { Cantor::Expression* e=evalExp( QLatin1String("2+2;3+3") ); - QVERIFY( e!=0 ); - QVERIFY( e->result()!=0 ); + QVERIFY( e!=nullptr ); + QVERIFY( e->result()!=nullptr ); QString result=e->result()->toHtml(); QCOMPARE( cleanOutput(result ), QLatin1String("4\n6") ); } //WARNING: for this test to work, Integration of Plots must be anabled //and CantorLib must be compiled with EPS-support void TestMaxima::testPlot() { if(QStandardPaths::findExecutable(QLatin1String("gnuplot")).isNull()) { QSKIP("gnuplot not found maxima needs it for plotting", SkipSingle); } Cantor::Expression* e=evalExp( QLatin1String("plot2d(sin(x), [x, -10,10])") ); - QVERIFY( e!=0 ); - QVERIFY( e->result()!=0 ); + QVERIFY( e!=nullptr ); + QVERIFY( e->result()!=nullptr ); if(e->result()->type()!= Cantor::EpsResult::Type) { waitForSignal(e, SIGNAL(gotResult())); } #ifdef WITH_EPS QCOMPARE( e->result()->type(), (int)Cantor::EpsResult::Type ); #else QCOMPARE( e->result()->type(), (int)Cantor::ImageResult::Type ); #endif QVERIFY( !e->result()->data().isNull() ); QVERIFY( e->errorMessage().isNull() ); } void TestMaxima::testInvalidSyntax() { Cantor::Expression* e=evalExp( QLatin1String("2+2*(") ); - QVERIFY( e!=0 ); + QVERIFY( e!=nullptr ); QVERIFY( e->status()==Cantor::Expression::Error ); } void TestMaxima::testExprNumbering() { Cantor::Expression* e=evalExp( QLatin1String("kill(labels)") ); //first reset the labels e=evalExp( QLatin1String("2+2") ); - QVERIFY( e!=0 ); + QVERIFY( e!=nullptr ); int id=e->id(); QCOMPARE( id, 1 ); e=evalExp( QString::fromLatin1("%O%1+1" ).arg( id ) ); - QVERIFY( e != 0 ); - QVERIFY( e->result()!=0 ); + QVERIFY( e != nullptr ); + QVERIFY( e->result()!=nullptr ); QCOMPARE( cleanOutput( e->result()->toHtml() ), QLatin1String( "5" ) ); } void TestMaxima::testCommandQueue() { //only wait for the last Expression to return, so the queue gets //actually filled Cantor::Expression* e1=session()->evaluateExpression(QLatin1String("0+1")); Cantor::Expression* e2=session()->evaluateExpression(QLatin1String("1+1")); Cantor::Expression* e3=evalExp(QLatin1String("1+2")); - QVERIFY(e1!=0); - QVERIFY(e2!=0); - QVERIFY(e3!=0); + QVERIFY(e1!=nullptr); + QVERIFY(e2!=nullptr); + QVERIFY(e3!=nullptr); QVERIFY(e1->result()); QVERIFY(e2->result()); QVERIFY(e3->result()); QCOMPARE(cleanOutput(e1->result()->toHtml()), QLatin1String("1")); QCOMPARE(cleanOutput(e2->result()->toHtml()), QLatin1String("2")); QCOMPARE(cleanOutput(e3->result()->toHtml()), QLatin1String("3")); } void TestMaxima::testSimpleExpressionWithComment() { Cantor::Expression* e=evalExp(QLatin1String("/*this is a comment*/2+2")); - QVERIFY(e!=0); - QVERIFY(e->result()!=0); + QVERIFY(e!=nullptr); + QVERIFY(e->result()!=nullptr); QCOMPARE(cleanOutput(e->result()->toHtml()), QLatin1String("4")); } void TestMaxima::testCommentExpression() { Cantor::Expression* e=evalExp(QLatin1String("/*this is a comment*/")); - QVERIFY(e!=0); - QVERIFY(e->result()==0||e->result()->toHtml().isEmpty()); + QVERIFY(e!=nullptr); + QVERIFY(e->result()==nullptr||e->result()->toHtml().isEmpty()); } void TestMaxima::testNestedComment() { Cantor::Expression* e=evalExp(QLatin1String("/*/*this is still a comment*/*/2+2/*still/*a*/comment*//**/")); - QVERIFY(e!=0); - QVERIFY(e->result()!=0); + QVERIFY(e!=nullptr); + QVERIFY(e->result()!=nullptr); QCOMPARE(cleanOutput(e->result()->toHtml()), QLatin1String("4")); } void TestMaxima::testUnmatchedComment() { Cantor::Expression* e=evalExp(QLatin1String("/*this comment doesn't end here!")); - QVERIFY(e!=0); - QVERIFY(e->result()==0); + QVERIFY(e!=nullptr); + QVERIFY(e->result()==nullptr); QVERIFY(e->status()==Cantor::Expression::Error); } void TestMaxima::testInvalidAssignment() { Cantor::Expression* e=evalExp(QLatin1String("0:a")); - QVERIFY(e!=0); + QVERIFY(e!=nullptr); //QVERIFY(e->result()==0); //QVERIFY(e->status()==Cantor::Expression::Error); if(session()->status()==Cantor::Session::Running) waitForSignal(session(), SIGNAL( statusChanged(Cantor::Session::Status))); //make sure we didn't screw up the session Cantor::Expression* e2=evalExp(QLatin1String("2+2")); - QVERIFY(e2!=0); - QVERIFY(e2->result()!=0); + QVERIFY(e2!=nullptr); + QVERIFY(e2->result()!=nullptr); QCOMPARE(cleanOutput(e2->result()->toHtml()), QLatin1String("4")); } void TestMaxima::testInformationRequest() { Cantor::Expression* e=session()->evaluateExpression(QLatin1String("integrate(x^n,x)")); - QVERIFY(e!=0); + QVERIFY(e!=nullptr); waitForSignal(e, SIGNAL(needsAdditionalInformation(QString))); e->addInformation(QLatin1String("nonzero;")); waitForSignal(e, SIGNAL(statusChanged(Cantor::Expression::Status))); - QVERIFY(e->result()!=0); + QVERIFY(e->result()!=nullptr); QCOMPARE(cleanOutput(e->result()->toHtml()), QLatin1String("x^(n+1)/(n+1)")); } void TestMaxima::testSyntaxHelp() { Cantor::SyntaxHelpObject* help = session()->syntaxHelpFor(QLatin1String("simplify_sum")); help->fetchSyntaxHelp(); waitForSignal(help, SIGNAL(done())); qWarning()<toHtml(); QVERIFY(!help->toHtml().isEmpty()); } QTEST_MAIN( TestMaxima ) diff --git a/src/backends/null/nullbackend.h b/src/backends/null/nullbackend.h index 90cb1074..4a643a1f 100644 --- a/src/backends/null/nullbackend.h +++ b/src/backends/null/nullbackend.h @@ -1,41 +1,41 @@ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. --- Copyright (C) 2009 Alexander Rieder */ #ifndef _NULLBACKEND_H #define _NULLBACKEND_H #include "backend.h" class NullBackend : public Cantor::Backend { Q_OBJECT public: - explicit NullBackend( QObject* parent = 0,const QList args = QList()); + explicit NullBackend( QObject* parent = nullptr,const QList args = QList()); ~NullBackend() override; QString id() const Q_DECL_OVERRIDE; Cantor::Session *createSession() Q_DECL_OVERRIDE; Cantor::Backend::Capabilities capabilities() const Q_DECL_OVERRIDE; }; #endif /* _NULLBACKEND_H */ diff --git a/src/backends/octave/octavebackend.h b/src/backends/octave/octavebackend.h index 9336ce1f..9a260fc1 100644 --- a/src/backends/octave/octavebackend.h +++ b/src/backends/octave/octavebackend.h @@ -1,43 +1,43 @@ /* Copyright (C) 2010 Miha Čančula This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef CANTOR_OCTAVE_BACKEND_H #define CANTOR_OCTAVE_BACKEND_H #include class OctaveBackend : public Cantor::Backend { Q_OBJECT public: - explicit OctaveBackend( QObject* parent = 0,const QList args = QList()); + explicit OctaveBackend( QObject* parent = nullptr,const QList args = QList()); ~OctaveBackend() override; QString id() const Q_DECL_OVERRIDE; QString version() const override; Cantor::Backend::Capabilities capabilities() const Q_DECL_OVERRIDE; Cantor::Session* createSession() Q_DECL_OVERRIDE; bool requirementsFullfilled() const Q_DECL_OVERRIDE; QUrl helpUrl() const Q_DECL_OVERRIDE; QString description() const Q_DECL_OVERRIDE; QWidget* settingsWidget(QWidget* parent) const Q_DECL_OVERRIDE; KConfigSkeleton* config() const Q_DECL_OVERRIDE; }; #endif diff --git a/src/backends/octave/octavecompletionobject.cpp b/src/backends/octave/octavecompletionobject.cpp index 28a54f85..f21bb884 100644 --- a/src/backends/octave/octavecompletionobject.cpp +++ b/src/backends/octave/octavecompletionobject.cpp @@ -1,118 +1,118 @@ /* Copyright (C) 2010 Miha Čančula This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "octavecompletionobject.h" #include "session.h" #include "expression.h" #include "result.h" #include OctaveCompletionObject::OctaveCompletionObject(const QString& command, int index, Cantor::Session* parent): CompletionObject(parent) { setLine(command, index); - m_expression = 0; + m_expression = nullptr; } OctaveCompletionObject::~OctaveCompletionObject() { } void OctaveCompletionObject::fetchCompletions() { if (m_expression) return; qDebug() << "Fetching completions for" << command(); QString expr = QString::fromLatin1("completion_matches('%1')").arg(command()); m_expression = session()->evaluateExpression(expr); connect(m_expression, &Cantor::Expression::statusChanged, this, &OctaveCompletionObject::extractCompletions); } void OctaveCompletionObject::extractCompletions() { if (!m_expression) return; if (m_expression->status() != Cantor::Expression::Done) { m_expression->deleteLater(); - m_expression = 0; + m_expression = nullptr; return; } Cantor::Result* result = m_expression->result(); if (result) { QString res = result->toHtml(); QStringList completions = res.split(QLatin1String("
\n"), QString::SkipEmptyParts); qDebug() << "Adding" << completions.size() << "completions"; setCompletions( completions ); } m_expression->deleteLater(); - m_expression = 0; + m_expression = nullptr; emit fetchingDone(); } void OctaveCompletionObject::fetchIdentifierType() { if (m_expression) return; qDebug() << "Fetching type of " << identifier(); // The output should look like // sin is a built-in function // __cantor_tmp2__ = 5 QString expr = QString::fromLatin1("ans = type('%1');ans").arg(identifier()); m_expression = session()->evaluateExpression(expr); connect(m_expression, &Cantor::Expression::statusChanged, this, &OctaveCompletionObject::extractIdentifierType); } void OctaveCompletionObject::extractIdentifierType() { qDebug() << "type fetching done"; if (!m_expression) return; if (m_expression->status() != Cantor::Expression::Done) { m_expression->deleteLater(); - m_expression = 0; + m_expression = nullptr; return; } Cantor::Result* result = m_expression->result(); m_expression->deleteLater(); - m_expression = 0; + m_expression = nullptr; if (!result) return; QString res = result->toHtml(); int endOfLine1 = res.indexOf(QLatin1String("
")); int endOfLine2 = res.indexOf(QLatin1String("
"), endOfLine1+1); QString line1 = res.left(endOfLine1); QString line2 = res.mid(endOfLine1, endOfLine2-endOfLine1); // for functions defined on the command line type says "undefined", // but sets ans to 103 if (line1.endsWith(QLatin1String("function")) || line1.contains(QLatin1String("user-defined function")) || line2.endsWith(QLatin1String("103"))) emit fetchingTypeDone(FunctionType); else if (res.endsWith(QLatin1String("variable"))) emit fetchingTypeDone(VariableType); else if (res.endsWith(QLatin1String("keyword"))) emit fetchingTypeDone(KeywordType); else emit fetchingTypeDone(UnknownType); } diff --git a/src/backends/octave/octavesession.cpp b/src/backends/octave/octavesession.cpp index 24ad08d1..0bb6a37b 100644 --- a/src/backends/octave/octavesession.cpp +++ b/src/backends/octave/octavesession.cpp @@ -1,311 +1,311 @@ /* Copyright (C) 2010 Miha Čančula This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "octavesession.h" #include "octaveexpression.h" #include "octavecompletionobject.h" #include "octavesyntaxhelpobject.h" #include "result.h" #include "textresult.h" #include "settings.h" #include "octave-backend-config.h" #include #include #include #include #include "octavehighlighter.h" #include #include #include OctaveSession::OctaveSession ( Cantor::Backend* backend ) : Session ( backend ), -m_process(0), -m_currentExpression(0), -m_watch(0), +m_process(nullptr), +m_currentExpression(nullptr), +m_watch(nullptr), m_variableModel(new Cantor::DefaultVariableModel(this)) { qDebug() << octaveScriptInstallDir; } OctaveSession::~OctaveSession() { } void OctaveSession::login() { qDebug() << "login"; emit loginStarted(); m_process = new KProcess ( this ); QStringList args; args << QLatin1String("--silent"); args << QLatin1String("--interactive"); args << QLatin1String("--persist"); // Add the cantor script directory to search path args << QLatin1String("--eval"); args << QString::fromLatin1("addpath %1;").arg(octaveScriptInstallDir); if (OctaveSettings::integratePlots()) { // Do not show the popup when plotting, rather only print to a file args << QLatin1String("--eval"); args << QLatin1String("graphics_toolkit gnuplot;"); args << QLatin1String("--eval"); args << QLatin1String("set (0, \"defaultfigurevisible\",\"off\");"); } else { args << QLatin1String("--eval"); args << QLatin1String("set (0, \"defaultfigurevisible\",\"on\");"); } // Do not show extra text in help commands args << QLatin1String("--eval"); args << QLatin1String("suppress_verbose_help_message(1);"); // Print the temp dir, used for plot files args << QLatin1String("--eval"); args << QLatin1String("____TMP_DIR____ = tempdir"); m_process->setProgram ( OctaveSettings::path().toLocalFile(), args ); qDebug() << m_process->program(); m_process->setOutputChannelMode ( KProcess::SeparateChannels ); connect ( m_process, SIGNAL ( readyReadStandardOutput() ), SLOT ( readOutput() ) ); connect ( m_process, SIGNAL ( readyReadStandardError() ), SLOT ( readError() ) ); connect ( m_process, SIGNAL ( error ( QProcess::ProcessError ) ), SLOT ( processError() ) ); m_process->start(); if (OctaveSettings::integratePlots()) { m_watch = new KDirWatch(this); m_watch->setObjectName(QLatin1String("OctaveDirWatch")); connect (m_watch, SIGNAL(dirty(QString)), SLOT(plotFileChanged(QString)) ); } if(!OctaveSettings::self()->autorunScripts().isEmpty()){ QString autorunScripts = OctaveSettings::self()->autorunScripts().join(QLatin1String("\n")); evaluateExpression(autorunScripts, OctaveExpression::DeleteOnFinish); } } void OctaveSession::logout() { qDebug() << "logout"; m_process->write("exit\n"); if (!m_process->waitForFinished(1000)) { m_process->kill(); } } void OctaveSession::interrupt() { qDebug() << "interrupt"; if (m_currentExpression) { m_currentExpression->interrupt(); } m_expressionQueue.clear(); qDebug() << "Sending SIGINT to Octave"; kill(m_process->pid(), SIGINT); changeStatus(Done); } void OctaveSession::processError() { qDebug() << "processError"; emit error(m_process->errorString()); } Cantor::Expression* OctaveSession::evaluateExpression ( const QString& command, Cantor::Expression::FinishingBehavior finishingBehavior ) { qDebug() << "evaluateExpression: " << command; OctaveExpression* expression = new OctaveExpression ( this ); expression->setCommand ( command ); expression->setFinishingBehavior ( finishingBehavior ); expression->evaluate(); return expression; } void OctaveSession::runExpression ( OctaveExpression* expression ) { qDebug() << "runExpression"; if ( status() != Done ) { m_expressionQueue.enqueue ( expression ); qDebug() << m_expressionQueue.size(); } else { m_currentExpression = expression; changeStatus(Running); connect(m_currentExpression, SIGNAL(statusChanged(Cantor::Expression::Status)), this, SLOT(currentExpressionStatusChanged(Cantor::Expression::Status))); QString command = expression->command(); command.replace(QLatin1Char('\n'), QLatin1Char(',')); command += QLatin1Char('\n'); m_process->write ( command.toLocal8Bit() ); } } void OctaveSession::readError() { qDebug() << "readError"; QString error = QString::fromLocal8Bit(m_process->readAllStandardError()); if (!m_currentExpression || error.isEmpty()) { return; } m_currentExpression->parseError(error); } void OctaveSession::readOutput() { qDebug() << "readOutput"; while (m_process->bytesAvailable() > 0) { if (m_tempDir.isEmpty() && !m_process->canReadLine()) { qDebug() << "Waiting"; // Wait for the full line containing octave's tempDir return; } QString line = QString::fromLocal8Bit(m_process->readLine()); if (!m_currentExpression) { if (m_prompt.isEmpty() && line.contains(QLatin1String(":1>"))) { qDebug() << "Found Octave prompt:" << line; line.replace(QLatin1String(":1"), QLatin1String(":[0-9]+")); m_prompt.setPattern(line); changeStatus(Done); if (!m_expressionQueue.isEmpty()) { runExpression(m_expressionQueue.dequeue()); } emit loginDone(); } else if (line.contains(QLatin1String("____TMP_DIR____"))) { m_tempDir = line; m_tempDir.remove(0,18); m_tempDir.chop(1); // isolate the tempDir's location qDebug() << "Got temporary file dir:" << m_tempDir; if (m_watch) { m_watch->addDir(m_tempDir, KDirWatch::WatchFiles); } } } else if (line.contains(m_prompt)) { // Check for errors before finalizing the expression // this makes sure that all errors are caught readError(); m_currentExpression->finalize(); if (m_currentExpression->command().contains(QLatin1String(" = "))) { emit variablesChanged(); } if (m_currentExpression->command().contains(QLatin1String("function "))) { emit functionsChanged(); } } else { // Avoid many calls to setResult if a lot of output came at the same time while (m_process->canReadLine()) { line += QString::fromLocal8Bit(m_process->readLine()); } m_currentExpression->parseOutput(line); } } } void OctaveSession::currentExpressionStatusChanged(Cantor::Expression::Status status) { qDebug() << "currentExpressionStatusChanged"; if (!m_currentExpression) { return; } switch (status) { case Cantor::Expression::Computing: break; case Cantor::Expression::Interrupted: break; case Cantor::Expression::Done: case Cantor::Expression::Error: changeStatus(Done); if (!m_expressionQueue.isEmpty()) { runExpression(m_expressionQueue.dequeue()); } break; } } void OctaveSession::plotFileChanged(const QString& filename) { if (!QFile::exists(filename) || !filename.split(QLatin1Char('/')).last().contains(QLatin1String("c-ob-"))) { return; } if (m_currentExpression) { m_currentExpression->parsePlotFile(filename); } } Cantor::CompletionObject* OctaveSession::completionFor ( const QString& cmd, int index ) { return new OctaveCompletionObject ( cmd, index, this ); } Cantor::SyntaxHelpObject* OctaveSession::syntaxHelpFor ( const QString& cmd ) { return new OctaveSyntaxHelpObject ( cmd, this ); } QSyntaxHighlighter* OctaveSession::syntaxHighlighter ( QObject* parent ) { OctaveHighlighter* highlighter = new OctaveHighlighter ( parent, this ); connect ( this, SIGNAL(functionsChanged()), highlighter, SLOT(updateFunctions()) ); connect ( this, SIGNAL(variablesChanged()), highlighter, SLOT(updateVariables()) ); return highlighter; } QAbstractItemModel* OctaveSession::variableModel() { return m_variableModel; } void OctaveSession::runSpecificCommands() { m_process->write("figure(1,'visible','off')"); } diff --git a/src/backends/octave/testoctave.cpp b/src/backends/octave/testoctave.cpp index 2ed4bebc..5c607f2f 100644 --- a/src/backends/octave/testoctave.cpp +++ b/src/backends/octave/testoctave.cpp @@ -1,90 +1,90 @@ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. --- Copyright (C) 2009 Alexander Rieder */ #include "testoctave.h" #include "session.h" #include "backend.h" #include "expression.h" #include "result.h" #include "imageresult.h" #include "epsresult.h" #include "octaveexpression.h" #include QString TestOctave::backendName() { return QLatin1String("octave"); } void TestOctave::testSimpleCommand() { Cantor::Expression* e=evalExp( QLatin1String("2+2") ); - QVERIFY( e!=0 ); - QVERIFY( e->result()!=0 ); + QVERIFY( e!=nullptr ); + QVERIFY( e->result()!=nullptr ); QCOMPARE( cleanOutput( e->result()->toHtml() ), QLatin1String("ans = 4") ); } void TestOctave::testMultilineCommand() { Cantor::Expression* e=evalExp( QLatin1String("a = 2+2, b = 3+3") ); - QVERIFY( e!=0 ); - QVERIFY( e->result()!=0 ); + QVERIFY( e!=nullptr ); + QVERIFY( e->result()!=nullptr ); QString result=e->result()->toHtml(); QCOMPARE( cleanOutput(result ), QLatin1String("a = 4\nb = 6") ); } void TestOctave::testPlot() { Cantor::Expression* e=evalExp( QLatin1String("cantor_plot2d('sin(x)', 'x', -10,10);") ); int cnt=0; //give some time to create the image, but at most 5sec - while(e->result()==0||e->result()->type()!=OctavePlotResult::Type ) + while(e->result()==nullptr||e->result()->type()!=OctavePlotResult::Type ) { QTest::qWait(250); cnt+=250; if(cnt>5000) break; } - QVERIFY( e!=0 ); - QVERIFY( e->result()!=0 ); + QVERIFY( e!=nullptr ); + QVERIFY( e->result()!=nullptr ); QCOMPARE( e->result()->type(), (int) OctavePlotResult::Type ); QVERIFY( !e->result()->data().isNull() ); } void TestOctave::testInvalidSyntax() { Cantor::Expression* e=evalExp( QLatin1String("2+2*+.") ); - QVERIFY( e!=0 ); + QVERIFY( e!=nullptr ); QCOMPARE( e->status(), Cantor::Expression::Error ); } QTEST_MAIN( TestOctave ) diff --git a/src/backends/python/pythonkeywords.cpp b/src/backends/python/pythonkeywords.cpp index 777b2cc5..2f630718 100644 --- a/src/backends/python/pythonkeywords.cpp +++ b/src/backends/python/pythonkeywords.cpp @@ -1,215 +1,215 @@ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. --- Copyright (C) 2011 Filipe Saraiva */ #include "pythonkeywords.h" #include #include PythonKeywords::PythonKeywords() { qDebug() << "PythonKeywords construtor"; } PythonKeywords::~PythonKeywords() { } PythonKeywords* PythonKeywords::instance() { - static PythonKeywords* inst = 0; - if(inst == 0) + static PythonKeywords* inst = nullptr; + if(inst == nullptr) { inst = new PythonKeywords(); inst->loadKeywords(); } return inst; } void PythonKeywords::loadKeywords() { //Begin m_keywords initialization m_keywords << QLatin1String("and"); m_keywords << QLatin1String("as"); m_keywords << QLatin1String("assert"); m_keywords << QLatin1String("break"); m_keywords << QLatin1String("class"); m_keywords << QLatin1String("continue"); m_keywords << QLatin1String("def"); m_keywords << QLatin1String("del"); m_keywords << QLatin1String("elif"); m_keywords << QLatin1String("else"); m_keywords << QLatin1String("except"); m_keywords << QLatin1String("exec"); m_keywords << QLatin1String("finally"); m_keywords << QLatin1String("for"); m_keywords << QLatin1String("from"); m_keywords << QLatin1String("global"); m_keywords << QLatin1String("if"); m_keywords << QLatin1String("import"); m_keywords << QLatin1String("in"); m_keywords << QLatin1String("is"); m_keywords << QLatin1String("lambda"); m_keywords << QLatin1String("not"); m_keywords << QLatin1String("or"); m_keywords << QLatin1String("pass"); m_keywords << QLatin1String("print"); m_keywords << QLatin1String("raise"); m_keywords << QLatin1String("return"); m_keywords << QLatin1String("try"); m_keywords << QLatin1String("while"); m_keywords << QLatin1String("with"); m_keywords << QLatin1String("yield"); //Finish m_keywords initialization //Begin m_functions initialization m_functions << QLatin1String("__import__"); m_functions << QLatin1String("abs"); m_functions << QLatin1String("all"); m_functions << QLatin1String("any"); m_functions << QLatin1String("apply"); m_functions << QLatin1String("basestring"); m_functions << QLatin1String("bin"); m_functions << QLatin1String("bool"); m_functions << QLatin1String("buffer"); m_functions << QLatin1String("bytearray"); m_functions << QLatin1String("callable"); m_functions << QLatin1String("chr"); m_functions << QLatin1String("classmethod"); m_functions << QLatin1String("cmp"); m_functions << QLatin1String("compile"); m_functions << QLatin1String("complex"); m_functions << QLatin1String("coerce"); m_functions << QLatin1String("delattr"); m_functions << QLatin1String("dict"); m_functions << QLatin1String("dir"); m_functions << QLatin1String("divmod"); m_functions << QLatin1String("enumerate"); m_functions << QLatin1String("eval"); m_functions << QLatin1String("execfile"); m_functions << QLatin1String("file"); m_functions << QLatin1String("filter"); m_functions << QLatin1String("float"); m_functions << QLatin1String("format"); m_functions << QLatin1String("frozenset"); m_functions << QLatin1String("getattr"); m_functions << QLatin1String("globals"); m_functions << QLatin1String("hasattr"); m_functions << QLatin1String("hash"); m_functions << QLatin1String("help"); m_functions << QLatin1String("hex"); m_functions << QLatin1String("id"); m_functions << QLatin1String("input"); m_functions << QLatin1String("int"); m_functions << QLatin1String("intern"); m_functions << QLatin1String("isinstance"); m_functions << QLatin1String("issubclass"); m_functions << QLatin1String("iter"); m_functions << QLatin1String("len"); m_functions << QLatin1String("list"); m_functions << QLatin1String("locals"); m_functions << QLatin1String("long"); m_functions << QLatin1String("map"); m_functions << QLatin1String("max"); m_functions << QLatin1String("memoryview"); m_functions << QLatin1String("min"); m_functions << QLatin1String("next"); m_functions << QLatin1String("object"); m_functions << QLatin1String("oct"); m_functions << QLatin1String("open"); m_functions << QLatin1String("ord"); m_functions << QLatin1String("pow"); m_functions << QLatin1String("print"); m_functions << QLatin1String("property"); m_functions << QLatin1String("range"); m_functions << QLatin1String("raw_input"); m_functions << QLatin1String("reduce"); m_functions << QLatin1String("reload"); m_functions << QLatin1String("repr"); m_functions << QLatin1String("reversed"); m_functions << QLatin1String("round"); m_functions << QLatin1String("set"); m_functions << QLatin1String("setattr"); m_functions << QLatin1String("slice"); m_functions << QLatin1String("sorted"); m_functions << QLatin1String("staticmethod"); m_functions << QLatin1String("str"); m_functions << QLatin1String("sum"); m_functions << QLatin1String("super"); m_functions << QLatin1String("tuple"); m_functions << QLatin1String("type"); m_functions << QLatin1String("unichr"); m_functions << QLatin1String("unicode"); m_functions << QLatin1String("vars"); m_functions << QLatin1String("xrange"); m_functions << QLatin1String("zip"); //Finish m_functions initialization //Begin m_variables initialization m_variables << QLatin1String("False"); m_variables << QLatin1String("True"); //Finish m_variables initialization } void PythonKeywords::loadFromModule(const QString& module, const QStringList& keywords) { qDebug() << "Module imported" << module; if (module.isEmpty()){ for(int contKeyword = 0; contKeyword < keywords.size(); contKeyword++){ m_functions << keywords.at(contKeyword); } } else { m_variables << module; for(int contKeyword = 0; contKeyword < keywords.size(); contKeyword++){ m_functions << module + QLatin1String(".") + keywords.at(contKeyword); } } } void PythonKeywords::addVariable(const QString& variable) { qDebug() << "Variable added" << variable; if (!m_variables.contains(variable)){ m_variables << variable; } } const QStringList& PythonKeywords::variables() const { return m_variables; } const QStringList& PythonKeywords::functions() const { return m_functions; } const QStringList& PythonKeywords::keywords() const { return m_keywords; } diff --git a/src/backends/python2/testpython2.cpp b/src/backends/python2/testpython2.cpp index 4ae59a3b..016496fe 100644 --- a/src/backends/python2/testpython2.cpp +++ b/src/backends/python2/testpython2.cpp @@ -1,59 +1,59 @@ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. --- Copyright (C) 2013 Tuukka Verho */ #include "testpython2.h" #include "session.h" #include "backend.h" #include "expression.h" #include "result.h" QString TestPython2::backendName() { return QLatin1String("python2"); } void TestPython2::testImportNumpy() { Cantor::Expression* e = evalExp(QLatin1String("import numpy")); - QVERIFY(e != 0); - QVERIFY(e->result() != 0); + QVERIFY(e != nullptr); + QVERIFY(e->result() != nullptr); } void TestPython2::testCodeWithComments() { { Cantor::Expression* e = evalExp(QLatin1String("#comment\n1+2")); - QVERIFY(e != 0); + QVERIFY(e != nullptr); QVERIFY(e->result()->data().toString() == QLatin1String("3")); } { Cantor::Expression* e = evalExp(QLatin1String(" #comment\n1+2")); - QVERIFY(e != 0); + QVERIFY(e != nullptr); QVERIFY(e->result()->data().toString() == QLatin1String("3")); } } QTEST_MAIN(TestPython2) diff --git a/src/backends/python3/tests/testpython3.cpp b/src/backends/python3/tests/testpython3.cpp index e2b205bd..9d6f443d 100644 --- a/src/backends/python3/tests/testpython3.cpp +++ b/src/backends/python3/tests/testpython3.cpp @@ -1,76 +1,76 @@ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. --- Copyright (C) 2015 Minh Ngo */ #include "testpython3.h" #include "session.h" #include "backend.h" #include "expression.h" #include "result.h" QString TestPython3::backendName() { return QLatin1String("python3"); } void TestPython3::testImportNumpy() { Cantor::Expression* e = evalExp(QLatin1String("import numpy")); - QVERIFY(e != 0); - QVERIFY(e->result() != 0); + QVERIFY(e != nullptr); + QVERIFY(e->result() != nullptr); } void TestPython3::testCodeWithComments() { { Cantor::Expression* e = evalExp(QLatin1String("#comment\n1+2")); - QVERIFY(e != 0); + QVERIFY(e != nullptr); QVERIFY(e->result()->data().toString() == QLatin1String("3")); } { Cantor::Expression* e = evalExp(QLatin1String(" #comment\n1+2")); - QVERIFY(e != 0); + QVERIFY(e != nullptr); QVERIFY(e->result()->data().toString() == QLatin1String("3")); } } void TestPython3::testPython3Code() { { Cantor::Expression* e = evalExp(QLatin1String("print 1 + 2")); - QVERIFY(e != 0); + QVERIFY(e != nullptr); QVERIFY(!e->errorMessage().isEmpty()); } { Cantor::Expression* e = evalExp(QLatin1String("print(1 + 2)")); - QVERIFY(e != 0); + QVERIFY(e != nullptr); QVERIFY(e->result()->data().toString() == QLatin1String("3")); } } QTEST_MAIN(TestPython3) diff --git a/src/backends/sage/sagebackend.h b/src/backends/sage/sagebackend.h index e63a496e..04801973 100644 --- a/src/backends/sage/sagebackend.h +++ b/src/backends/sage/sagebackend.h @@ -1,47 +1,47 @@ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. --- Copyright (C) 2009 Alexander Rieder */ #ifndef _SAGEBACKEND_H #define _SAGEBACKEND_H #include "backend.h" class SageBackend : public Cantor::Backend { Q_OBJECT public: - explicit SageBackend( QObject* parent = 0,const QList args = QList()); + explicit SageBackend( QObject* parent = nullptr,const QList args = QList()); ~SageBackend() override; QString id() const Q_DECL_OVERRIDE; QString version() const override; Cantor::Session *createSession() Q_DECL_OVERRIDE; Cantor::Backend::Capabilities capabilities() const Q_DECL_OVERRIDE; bool requirementsFullfilled() const Q_DECL_OVERRIDE; QWidget* settingsWidget(QWidget* parent) const Q_DECL_OVERRIDE; KConfigSkeleton* config() const Q_DECL_OVERRIDE; QUrl helpUrl() const Q_DECL_OVERRIDE; QString description() const Q_DECL_OVERRIDE; }; #endif /* _SAGEBACKEND_H */ diff --git a/src/backends/sage/sagecompletionobject.cpp b/src/backends/sage/sagecompletionobject.cpp index 3aaee267..613eae15 100644 --- a/src/backends/sage/sagecompletionobject.cpp +++ b/src/backends/sage/sagecompletionobject.cpp @@ -1,188 +1,188 @@ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. --- Copyright (C) 2009 Alexander Rieder */ #include "sagecompletionobject.h" #include "sagesession.h" #include "sagekeywords.h" #include "textresult.h" #include #include SageCompletionObject::SageCompletionObject(const QString& command, int index, SageSession* session) : Cantor::CompletionObject(session) { setLine(command, index); - m_expression=0; + m_expression=nullptr; } SageCompletionObject::~SageCompletionObject() { if(m_expression) { m_expression->interrupt(); m_expression->deleteLater(); } } void SageCompletionObject::fetchCompletions() { if (m_expression) return; bool t=session()->isTypesettingEnabled(); if(t) session()->setTypesettingEnabled(false); //cache the value of the "_" variable into __hist_tmp__, so we can restore the previous result //after complete() was evaluated m_expression=session()->evaluateExpression(QLatin1String("__hist_tmp__=_; __CANTOR_IPYTHON_SHELL__.complete(\"")+command()+QLatin1String("\");_=__hist_tmp__")); connect(m_expression, &Cantor::Expression::gotResult, this, &SageCompletionObject::extractCompletions); if(t) session()->setTypesettingEnabled(true); } void SageCompletionObject::extractCompletions() { SageSession* s=qobject_cast(session()); if(s&&s->sageVersion()result(); m_expression->deleteLater(); - m_expression=0; + m_expression=nullptr; if(!res || !(res->type()==Cantor::TextResult::Type)) { qDebug()<<"something went wrong fetching tab completion"; return; } //the result looks like "['comp1', 'comp2']" parse it //for sage version 5.7 this looks like //('s1', ['comp1','comp2']) where s1 is the string we called complete with QString txt=res->toHtml().trimmed(); txt.remove(QLatin1String("
")); txt=txt.mid(txt.indexOf(command())+command().length()+2).trimmed(); txt=txt.mid(1); //remove [ txt.chop(2); //remove ] qDebug()<<"completion string: "<keywords(); setCompletions(completions); emit fetchingDone(); } void SageCompletionObject::extractCompletionsLegacy() { Cantor::Result* res=m_expression->result(); m_expression->deleteLater(); - m_expression=0; + m_expression=nullptr; if(!res || !(res->type()==Cantor::TextResult::Type)) { qDebug()<<"something went wrong fetching tab completion"; return; } //the result looks like "['comp1', 'comp2']" parse it QString txt=res->toHtml().trimmed(); txt=txt.mid(1); //remove [ txt.chop(1); //remove ] QStringList tmp=txt.split(QLatin1Char(',')); QStringList completions; foreach(QString c, tmp) // krazy:exclude=foreach { c=c.trimmed(); c.chop(1); completions<keywords(); setCompletions(completions); emit fetchingDone(); } void SageCompletionObject::fetchIdentifierType() { if (m_expression) return; if (SageKeywords::instance()->keywords().contains(identifier())) { emit fetchingTypeDone(KeywordType); return; } QString expr = QString::fromLatin1("__cantor_internal__ = _; type(%1); _ = __cantor_internal__").arg(identifier()); m_expression = session()->evaluateExpression(expr); connect(m_expression, &Cantor::Expression::statusChanged, this, &SageCompletionObject::extractIdentifierType); } void SageCompletionObject::extractIdentifierType() { if (m_expression->status() != Cantor::Expression::Done) { m_expression->deleteLater(); - m_expression = 0; + m_expression = nullptr; return; } Cantor::Result* result = m_expression->result(); m_expression->deleteLater(); - m_expression = 0; + m_expression = nullptr; if (!result) return; QString res = result->toHtml(); if (res.contains(QLatin1String("function")) || res.contains(QLatin1String("method"))) emit fetchingTypeDone(FunctionType); else emit fetchingTypeDone(VariableType); } bool SageCompletionObject::mayIdentifierContain(QChar c) const { return c.isLetter() || c.isDigit() || c == QLatin1Char('_') || c == QLatin1Char('.'); } bool SageCompletionObject::mayIdentifierBeginWith(QChar c) const { return c.isLetter() || c.isDigit() || c == QLatin1Char('_'); } diff --git a/src/backends/sage/sageexpression.cpp b/src/backends/sage/sageexpression.cpp index 99a58e54..fa52e773 100644 --- a/src/backends/sage/sageexpression.cpp +++ b/src/backends/sage/sageexpression.cpp @@ -1,268 +1,268 @@ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. --- Copyright (C) 2009 Alexander Rieder */ #include "sageexpression.h" #include "sagesession.h" #include "textresult.h" #include "imageresult.h" #include "animationresult.h" #include "helpresult.h" #include #include #include #include SageExpression::SageExpression( Cantor::Session* session ) : Cantor::Expression(session) { qDebug(); } SageExpression::~SageExpression() { } void SageExpression::evaluate() { qDebug()<<"evaluating "<(session())->appendExpressionToQueue(this); } void SageExpression::interrupt() { qDebug()<<"interrupting"; dynamic_cast(session())->sendSignalToProcess(2); dynamic_cast(session())->waitForNextPrompt(); setStatus(Cantor::Expression::Interrupted); } void SageExpression::parseOutput(const QString& text) { QString output=text; //remove carriage returns, we only use \n internally output.remove(QLatin1Char('\r')); //replace appearing backspaces, as they mess the whole output up output.remove(QRegExp(QLatin1String(".\b"))); //replace Escape sequences (only tested with `ls` command) const QChar ESC(0x1b); output.remove(QRegExp(QString(ESC)+QLatin1String("\\][^\a]*\a"))); const QString promptRegexpBase(QLatin1String("(^|\\n)%1")); const QRegExp promptRegexp(promptRegexpBase.arg(QRegExp::escape(QLatin1String(SageSession::SagePrompt)))); const QRegExp altPromptRegexp(promptRegexpBase.arg(QRegExp::escape(QLatin1String(SageSession::SageAlternativePrompt)))); bool endsWithAlternativePrompt=output.endsWith(QLatin1String(SageSession::SageAlternativePrompt)); //remove all prompts. we do this in a loop, because after we removed the first prompt, //there could be a second one, that isn't matched by promptRegexp in the first run, because //it originally isn't at the beginning of a line. int index=-1, index2=-1; while ( (index=output.indexOf(promptRegexp)) != -1 || (index2=output.indexOf(altPromptRegexp)) != -1 ) { qDebug()<<"got prompt"<")); const bool isLatex=m_outputCache.contains(QLatin1String("\\newcommand{\\Bold}")); //Check if it's latex stuff if(isLatex) //It's latex stuff so encapsulate it into an eqnarray environment { stripped.prepend(QLatin1String("\\begin{eqnarray*}")); stripped.append(QLatin1String("\\end{eqnarray*}")); } //strip html tags if(isHtml) { stripped.remove( QRegExp( QLatin1String("<[a-zA-Z\\/][^>]*>") ) ); } else { //Replace < and > with their html code, so they won't be confused as html tags stripped.replace( QLatin1Char('<') , QLatin1String("<")); stripped.replace( QLatin1Char('>') , QLatin1String(">")); } if (stripped.endsWith(QLatin1Char('\n'))) stripped.chop(1); if (m_isHelpRequest) { //Escape whitespace stripped.replace( QLatin1Char(' '), QLatin1String(" ")); //make things quoted in `` `` bold stripped.replace(QRegExp(QLatin1String("``([^`]*)``")), QLatin1String("\\1")); result=new Cantor::HelpResult(stripped); } else { result=new Cantor::TextResult(stripped); } if(isLatex) result->setFormat(Cantor::TextResult::LatexFormat); setResult(result); } else { QMimeDatabase db; QMimeType type = db.mimeTypeForUrl(QUrl::fromLocalFile(m_imagePath)); if(type.inherits(QLatin1String("image/gif"))) setResult( new Cantor::AnimationResult(QUrl::fromLocalFile(m_imagePath ),i18n("Result of %1" , command() ) ) ); else setResult( new Cantor::ImageResult( QUrl::fromLocalFile(m_imagePath ),i18n("Result of %1" , command() ) ) ); } setStatus(Cantor::Expression::Done); } void SageExpression::onProcessError(const QString& msg) { QString errMsg=i18n("%1\nThe last output was: \n %2", msg, m_outputCache.trimmed()); setErrorMessage(errMsg); setStatus(Cantor::Expression::Error); } QString SageExpression::additionalLatexHeaders() { //The LaTeX sage needs the amsmath package and some specific macros. //So include them in the header. //More about the macros requirement in bug #312738 return QLatin1String("\\usepackage{amsmath}\n" \ "\\newcommand{\\ZZ}{\\Bold{Z}}\n" \ "\\newcommand{\\NN}{\\Bold{N}}\n" \ "\\newcommand{\\RR}{\\Bold{R}}\n" \ "\\newcommand{\\CC}{\\Bold{C}}\n" \ "\\newcommand{\\QQ}{\\Bold{Q}}\n" \ "\\newcommand{\\QQbar}{\\overline{\\QQ}}\n" \ "\\newcommand{\\GF}[1]{\\Bold{F}_{#1}}\n" \ "\\newcommand{\\Zp}[1]{\\ZZ_{#1}}\n" \ "\\newcommand{\\Qp}[1]{\\QQ_{#1}}\n" \ "\\newcommand{\\Zmod}[1]{\\ZZ/#1\\ZZ}\n" \ "\\newcommand{\\CDF}{\\Bold{C}}\n" \ "\\newcommand{\\CIF}{\\Bold{C}}\n" \ "\\newcommand{\\CLF}{\\Bold{C}}\n" \ "\\newcommand{\\RDF}{\\Bold{R}}\n" \ "\\newcommand{\\RIF}{\\Bold{I} \\Bold{R}}\n"\ "\\newcommand{\\RLF}{\\Bold{R}}\n" \ "\\newcommand{\\CFF}{\\Bold{CFF}}\n"); } diff --git a/src/backends/sage/sagekeywords.cpp b/src/backends/sage/sagekeywords.cpp index a491e656..ab4d4b60 100644 --- a/src/backends/sage/sagekeywords.cpp +++ b/src/backends/sage/sagekeywords.cpp @@ -1,86 +1,86 @@ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. --- Copyright (C) 2012 Martin Kuettler */ #include "sagekeywords.h" #include SageKeywords::SageKeywords() { } SageKeywords::~SageKeywords() { } SageKeywords* SageKeywords::instance() { - static SageKeywords* inst=0; - if(inst==0) + static SageKeywords* inst=nullptr; + if(inst==nullptr) { inst = new SageKeywords(); inst->loadKeywords(); } return inst; } void SageKeywords::loadKeywords() { //Begin m_keywords initialization m_keywords << QLatin1String("and"); m_keywords << QLatin1String("as"); m_keywords << QLatin1String("assert"); m_keywords << QLatin1String("break"); m_keywords << QLatin1String("class"); m_keywords << QLatin1String("continue"); m_keywords << QLatin1String("def"); m_keywords << QLatin1String("del"); m_keywords << QLatin1String("elif"); m_keywords << QLatin1String("else"); m_keywords << QLatin1String("except"); m_keywords << QLatin1String("exec"); m_keywords << QLatin1String("finally"); m_keywords << QLatin1String("for"); m_keywords << QLatin1String("from"); m_keywords << QLatin1String("global"); m_keywords << QLatin1String("if"); m_keywords << QLatin1String("import"); m_keywords << QLatin1String("in"); m_keywords << QLatin1String("is"); m_keywords << QLatin1String("lambda"); m_keywords << QLatin1String("not"); m_keywords << QLatin1String("or"); m_keywords << QLatin1String("pass"); m_keywords << QLatin1String("print"); m_keywords << QLatin1String("raise"); m_keywords << QLatin1String("return"); m_keywords << QLatin1String("try"); m_keywords << QLatin1String("while"); m_keywords << QLatin1String("with"); m_keywords << QLatin1String("yield"); //Finish m_keywords initialization } const QStringList& SageKeywords::keywords() const { return m_keywords; } diff --git a/src/backends/sage/sagesession.cpp b/src/backends/sage/sagesession.cpp index 51fa5f13..d9e8f502 100644 --- a/src/backends/sage/sagesession.cpp +++ b/src/backends/sage/sagesession.cpp @@ -1,440 +1,440 @@ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. --- Copyright (C) 2009 Alexander Rieder */ #include "sagesession.h" #include "sageexpression.h" #include "sagecompletionobject.h" #include "sagehighlighter.h" #include #include #include #include #include #include "settings.h" const QByteArray SageSession::SagePrompt="sage: "; //Text, sage outputs after each command const QByteArray SageSession::SageAlternativePrompt="....: "; //Text, sage outputs when it expects further input //some commands that are run after login static QByteArray initCmd="os.environ['PAGER'] = 'cat' \n "\ "sage.misc.pager.EMBEDDED_MODE = True \n "\ "sage.misc.viewer.BROWSER='' \n "\ "sage.misc.viewer.viewer.png_viewer('') \n" \ "sage.plot.plot3d.base.SHOW_DEFAULTS['viewer'] = 'tachyon' \n"\ "sage.misc.latex.EMBEDDED_MODE = True \n "\ "os.environ['PAGER'] = 'cat' \n "\ "%colors nocolor \n "\ "print '____TMP_DIR____', sage.misc.misc.SAGE_TMP\n"; static QByteArray newInitCmd= "__CANTOR_IPYTHON_SHELL__=get_ipython() \n "\ "__CANTOR_IPYTHON_SHELL__.autoindent=False\n "; static QByteArray legacyInitCmd= "__CANTOR_IPYTHON_SHELL__=__IPYTHON__ \n " \ "__CANTOR_IPYTHON_SHELL__.autoindent=False\n "; static QByteArray endOfInitMarker="print '____END_OF_INIT____'\n "; SageSession::VersionInfo::VersionInfo(int major, int minor) { m_major=major; m_minor=minor; } int SageSession::VersionInfo::majorVersion() const { return m_major; } int SageSession::VersionInfo::minorVersion() const { return m_minor; } bool SageSession::VersionInfo::operator==(const SageSession::VersionInfo &other) const { return m_major==other.m_major&&m_minor==other.m_minor; } bool SageSession::VersionInfo::operator<(const SageSession::VersionInfo &other) const { return (m_major!= -1 && other.m_major==-1) || ( ((m_major!=-1 && other.m_major!=-1) || (m_major==other.m_major && m_major==-1) ) && ( m_major(const SageSession::VersionInfo& other) const { return !( (*this <= other )); } bool SageSession::VersionInfo::operator>=(const SageSession::VersionInfo& other) const { return !( *this < other); } SageSession::SageSession( Cantor::Backend* backend) : Session(backend) { qDebug(); m_isInitialized=false; m_haveSentInitCmd=false; connect( &m_dirWatch, SIGNAL( created( const QString& ) ), this, SLOT( fileCreated( const QString& ) ) ); } SageSession::~SageSession() { qDebug(); } void SageSession::login() { qDebug()<<"login"; emit loginStarted(); m_process=new KPtyProcess(this); m_process->setProgram(SageSettings::self()->path().toLocalFile()); m_process->setOutputChannelMode(KProcess::SeparateChannels); m_process->setPtyChannels(KPtyProcess::AllChannels); m_process->pty()->setEcho(false); connect(m_process->pty(), SIGNAL(readyRead()), this, SLOT(readStdOut())); connect(m_process, SIGNAL(readyReadStandardError()), this, SLOT(readStdErr())); connect(m_process, SIGNAL(finished ( int, QProcess::ExitStatus )), this, SLOT(processFinished(int, QProcess::ExitStatus))); connect(m_process, SIGNAL(error(QProcess::ProcessError)), this, SLOT(reportProcessError(QProcess::ProcessError))); m_process->start(); m_process->pty()->write(initCmd); if(!SageSettings::self()->autorunScripts().isEmpty()){ QString autorunScripts = SageSettings::self()->autorunScripts().join(QLatin1String("\n")); evaluateExpression(autorunScripts, SageExpression::DeleteOnFinish); } emit loginDone(); } void SageSession::logout() { qDebug()<<"logout"; disconnect(m_process, SIGNAL(finished ( int, QProcess::ExitStatus )), this, SLOT(processFinished(int, QProcess::ExitStatus))); m_process->pty()->write("exit\n"); m_process->kill(); //Run sage-cleaner to kill all the orphans KProcess::startDetached(SageSettings::self()->path().toLocalFile(),QStringList()<setFinishingBehavior(behave); expr->setCommand(cmd); expr->evaluate(); return expr; } void SageSession::appendExpressionToQueue(SageExpression* expr) { m_expressionQueue.append(expr); if(m_expressionQueue.size()==1) { changeStatus(Cantor::Session::Running); runFirstExpression(); } } void SageSession::readStdOut() { m_outputCache.append(QLatin1String(m_process->pty()->readAll())); qDebug()<<"out: "<path().toLocalFile()); get_sage_version.setArguments(QStringList()<2) { int major=version[1].toInt(); int minor=version[2].toInt(); m_sageVersion=SageSession::VersionInfo(major, minor); if(m_sageVersion<=SageSession::VersionInfo(5, 7)) { qDebug()<<"using an old version of sage: "<pty()->write(legacyInitCmd); defineCustomFunctions(); m_process->pty()->write(endOfInitMarker); m_haveSentInitCmd=true; } }else { qDebug()<<"using the current set of commands"; if(!m_haveSentInitCmd) { m_process->pty()->write(newInitCmd); defineCustomFunctions(); m_process->pty()->write(endOfInitMarker); m_haveSentInitCmd=true; } } } } int indexOfEOI=m_outputCache.indexOf(QLatin1String("____END_OF_INIT____")); if(indexOfEOI!=-1&&m_outputCache.indexOf(QLatin1String(SagePrompt), indexOfEOI)!=-1) { qDebug()<<"initialized"; //out.remove("____END_OF_INIT____"); //out.remove(SagePrompt); m_isInitialized=true; m_waitingForPrompt=false; runFirstExpression(); changeStatus(Cantor::Session::Done); m_outputCache.clear(); } //If we are waiting for another prompt, drop every output //until a prompt is found if(m_isInitialized&&m_waitingForPrompt) { qDebug()<<"waiting for prompt"; if(m_outputCache.contains(QLatin1String(SagePrompt))) m_waitingForPrompt=false; m_outputCache.clear(); return; } if(m_isInitialized&&!m_expressionQueue.isEmpty()) { SageExpression* expr=m_expressionQueue.first(); expr->parseOutput(m_outputCache); m_outputCache.clear(); } } void SageSession::readStdErr() { qDebug()<<"reading stdErr"; QString out=QLatin1String(m_process->readAllStandardError()); qDebug()<<"err: "<parseError(out); } } void SageSession::currentExpressionChangedStatus(Cantor::Expression::Status status) { if(status!=Cantor::Expression::Computing) //The session is ready for the next command { SageExpression* expr=m_expressionQueue.takeFirst(); - disconnect(expr, 0, this, 0); + disconnect(expr, nullptr, this, nullptr); if(m_expressionQueue.isEmpty()) changeStatus(Cantor::Session::Done); runFirstExpression(); } } void SageSession::processFinished(int exitCode, QProcess::ExitStatus exitStatus) { Q_UNUSED(exitCode); if(exitStatus==QProcess::CrashExit) { if(!m_expressionQueue.isEmpty()) { m_expressionQueue.last()->onProcessError(i18n("The Sage process crashed while evaluating this expression")); }else { //We don't have an actual command. it crashed for some other reason, just show a plain error message box - KMessageBox::error(0, i18n("The Sage process crashed"), i18n("Cantor")); + KMessageBox::error(nullptr, i18n("The Sage process crashed"), i18n("Cantor")); } }else { if(!m_expressionQueue.isEmpty()) { m_expressionQueue.last()->onProcessError(i18n("The Sage process exited while evaluating this expression")); }else { //We don't have an actual command. it crashed for some other reason, just show a plain error message box - KMessageBox::error(0, i18n("The Sage process exited"), i18n("Cantor")); + KMessageBox::error(nullptr, i18n("The Sage process exited"), i18n("Cantor")); } } } void SageSession::reportProcessError(QProcess::ProcessError e) { if(e==QProcess::FailedToStart) { changeStatus(Cantor::Session::Done); emit error(i18n("Failed to start Sage")); } } void SageSession::runFirstExpression() { if(!m_expressionQueue.isEmpty()&&m_isInitialized) { SageExpression* expr=m_expressionQueue.first(); connect(expr, SIGNAL(statusChanged(Cantor::Expression::Status)), this, SLOT(currentExpressionChangedStatus(Cantor::Expression::Status))); QString command=expr->command(); if(command.endsWith(QLatin1Char('?'))) command=QLatin1String("help(")+command.left(command.size()-1)+QLatin1Char(')'); if(command.startsWith(QLatin1Char('?'))) command=QLatin1String("help(")+command.mid(1)+QLatin1Char(')'); qDebug()<<"writing "<pty()->write(QString(command+QLatin1String("\n\n")).toUtf8()); } } void SageSession::interrupt() { if(!m_expressionQueue.isEmpty()) m_expressionQueue.first()->interrupt(); m_expressionQueue.clear(); changeStatus(Cantor::Session::Done); } void SageSession::sendSignalToProcess(int signal) { qDebug()<<"sending signal....."<bash->sage-ipython QString cmd=QString::fromLatin1("pkill -%1 -f -P `pgrep -P %2 bash` .*sage-ipython.*").arg(signal).arg(m_process->pid()); KProcess proc(this); proc.setShellCommand(cmd); proc.execute(); } void SageSession::sendInputToProcess(const QString& input) { m_process->pty()->write(input.toUtf8()); } void SageSession::waitForNextPrompt() { m_waitingForPrompt=true; } void SageSession::fileCreated( const QString& path ) { qDebug()<<"got a file "<addFileResult( path ); } void SageSession::setTypesettingEnabled(bool enable) { Cantor::Session::setTypesettingEnabled(enable); //tell the sage server to enable/disable pretty_print const QString cmd=QLatin1String("__cantor_enable_typesetting(%1)"); evaluateExpression(cmd.arg(enable ? QLatin1String("true"):QLatin1String("false")), Cantor::Expression::DeleteOnFinish); } Cantor::CompletionObject* SageSession::completionFor(const QString& command, int index) { return new SageCompletionObject(command, index, this); } QSyntaxHighlighter* SageSession::syntaxHighlighter(QObject* parent) { return new SageHighlighter(parent); } SageSession::VersionInfo SageSession::sageVersion() { return m_sageVersion; } void SageSession::defineCustomFunctions() { //typesetting QString cmd=QLatin1String("def __cantor_enable_typesetting(enable):\n"); if(m_sageVersion VersionInfo(5, 7) && m_sageVersion< VersionInfo(5, 12)) { cmd+=QLatin1String("\t sage.misc.latex.pretty_print_default(enable)\n\n"); }else { cmd+=QLatin1String("\t if(enable==true):\n "\ "\t \t %display typeset \n"\ "\t else: \n" \ "\t \t %display simple \n\n"); } sendInputToProcess(cmd); } diff --git a/src/backends/sage/testsage.cpp b/src/backends/sage/testsage.cpp index a22a22c4..c0db6a7b 100644 --- a/src/backends/sage/testsage.cpp +++ b/src/backends/sage/testsage.cpp @@ -1,121 +1,121 @@ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. --- Copyright (C) 2009 Alexander Rieder */ #include "testsage.h" #include "session.h" #include "backend.h" #include "expression.h" #include "result.h" #include "imageresult.h" #include QString TestSage::backendName() { return QLatin1String("sage"); } void TestSage::testSimpleCommand() { Cantor::Expression* e=evalExp( QLatin1String("2+2") ); - QVERIFY( e!=0 ); - QVERIFY( e->result()!=0 ); + QVERIFY( e!=nullptr ); + QVERIFY( e->result()!=nullptr ); QCOMPARE( e->result()->toHtml(), QLatin1String(("4")) ); } void TestSage::testCommandQueue() { //only wait for the last Expression to return, so the queue gets //actually filled Cantor::Expression* e1=session()->evaluateExpression(QLatin1String("0+1")); Cantor::Expression* e2=session()->evaluateExpression(QLatin1String("1+1")); Cantor::Expression* e3=evalExp(QLatin1String("1+2")); - QVERIFY(e1!=0); - QVERIFY(e2!=0); - QVERIFY(e3!=0); + QVERIFY(e1!=nullptr); + QVERIFY(e2!=nullptr); + QVERIFY(e3!=nullptr); QVERIFY(e1->result()); QVERIFY(e2->result()); QVERIFY(e3->result()); QCOMPARE(cleanOutput(e1->result()->toHtml()), QLatin1String("1")); QCOMPARE(cleanOutput(e2->result()->toHtml()), QLatin1String("2")); QCOMPARE(cleanOutput(e3->result()->toHtml()), QLatin1String("3")); } void TestSage::testMultilineCommand() { Cantor::Expression* e=evalExp( QLatin1String("2+2 \n simplify(1 - x + x)") ); - QVERIFY( e!=0 ); - QVERIFY( e->result()!=0 ); + QVERIFY( e!=nullptr ); + QVERIFY( e->result()!=nullptr ); QCOMPARE( e->result()->toHtml(), QLatin1String("4
\n1") ); } void TestSage::testDefineFunction() { const char* cmd="def func1(param) : \n" \ " return param*param\n\n"; Cantor::Expression* e1=evalExp( QLatin1String(cmd) ); - QVERIFY( e1!=0 ); - QVERIFY( e1->result()!=0 ); + QVERIFY( e1!=nullptr ); + QVERIFY( e1->result()!=nullptr ); Cantor::Expression* e2=evalExp( QLatin1String("func1(2)") ); - QVERIFY( e2!=0 ); - QVERIFY( e2->result()!=0 ); + QVERIFY( e2!=nullptr ); + QVERIFY( e2->result()!=nullptr ); QCOMPARE( e2->result()->toHtml(), QLatin1String("4") ); } void TestSage::testPlot() { Cantor::Expression* e=evalExp( QLatin1String("plot(sin(x))") ); - QVERIFY( e!=0 ); - QVERIFY( e->result()!=0 ); + QVERIFY( e!=nullptr ); + QVERIFY( e->result()!=nullptr ); QVERIFY( e->result()->type()==Cantor::ImageResult::Type ); QVERIFY( !e->result()->data().isNull() ); } void TestSage::testInvalidSyntax() { Cantor::Expression* e=evalExp( QLatin1String("2+2*(") ); - QVERIFY( e!=0 ); + QVERIFY( e!=nullptr ); QVERIFY( e->errorMessage()== QLatin1String("Syntax Error") ); } void TestSage::testNoOutput() { Cantor::Expression* e=evalExp( QLatin1String("f(x)=x^2+3*x+2\nf(0)") ); - QVERIFY( e!=0 ); - QVERIFY( e->result() != 0 ); + QVERIFY( e!=nullptr ); + QVERIFY( e->result() != nullptr ); QCOMPARE( e->result()->toHtml(), QLatin1String("2") ); } QTEST_MAIN( TestSage ) diff --git a/src/backends/scilab/scilabbackend.h b/src/backends/scilab/scilabbackend.h index d7e7d8fa..148fa863 100644 --- a/src/backends/scilab/scilabbackend.h +++ b/src/backends/scilab/scilabbackend.h @@ -1,47 +1,47 @@ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. --- Copyright (C) 2011 Filipe Saraiva */ #ifndef _SCILABBACKEND_H #define _SCILABBACKEND_H #include "backend.h" class ScilabBackend : public Cantor::Backend { Q_OBJECT public: - explicit ScilabBackend( QObject* parent = 0,const QList args = QList()); + explicit ScilabBackend( QObject* parent = nullptr,const QList args = QList()); ~ScilabBackend() override; QString id() const Q_DECL_OVERRIDE; QString version() const override; Cantor::Session *createSession() Q_DECL_OVERRIDE; Cantor::Backend::Capabilities capabilities() const Q_DECL_OVERRIDE; bool requirementsFullfilled() const Q_DECL_OVERRIDE; QWidget* settingsWidget(QWidget* parent) const Q_DECL_OVERRIDE; KConfigSkeleton* config() const Q_DECL_OVERRIDE; QUrl helpUrl() const Q_DECL_OVERRIDE; QString description() const Q_DECL_OVERRIDE; }; #endif /* _SCILABBACKEND_H */ diff --git a/src/backends/scilab/scilabkeywords.cpp b/src/backends/scilab/scilabkeywords.cpp index a2726863..d47b0700 100644 --- a/src/backends/scilab/scilabkeywords.cpp +++ b/src/backends/scilab/scilabkeywords.cpp @@ -1,116 +1,116 @@ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. --- Copyright (C) 2011 Filipe Saraiva */ #include "scilabkeywords.h" #include #include #include #include ScilabKeywords::ScilabKeywords() { qDebug() << "ScilabKeywords construtor"; } ScilabKeywords::~ScilabKeywords() { } ScilabKeywords* ScilabKeywords::instance() { - static ScilabKeywords* inst = 0; + static ScilabKeywords* inst = nullptr; - if(inst == 0){ + if(inst == nullptr){ inst = new ScilabKeywords(); qSort(inst->m_variables); qSort(inst->m_functions); qSort(inst->m_keywords); } return inst; } void ScilabKeywords::setupKeywords(QString keywords) { qDebug(); QStringList key; key = keywords.replace(QLatin1String(" !"), QLatin1String("\n")).replace(QLatin1String("!"), QLatin1String("")) .replace(QLatin1String(" "), QLatin1String("")).split(QLatin1String("\n")); for(int count = key.indexOf(QLatin1String("(1)")); key.at(count) != QLatin1String("(2)"); count++){ if(key.at(count) == QLatin1String("")){ continue; } qDebug() << key.at(count); m_functions << key.at(count); } for(int count = key.indexOf(QLatin1String("(2)")); key.at(count) != QLatin1String("(3)"); count++){ if(key.at(count) == QLatin1String("")){ continue; } qDebug() << key.at(count); m_keywords << key.at(count); } for(int count = key.indexOf(QLatin1String("(3)")); key.at(count) != QLatin1String("(4)"); count++){ if(key.at(count) == QLatin1String("")){ continue; } qDebug() << key.at(count); m_variables << key.at(count); } for(int count = key.indexOf(QLatin1String("(4)")); count < key.size(); count++){ if(key.at(count) == QLatin1String("")){ continue; } qDebug() << key.at(count); m_functions << key.at(count); } } void ScilabKeywords::addVariable(QString variable) { m_variables << variable; } const QStringList& ScilabKeywords::variables() const { return m_variables; } const QStringList& ScilabKeywords::functions() const { return m_functions; } const QStringList& ScilabKeywords::keywords() const { return m_keywords; } diff --git a/src/backends/scilab/scilabsession.cpp b/src/backends/scilab/scilabsession.cpp index 29860b6a..66d69d47 100644 --- a/src/backends/scilab/scilabsession.cpp +++ b/src/backends/scilab/scilabsession.cpp @@ -1,304 +1,304 @@ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. --- Copyright (C) 2011 Filipe Saraiva */ #include "scilabsession.h" #include "scilabexpression.h" #include "scilabhighlighter.h" #include "scilabkeywords.h" #include "scilabcompletionobject.h" #include #include #include #include #include #include #include #include #include #include #include ScilabSession::ScilabSession( Cantor::Backend* backend) : Session(backend), m_variableModel(new Cantor::DefaultVariableModel(this)) { - m_process = 0; + m_process = nullptr; qDebug(); } ScilabSession::~ScilabSession() { m_process->terminate(); qDebug(); } void ScilabSession::login() { qDebug()<<"login"; emit loginStarted(); QStringList args; args << QLatin1String("-nb"); m_process = new KProcess(this); m_process->setProgram(ScilabSettings::self()->path().toLocalFile(), args); qDebug() << m_process->program(); m_process->setOutputChannelMode(KProcess::SeparateChannels); m_process->start(); if(ScilabSettings::integratePlots()){ qDebug() << "integratePlots"; QString tempPath = QDir::tempPath(); QString pathScilabOperations = tempPath; pathScilabOperations.prepend(QLatin1String("chdir('")); pathScilabOperations.append(QLatin1String("');\n")); qDebug() << "Processing command to change chdir in Scilab. Command " << pathScilabOperations.toLocal8Bit(); m_process->write(pathScilabOperations.toLocal8Bit()); m_watch = new KDirWatch(this); m_watch->setObjectName(QLatin1String("ScilabDirWatch")); m_watch->addDir(tempPath, KDirWatch::WatchFiles); qDebug() << "addDir " << tempPath << "? " << m_watch->contains(QLatin1String(tempPath.toLocal8Bit())); QObject::connect(m_watch, &KDirWatch::created, this, &ScilabSession::plotFileChanged); } if(!ScilabSettings::self()->autorunScripts().isEmpty()){ QString autorunScripts = ScilabSettings::self()->autorunScripts().join(QLatin1String("\n")); m_process->write(autorunScripts.toLocal8Bit()); } QObject::connect(m_process, &KProcess::readyReadStandardOutput, this, &ScilabSession::listKeywords); QObject::connect(m_process, &KProcess::readyReadStandardError, this, &ScilabSession::readError); m_process->readAllStandardOutput().clear(); m_process->readAllStandardError().clear(); ScilabExpression *listKeywords = new ScilabExpression(this); listKeywords->setCommand(QLatin1String("disp(getscilabkeywords());")); runExpression(listKeywords); emit loginDone(); } void ScilabSession::logout() { qDebug()<<"logout"; m_process->write("exit\n"); m_runningExpressions.clear(); qDebug() << "m_runningExpressions: " << m_runningExpressions.isEmpty(); QDir removePlotFigures; QListIterator i(m_listPlotName); while(i.hasNext()){ removePlotFigures.remove(QLatin1String(i.next().toLocal8Bit().constData())); } } void ScilabSession::interrupt() { qDebug()<<"interrupt"; foreach(Cantor::Expression* e, m_runningExpressions) e->interrupt(); m_runningExpressions.clear(); changeStatus(Cantor::Session::Done); } Cantor::Expression* ScilabSession::evaluateExpression(const QString& cmd, Cantor::Expression::FinishingBehavior behave) { qDebug() << "evaluating: " << cmd; ScilabExpression* expr = new ScilabExpression(this); changeStatus(Cantor::Session::Running); expr->setFinishingBehavior(behave); expr->setCommand(cmd); expr->evaluate(); return expr; } void ScilabSession::runExpression(ScilabExpression* expr) { QString command; command.prepend(QLatin1String("\nprintf('begin-cantor-scilab-command-processing')\n")); command += expr->command(); m_currentExpression = expr; connect(m_currentExpression, &ScilabExpression::statusChanged, this, &ScilabSession::currentExpressionStatusChanged); command += QLatin1String("\nprintf('terminated-cantor-scilab-command-processing')\n"); qDebug() << "Writing command to process" << command; m_process->write(command.toLocal8Bit()); } void ScilabSession::expressionFinished() { qDebug()<<"finished"; ScilabExpression* expression = qobject_cast(sender()); m_runningExpressions.removeAll(expression); qDebug() << "size: " << m_runningExpressions.size(); } void ScilabSession::readError() { qDebug() << "readError"; QString error = QLatin1String(m_process->readAllStandardError()); qDebug() << "error: " << error; m_currentExpression->parseError(error); } void ScilabSession::readOutput() { qDebug() << "readOutput"; while(m_process->bytesAvailable() > 0){ m_output.append(QString::fromLocal8Bit(m_process->readLine())); } qDebug() << "output.isNull? " << m_output.isNull(); qDebug() << "output: " << m_output; if(status() != Running || m_output.isNull()){ return; } if(m_output.contains(QLatin1String("begin-cantor-scilab-command-processing")) && m_output.contains(QLatin1String("terminated-cantor-scilab-command-processing"))){ m_output.remove(QLatin1String("begin-cantor-scilab-command-processing")); m_output.remove(QLatin1String("terminated-cantor-scilab-command-processing")); m_currentExpression->parseOutput(m_output); m_output.clear(); } } void ScilabSession::plotFileChanged(QString filename) { qDebug() << "plotFileChanged filename:" << filename; if ((m_currentExpression) && (filename.contains(QLatin1String("cantor-export-scilab-figure")))){ qDebug() << "Calling parsePlotFile"; m_currentExpression->parsePlotFile(filename); m_listPlotName.append(filename); } } void ScilabSession::currentExpressionStatusChanged(Cantor::Expression::Status status) { qDebug() << "currentExpressionStatusChanged: " << status; switch (status){ case Cantor::Expression::Computing: break; case Cantor::Expression::Interrupted: break; case Cantor::Expression::Done: case Cantor::Expression::Error: changeStatus(Done); emit updateVariableHighlighter(); break; } } void ScilabSession::listKeywords() { qDebug(); while(m_process->bytesAvailable() > 0){ m_output.append(QString::fromLocal8Bit(m_process->readLine())); } if(m_output.contains(QLatin1String("begin-cantor-scilab-command-processing")) && m_output.contains(QLatin1String("terminated-cantor-scilab-command-processing"))){ m_output.remove(QLatin1String("begin-cantor-scilab-command-processing")); m_output.remove(QLatin1String("terminated-cantor-scilab-command-processing")); ScilabKeywords::instance()->setupKeywords(m_output); QObject::disconnect(m_process, &KProcess::readyReadStandardOutput, this, &ScilabSession::listKeywords); QObject::connect(m_process, &KProcess::readyReadStandardOutput, this, &ScilabSession::readOutput); m_process->readAllStandardOutput().clear(); m_process->readAllStandardError().clear(); m_output.clear(); } changeStatus(Done); m_currentExpression->evalFinished(); emit updateHighlighter(); } QSyntaxHighlighter* ScilabSession::syntaxHighlighter(QObject* parent) { qDebug(); ScilabHighlighter *highlighter = new ScilabHighlighter(parent); QObject::connect(this, &ScilabSession::updateHighlighter, highlighter, &ScilabHighlighter::updateHighlight); QObject::connect(this, &ScilabSession::updateVariableHighlighter, highlighter, &ScilabHighlighter::addVariableHighlight); return highlighter; } Cantor::CompletionObject* ScilabSession::completionFor(const QString& command, int index) { return new ScilabCompletionObject(command, index, this); } QAbstractItemModel* ScilabSession::variableModel() { return m_variableModel; } diff --git a/src/cantor.cpp b/src/cantor.cpp index f9d343fc..b00592dd 100644 --- a/src/cantor.cpp +++ b/src/cantor.cpp @@ -1,584 +1,584 @@ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. --- Copyright (C) 2009 Alexander Rieder */ #include "cantor.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "lib/backend.h" #include "lib/panelpluginhandler.h" #include "lib/panelplugin.h" #include "lib/worksheetaccess.h" #include "settings.h" #include "ui_settings.h" #include "backendchoosedialog.h" CantorShell::CantorShell() : KParts::MainWindow( ) { - m_part=0; + m_part=nullptr; // set the shell's ui resource file setXMLFile(QLatin1String("cantor_shell.rc")); // then, setup our actions setupActions(); - createGUI(0); + createGUI(nullptr); m_tabWidget=new QTabWidget(this); m_tabWidget->setTabsClosable(true); m_tabWidget->setMovable(true); m_tabWidget->setDocumentMode(true); setCentralWidget(m_tabWidget); connect(m_tabWidget, SIGNAL(currentChanged(int)), this, SLOT(activateWorksheet(int))); connect(m_tabWidget, SIGNAL(tabCloseRequested(int)), this, SLOT(closeTab(int))); // apply the saved mainwindow settings, if any, and ask the mainwindow // to automatically save settings if changed: window size, toolbar // position, icon size, etc. setAutoSaveSettings(); setDockOptions(QMainWindow::AnimatedDocks|QMainWindow::AllowTabbedDocks|QMainWindow::VerticalTabs); } CantorShell::~CantorShell() { } void CantorShell::load(const QUrl &url) { if (!m_part||!m_part->url().isEmpty() || m_part->isModified() ) { addWorksheet(QLatin1String("null")); m_tabWidget->setCurrentIndex(m_parts.size()-1); } m_part->openUrl( url ); } bool CantorShell::hasAvailableBackend() { bool hasBackend=false; foreach(Cantor::Backend* b, Cantor::Backend::availableBackends()) { if(b->isEnabled()) hasBackend=true; } return hasBackend; } void CantorShell::setupActions() { QAction* openNew = KStandardAction::openNew(this, SLOT(fileNew()), actionCollection()); openNew->setPriority(QAction::LowPriority); QAction* open = KStandardAction::open(this, SLOT(fileOpen()), actionCollection()); open->setPriority(QAction::LowPriority); KStandardAction::close (this, SLOT(closeTab()), actionCollection()); KStandardAction::quit(qApp, SLOT(closeAllWindows()), actionCollection()); createStandardStatusBarAction(); //setStandardToolBarMenuEnabled(true); KStandardAction::keyBindings(this, SLOT(optionsConfigureKeys()), actionCollection()); KStandardAction::configureToolbars(this, SLOT(configureToolbars()), actionCollection()); KStandardAction::preferences(this, SLOT(showSettings()), actionCollection()); QAction * downloadExamples = new QAction(i18n("Download Example Worksheets"), actionCollection()); downloadExamples->setIcon(QIcon::fromTheme(QLatin1String("get-hot-new-stuff"))); actionCollection()->addAction(QLatin1String("file_example_download"), downloadExamples); connect(downloadExamples, SIGNAL(triggered()), this, SLOT(downloadExamples())); QAction * openExample =new QAction(i18n("&Open Example"), actionCollection()); openExample->setIcon(QIcon::fromTheme(QLatin1String("document-open"))); actionCollection()->addAction(QLatin1String("file_example_open"), openExample); connect(openExample, SIGNAL(triggered()), this, SLOT(openExample())); } void CantorShell::saveProperties(KConfigGroup & /*config*/) { // the 'config' object points to the session managed // config file. anything you write here will be available // later when this app is restored } void CantorShell::readProperties(const KConfigGroup & /*config*/) { // the 'config' object points to the session managed // config file. this function is automatically called whenever // the app is being restored. read in here whatever you wrote // in 'saveProperties' } void CantorShell::fileNew() { if (sender()->inherits("QAction")) { QAction * a = qobject_cast(sender()); QString backendName = a->data().toString(); if (!backendName.isEmpty()) { addWorksheet(backendName); return; } } addWorksheet(); } void CantorShell::optionsConfigureKeys() { KShortcutsDialog dlg( KShortcutsEditor::AllActions, KShortcutsEditor::LetterShortcutsDisallowed, this ); dlg.addCollection( actionCollection(), i18n("Cantor") ); dlg.addCollection( m_part->actionCollection(), i18n("Cantor") ); dlg.configure( true ); } void CantorShell::fileOpen() { // this slot is called whenever the File->Open menu is selected, // the Open shortcut is pressed (usually CTRL+O) or the Open toolbar // button is clicked QUrl url = QFileDialog::getOpenFileUrl(this, i18n("Open file"), QUrl(), i18n("*.cws|Cantor Worksheet")); if (url.isEmpty() == false) { // About this function, the style guide ( // http://developer.kde.org/documentation/standards/kde/style/basics/index.html ) // says that it should open a new window if the document is _not_ // in its initial state. This is what we do here.. /*if ( m_part->url().isEmpty() && ! m_part->isModified() ) { // we open the file in this window... load( url ); } else { // we open the file in a new window... CantorShell* newWin = new CantorShell; newWin->load( url ); newWin->show(); }*/ load( url ); } } void CantorShell::addWorksheet() { if(hasAvailableBackend()) //There is no point in asking for the backend, if no one is available { QString backend = Settings::self()->defaultBackend(); if (backend.isEmpty()) { QPointer dlg=new BackendChooseDialog(this); if(dlg->exec()) { backend = dlg->backendName(); addWorksheet(backend); } delete dlg; } else { addWorksheet(backend); } }else { QTextBrowser *browser=new QTextBrowser(this); QString backendList=QLatin1String("
    "); int backendListSize = 0; foreach(Cantor::Backend* b, Cantor::Backend::availableBackends()) { if(!b->requirementsFullfilled()) //It's disabled because of misssing dependencies, not because of some other reason(like eg. nullbackend) { backendList+=QString::fromLatin1("
  • %1: %2
  • ").arg(b->name(), b->url()); ++backendListSize; } } browser->setHtml(i18np("

    No Backend Found

    \n" \ "
    You could try:\n" \ "
      " \ "
    • Changing the settings in the config dialog;
    • " \ "
    • Installing packages for the following program:
    • " \ " %2 " \ "
    " \ "
    " , "

    No Backend Found

    \n" \ "
    You could try:\n" \ "
      " \ "
    • Changing the settings in the config dialog;
    • " \ "
    • Installing packages for one of the following programs:
    • " \ " %2 " \ "
    " \ "
    " , backendListSize, backendList )); browser->setObjectName(QLatin1String("ErrorMessage")); m_tabWidget->addTab(browser, i18n("Error")); } } void CantorShell::addWorksheet(const QString& backendName) { static int sessionCount=1; // this routine will find and load our Part. it finds the Part by // name which is a bad idea usually.. but it's alright in this // case since our Part is made for this Shell KPluginFactory* factory = KPluginLoader(QLatin1String("libcantorpart")).factory(); if (factory) { // now that the Part is loaded, we cast it to a Part to get // our hands on it KParts::ReadWritePart* part = factory->create(m_tabWidget, QVariantList()<addTab(part->widget(), i18n("Session %1", sessionCount++)); m_tabWidget->setCurrentIndex(tab); } else { qDebug()<<"error creating part "; } } else { // if we couldn't find our Part, we exit since the Shell by // itself can't do anything useful KMessageBox::error(this, i18n("Could not find the Cantor Part.")); qApp->quit(); // we return here, cause qApp->quit() only means "exit the // next time we enter the event loop... return; } } void CantorShell::activateWorksheet(int index) { QObject* pluginHandler=m_part->findChild(QLatin1String("PanelPluginHandler")); disconnect(pluginHandler,SIGNAL(pluginsChanged()), this, SLOT(updatePanel())); m_part=findPart(m_tabWidget->widget(index)); if(m_part) { createGUI(m_part); QObject* pluginHandler=m_part->findChild(QLatin1String("PanelPluginHandler")); connect(pluginHandler, SIGNAL(pluginsChanged()), this, SLOT(updatePanel())); updatePanel(); } else qDebug()<<"selected part doesn't exist"; m_tabWidget->setCurrentIndex(index); } void CantorShell::setTabCaption(const QString& caption) { if (caption.isEmpty()) return; KParts::ReadWritePart* part=dynamic_cast(sender()); m_tabWidget->setTabText(m_tabWidget->indexOf(part->widget()), caption); } void CantorShell::closeTab(int index) { if (!reallyClose(false)) { return; } QWidget* widget = nullptr; if (index >= 0) { widget = m_tabWidget->widget(index); } else if (m_part) { widget = m_part->widget(); } if (!widget) { qWarning() << "Could not find widget by tab index" << index; return; } m_tabWidget->removeTab(index); if(widget->objectName()==QLatin1String("ErrorMessage")) { widget->deleteLater(); }else { KParts::ReadWritePart* part= findPart(widget); if(part) { m_parts.removeAll(part); delete part; } } } bool CantorShell::reallyClose(bool checkAllParts) { if(checkAllParts && m_parts.count() > 1) { bool modified = false; foreach( KParts::ReadWritePart* const part, m_parts) { if(part->isModified()) { modified = true; break; } } if(!modified) return true; int want_save = KMessageBox::warningYesNo( this, i18n("Multiple unsaved Worksheets are opened. Do you want to close them?"), i18n("Close Cantor")); switch (want_save) { case KMessageBox::Yes: return true; case KMessageBox::No: return false; } } if (m_part && m_part->isModified() ) { int want_save = KMessageBox::warningYesNoCancel( this, i18n("The current project has been modified. Do you want to save it?"), i18n("Save Project")); switch (want_save) { case KMessageBox::Yes: m_part->save(); if(m_part->waitSaveComplete()) { return true; } else { m_part->setModified(true); return false; } case KMessageBox::Cancel: return false; case KMessageBox::No: return true; } } return true; } void CantorShell::closeEvent(QCloseEvent* event) { if(!reallyClose()) { event->ignore(); } else { KParts::MainWindow::closeEvent(event); } } void CantorShell::showSettings() { KConfigDialog *dialog = new KConfigDialog(this, QLatin1String("settings"), Settings::self()); QWidget *generalSettings = new QWidget; Ui::SettingsBase base; base.setupUi(generalSettings); base.kcfg_DefaultBackend->addItems(Cantor::Backend::listAvailableBackends()); dialog->addPage(generalSettings, i18n("General"), QLatin1String("preferences-other")); foreach(Cantor::Backend* backend, Cantor::Backend::availableBackends()) { if (backend->config()) //It has something to configure, so add it to the dialog dialog->addPage(backend->settingsWidget(dialog), backend->config(), backend->name(), backend->icon()); } dialog->show(); } void CantorShell::downloadExamples() { KNS3::DownloadDialog dialog; dialog.exec(); foreach (const KNS3::Entry& e, dialog.changedEntries()) { qDebug() << "Changed Entry: " << e.name(); } } void CantorShell::openExample() { QString dir = QStandardPaths::writableLocation(QStandardPaths::DataLocation) + QLatin1String("/examples"); if (dir.isEmpty()) return; QDir().mkpath(dir); QStringList files=QDir(dir).entryList(QDir::Files); QPointer dlg=new QDialog(this); QListWidget* list=new QListWidget(dlg); foreach(const QString& file, files) { QString name=file; name.remove(QRegExp(QLatin1String("-.*\\.hotstuff-access$"))); list->addItem(name); } QVBoxLayout *mainLayout = new QVBoxLayout; dlg->setLayout(mainLayout); mainLayout->addWidget(list); QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); mainLayout->addWidget(buttonBox); buttonBox->button(QDialogButtonBox::Ok)->setIcon(QApplication::style()->standardIcon(QStyle::SP_DialogOkButton)); buttonBox->button(QDialogButtonBox::Cancel)->setIcon(QApplication::style()->standardIcon(QStyle::SP_DialogCancelButton)); connect(buttonBox, SIGNAL(accepted()), dlg, SLOT(accept()) ); connect(buttonBox, SIGNAL(rejected()), dlg, SLOT(reject()) ); if (dlg->exec()==QDialog::Accepted&&list->currentRow()>=0) { const QString& selectedFile=files[list->currentRow()]; QUrl url = QUrl::fromLocalFile(QDir(dir).absoluteFilePath(selectedFile)); qDebug()<<"loading file "<widget()==widget) return part; } - return 0; + return nullptr; } void CantorShell::updatePanel() { qDebug()<<"updating panels"; unplugActionList(QLatin1String("view_show_panel_list")); //remove all of the previous panels (but do not delete the widgets) foreach(QDockWidget* dock, m_panels) { QWidget* widget=dock->widget(); - if(widget!=0) + if(widget!=nullptr) { widget->setParent(this); widget->hide(); } dock->deleteLater(); } m_panels.clear(); QList panelActions; Cantor::PanelPluginHandler* handler=m_part->findChild(QLatin1String("PanelPluginHandler")); if(!handler) { qDebug()<<"no PanelPluginHandle found for this part"; return; } - QDockWidget* last=0; + QDockWidget* last=nullptr; QList plugins=handler->plugins(); foreach(Cantor::PanelPlugin* plugin, plugins) { - if(plugin==0) + if(plugin==nullptr) { qDebug()<<"somethings wrong"; continue; } qDebug()<<"adding panel for "<name(); plugin->setParentWidget(this); QDockWidget* docker=new QDockWidget(plugin->name(), this); docker->setObjectName(plugin->name()); docker->setWidget(plugin->widget()); addDockWidget ( Qt::RightDockWidgetArea, docker ); - if(last!=0) + if(last!=nullptr) tabifyDockWidget(last, docker); last=docker; connect(plugin, SIGNAL(visibilityRequested()), docker, SLOT(raise())); m_panels.append(docker); //Create the action to show/hide this panel panelActions<toggleViewAction(); } plugActionList(QLatin1String("view_show_panel_list"), panelActions); unplugActionList(QLatin1String("new_worksheet_with_backend_list")); QList newBackendActions; foreach (Cantor::Backend* backend, Cantor::Backend::availableBackends()) { if (!backend->isEnabled()) continue; - QAction * action = new QAction(QIcon::fromTheme(backend->icon()), backend->name(), 0); + QAction * action = new QAction(QIcon::fromTheme(backend->icon()), backend->name(), nullptr); action->setData(backend->name()); connect(action, SIGNAL(triggered()), this, SLOT(fileNew())); newBackendActions << action; } plugActionList(QLatin1String("new_worksheet_with_backend_list"), newBackendActions); } Cantor::WorksheetAccessInterface* CantorShell::currentWorksheetAccessInterface() { Cantor::WorksheetAccessInterface* wa=m_part->findChild(Cantor::WorksheetAccessInterface::Name); if (!wa) qDebug()<<"failed to access worksheet access interface for current part"; return wa; } diff --git a/src/cantor_part.cpp b/src/cantor_part.cpp index a6ede493..eee703c0 100644 --- a/src/cantor_part.cpp +++ b/src/cantor_part.cpp @@ -1,882 +1,882 @@ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. --- Copyright (C) 2009 Alexander Rieder */ #include "cantor_part.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "worksheet.h" #include "worksheetview.h" #include "searchbar.h" #include "scripteditorwidget.h" #include "lib/backend.h" #include "lib/extension.h" #include "lib/assistant.h" #include "lib/panelpluginhandler.h" #include "lib/panelplugin.h" #include "lib/worksheetaccess.h" #include "settings.h" //A concrete implementation of the WorksheetAccesssInterface class WorksheetAccessInterfaceImpl : public Cantor::WorksheetAccessInterface { //Q_OBJECT public: WorksheetAccessInterfaceImpl(QObject* parent, Worksheet* worksheet) : WorksheetAccessInterface(parent), m_worksheet(worksheet) { qDebug()<<"new worksheetaccess interface"; connect(worksheet, SIGNAL(sessionChanged()), this, SIGNAL(sessionChanged())); } ~WorksheetAccessInterfaceImpl() override { } QByteArray saveWorksheetToByteArray() Q_DECL_OVERRIDE { return m_worksheet->saveToByteArray(); } void loadWorksheetFromByteArray(QByteArray* data) Q_DECL_OVERRIDE { m_worksheet->load(data); } Cantor::Session* session() Q_DECL_OVERRIDE { return m_worksheet->session(); } // public Q_SLOTS: void evaluate() Q_DECL_OVERRIDE { m_worksheet->evaluate(); } void interrupt() Q_DECL_OVERRIDE { m_worksheet->interrupt(); } private: Worksheet* m_worksheet; }; CantorPart::CantorPart( QWidget *parentWidget, QObject *parent, const QVariantList & args ): KParts::ReadWritePart(parent) { - m_showBackendHelp=0; - m_initProgressDlg=0; + m_showBackendHelp=nullptr; + m_initProgressDlg=nullptr; m_statusBarBlocked=false; m_showProgressDlg=true; qDebug()<<"Created a CantorPart"; m_panelHandler=new Cantor::PanelPluginHandler(this); connect(m_panelHandler, SIGNAL(pluginsChanged()), this, SLOT(pluginsChanged())); QString backendName; if(args.isEmpty()) backendName=QLatin1String("null"); else backendName=args.first().toString(); foreach(const QVariant& arg, args) { if (arg.toString() == QLatin1String("--noprogress") ) { qWarning()<<"not showing the progress bar by request"; m_showProgressDlg=false; } } Cantor::Backend* b=Cantor::Backend::createBackend(backendName); if(!b) { KMessageBox::error(parentWidget, i18n("Backend %1 is not installed", backendName), i18n("Error - Cantor")); setWidget(new QWidget(parentWidget)); //fake being modified so the shell won't try to reuse this part ReadWritePart::setModified(true); return; } qDebug()<<"Backend "<name()<<" offers extensions: "<extensions(); QWidget* widget = new QWidget(parentWidget); QVBoxLayout* layout = new QVBoxLayout(widget); m_worksheet=new Worksheet(b, widget); m_worksheetview=new WorksheetView(m_worksheet, widget); m_worksheetview->setEnabled(false); //disable input until the session has successfully logged in and emits the ready signal connect(m_worksheet, SIGNAL(modified()), this, SLOT(setModified())); connect(m_worksheet, SIGNAL(showHelp(const QString&)), this, SIGNAL(showHelp(const QString&))); connect(m_worksheet, SIGNAL(sessionChanged()), this, SLOT(worksheetSessionChanged())); connect(actionCollection(), SIGNAL(inserted(QAction*)), m_worksheet, SLOT(registerShortcut(QAction*))); - m_searchBar = 0; + m_searchBar = nullptr; layout->addWidget(m_worksheetview); // notify the part that this is our internal widget setWidget(widget); Cantor::WorksheetAccessInterface* iface=new WorksheetAccessInterfaceImpl(this, m_worksheet); // create our actions m_worksheet->createActions(actionCollection()); KStandardAction::saveAs(this, SLOT(fileSaveAs()), actionCollection()); m_save = KStandardAction::save(this, SLOT(save()), actionCollection()); m_save->setPriority(QAction::LowPriority); QAction * savePlain=new QAction(i18n("Save Plain Text"), actionCollection()); actionCollection()->addAction(QLatin1String("file_save_plain"), savePlain); savePlain->setIcon(QIcon::fromTheme(QLatin1String("document-save"))); connect(savePlain, SIGNAL(triggered()), this, SLOT(fileSavePlain())); QAction * undo=KStandardAction::undo(m_worksheet, SIGNAL(undo()), actionCollection()); undo->setPriority(QAction::LowPriority); connect(m_worksheet, SIGNAL(undoAvailable(bool)), undo, SLOT(setEnabled(bool))); QAction * redo=KStandardAction::redo(m_worksheet, SIGNAL(redo()), actionCollection()); redo->setPriority(QAction::LowPriority); connect(m_worksheet, SIGNAL(redoAvailable(bool)), redo, SLOT(setEnabled(bool))); QAction * cut=KStandardAction::cut(m_worksheet, SIGNAL(cut()), actionCollection()); cut->setPriority(QAction::LowPriority); connect(m_worksheet, SIGNAL(cutAvailable(bool)), cut, SLOT(setEnabled(bool))); QAction * copy=KStandardAction::copy(m_worksheet, SIGNAL(copy()), actionCollection()); copy->setPriority(QAction::LowPriority); connect(m_worksheet, SIGNAL(copyAvailable(bool)), copy, SLOT(setEnabled(bool))); QAction * paste=KStandardAction::paste(m_worksheet, SIGNAL(paste()), actionCollection()); paste->setPriority(QAction::LowPriority); connect(m_worksheet, SIGNAL(pasteAvailable(bool)), paste, SLOT(setEnabled(bool))); QAction * find=KStandardAction::find(this, SLOT(showSearchBar()), actionCollection()); find->setPriority(QAction::LowPriority); QAction * replace=KStandardAction::replace(this, SLOT(showExtendedSearchBar()), actionCollection()); replace->setPriority(QAction::LowPriority); m_findNext = KStandardAction::findNext(this, SLOT(findNext()), actionCollection()); m_findNext->setEnabled(false); m_findPrev = KStandardAction::findPrev(this, SLOT(findPrev()), actionCollection()); m_findPrev->setEnabled(false); QAction * latexExport=new QAction(i18n("Export to LaTeX"), actionCollection()); actionCollection()->addAction(QLatin1String("file_export_latex"), latexExport); latexExport->setIcon(QIcon::fromTheme(QLatin1String("document-export"))); connect(latexExport, SIGNAL(triggered()), this, SLOT(exportToLatex())); QAction * print = KStandardAction::print(this, SLOT(print()), actionCollection()); print->setPriority(QAction::LowPriority); QAction * printPreview = KStandardAction::printPreview(this, SLOT(printPreview()), actionCollection()); printPreview->setPriority(QAction::LowPriority); KStandardAction::zoomIn(m_worksheetview, SLOT(zoomIn()), actionCollection()); KStandardAction::zoomOut(m_worksheetview, SLOT(zoomOut()), actionCollection()); m_evaluate=new QAction(i18n("Evaluate Worksheet"), actionCollection()); actionCollection()->addAction(QLatin1String("evaluate_worksheet"), m_evaluate); m_evaluate->setIcon(QIcon::fromTheme(QLatin1String("system-run"))); connect(m_evaluate, SIGNAL(triggered()), this, SLOT(evaluateOrInterrupt())); m_typeset=new KToggleAction(i18n("Typeset using LaTeX"), actionCollection()); m_typeset->setChecked(Settings::self()->typesetDefault()); actionCollection()->addAction(QLatin1String("enable_typesetting"), m_typeset); connect(m_typeset, SIGNAL(toggled(bool)), this, SLOT(enableTypesetting(bool))); m_highlight=new KToggleAction(i18n("Syntax Highlighting"), actionCollection()); m_highlight->setChecked(Settings::self()->highlightDefault()); actionCollection()->addAction(QLatin1String("enable_highlighting"), m_highlight); connect(m_highlight, SIGNAL(toggled(bool)), m_worksheet, SLOT(enableHighlighting(bool))); m_completion=new KToggleAction(i18n("Completion"), actionCollection()); m_completion->setChecked(Settings::self()->completionDefault()); actionCollection()->addAction(QLatin1String("enable_completion"), m_completion); connect(m_completion, SIGNAL(toggled(bool)), m_worksheet, SLOT(enableCompletion(bool))); m_exprNumbering=new KToggleAction(i18n("Line Numbers"), actionCollection()); m_exprNumbering->setChecked(Settings::self()->expressionNumberingDefault()); actionCollection()->addAction(QLatin1String("enable_expression_numbers"), m_exprNumbering); connect(m_exprNumbering, SIGNAL(toggled(bool)), m_worksheet, SLOT(enableExpressionNumbering(bool))); m_animateWorksheet=new KToggleAction(i18n("Animate Worksheet"), actionCollection()); m_animateWorksheet->setChecked(Settings::self()->animationDefault()); actionCollection()->addAction(QLatin1String("enable_animations"), m_animateWorksheet); connect(m_animateWorksheet, SIGNAL(toggled(bool)), m_worksheet, SLOT(enableAnimations(bool))); QAction * restart=new QAction(i18n("Restart Backend"), actionCollection()); actionCollection()->addAction(QLatin1String("restart_backend"), restart); restart->setIcon(QIcon::fromTheme(QLatin1String("system-reboot"))); connect(restart, SIGNAL(triggered()), this, SLOT(restartBackend())); QAction * evaluateCurrent=new QAction(i18n("Evaluate Entry"), actionCollection()); actionCollection()->addAction(QLatin1String("evaluate_current"), evaluateCurrent); actionCollection()->setDefaultShortcut(evaluateCurrent, Qt::SHIFT + Qt::Key_Return); connect(evaluateCurrent, SIGNAL(triggered()), m_worksheet, SLOT(evaluateCurrentEntry())); QAction * insertCommandEntry=new QAction(i18n("Insert Command Entry"), actionCollection()); actionCollection()->addAction(QLatin1String("insert_command_entry"), insertCommandEntry); actionCollection()->setDefaultShortcut(insertCommandEntry, Qt::CTRL + Qt::Key_Return); connect(insertCommandEntry, SIGNAL(triggered()), m_worksheet, SLOT(insertCommandEntry())); QAction * insertTextEntry=new QAction(i18n("Insert Text Entry"), actionCollection()); actionCollection()->addAction(QLatin1String("insert_text_entry"), insertTextEntry); connect(insertTextEntry, SIGNAL(triggered()), m_worksheet, SLOT(insertTextEntry())); QAction * insertLatexEntry=new QAction(i18n("Insert Latex Entry"), actionCollection()); actionCollection()->addAction(QLatin1String("insert_latex_entry"), insertLatexEntry); connect(insertLatexEntry, SIGNAL(triggered()), m_worksheet, SLOT(insertLatexEntry())); QAction * insertPageBreakEntry=new QAction(i18n("Insert Page Break"), actionCollection()); actionCollection()->addAction(QLatin1String("insert_page_break_entry"), insertPageBreakEntry); connect(insertPageBreakEntry, SIGNAL(triggered()), m_worksheet, SLOT(insertPageBreakEntry())); QAction * insertImageEntry=new QAction(i18n("Insert Image"), actionCollection()); actionCollection()->addAction(QLatin1String("insert_image_entry"), insertImageEntry); connect(insertImageEntry, SIGNAL(triggered()), m_worksheet, SLOT(insertImageEntry())); /* QAction * insertCommandEntryBefore=new QAction(i18n("Insert Command Entry Before"), actionCollection()); //insertCommandEntryBefore->setShortcut(Qt::CTRL + Qt::Key_Return); actionCollection()->addAction("insert_command_entry_before", insertCommandEntryBefore); connect(insertCommandEntryBefore, SIGNAL(triggered()), m_worksheet, SLOT(insertCommandEntryBefore())); QAction * insertTextEntryBefore=new QAction(i18n("Insert Text Entry Before"), actionCollection()); //insertTextEntryBefore->setShortcut(Qt::CTRL + Qt::Key_Return); actionCollection()->addAction("insert_text_entry_before", insertTextEntryBefore); connect(insertTextEntryBefore, SIGNAL(triggered()), m_worksheet, SLOT(insertTextEntryBefore())); QAction * insertPageBreakEntryBefore=new QAction(i18n("Insert Page Break Before"), actionCollection()); actionCollection()->addAction("insert_page_break_entry_before", insertPageBreakEntryBefore); connect(insertPageBreakEntryBefore, SIGNAL(triggered()), m_worksheet, SLOT(insertPageBreakEntryBefore())); QAction * insertImageEntryBefore=new QAction(i18n("Insert Image Entry Before"), actionCollection()); //insertTextEntryBefore->setShortcut(Qt::CTRL + Qt::Key_Return); actionCollection()->addAction("insert_image_entry_before", insertImageEntryBefore); connect(insertImageEntryBefore, SIGNAL(triggered()), m_worksheet, SLOT(insertImageEntryBefore())); */ QAction * removeCurrent=new QAction(i18n("Remove current Entry"), actionCollection()); actionCollection()->addAction(QLatin1String("remove_current"), removeCurrent); actionCollection()->setDefaultShortcut(removeCurrent, Qt::ShiftModifier + Qt::Key_Delete); connect(removeCurrent, SIGNAL(triggered()), m_worksheet, SLOT(removeCurrentEntry())); m_showBackendHelp=new QAction(i18n("Show %1 Help", b->name()) , actionCollection()); m_showBackendHelp->setIcon(QIcon::fromTheme(QLatin1String("help-contents"))); actionCollection()->addAction(QLatin1String("backend_help"), m_showBackendHelp); connect(m_showBackendHelp, SIGNAL(triggered()), this, SLOT(showBackendHelp())); QAction * publishWorksheet=new QAction(i18n("Publish Worksheet"), actionCollection()); publishWorksheet->setIcon(QIcon::fromTheme(QLatin1String("get-hot-new-stuff"))); actionCollection()->addAction(QLatin1String("file_publish_worksheet"), publishWorksheet); connect(publishWorksheet, SIGNAL(triggered()), this, SLOT(publishWorksheet())); KToggleAction* showEditor=new KToggleAction(i18n("Show Script Editor"), actionCollection()); showEditor->setChecked(false); actionCollection()->addAction(QLatin1String("show_editor"), showEditor); connect(showEditor, SIGNAL(toggled(bool)), this, SLOT(showScriptEditor(bool))); showEditor->setEnabled(b->extensions().contains(QLatin1String("ScriptExtension"))); QAction * showCompletion=new QAction(i18n("Show Completion"), actionCollection()); actionCollection()->addAction(QLatin1String("show_completion"), showCompletion); QList showCompletionShortcuts; showCompletionShortcuts << Qt::Key_Tab << Qt::CTRL + Qt::Key_Space; actionCollection()->setDefaultShortcuts(showCompletion, showCompletionShortcuts); connect(showCompletion, SIGNAL(triggered()), m_worksheet, SLOT(showCompletion())); // set our XML-UI resource file setXMLFile(QLatin1String("cantor_part.rc")); // we are read-write by default setReadWrite(true); // we are not modified since we haven't done anything yet setModified(false); worksheetSessionChanged(); } CantorPart::~CantorPart() { if (m_scriptEditor) { disconnect(m_scriptEditor, SIGNAL(destroyed()), this, SLOT(scriptEditorClosed())); delete m_scriptEditor; } if (m_searchBar) delete m_searchBar; } void CantorPart::setReadWrite(bool rw) { // notify your internal widget of the read-write state m_worksheetview->setInteractive(rw); ReadWritePart::setReadWrite(rw); } void CantorPart::setModified(bool modified) { // get a handle on our Save action and make sure it is valid if (!m_save) return; // if so, we either enable or disable it based on the current // state if (modified) m_save->setEnabled(true); else m_save->setEnabled(false); // in any event, we want our parent to do it's thing ReadWritePart::setModified(modified); } KAboutData& CantorPart::createAboutData() { // the non-i18n name here must be the same as the directory in // which the part's rc file is installed ('partrcdir' in the // Makefile) static KAboutData about(QLatin1String("cantorpart"), QLatin1String("Cantor"), QLatin1String(CANTOR_VERSION), i18n("CantorPart"), KAboutLicense::GPL, i18n("(C) 2009-2015 Alexander Rieder"), QString(), QLatin1String("http://edu.kde.org/cantor")); about.addAuthor( i18n("Alexander Rieder"), QString(), QLatin1String("alexanderrieder@gmail.com") ); return about; } bool CantorPart::openFile() { //don't crash if for some reason the worksheet is invalid - if(m_worksheet==0) + if(m_worksheet==nullptr) { qWarning()<<"trying to open in an invalid cantor part"; return false; } m_worksheet->load(localFilePath()); // just for fun, set the status bar //setStatusMessage( m_url.prettyUrl() ); updateCaption(); return true; } bool CantorPart::saveFile() { // if we aren't read-write, return immediately if (isReadWrite() == false) return false; qDebug()<<"saving to: "<save( localFilePath() ); setModified(false); return true; } void CantorPart::fileSaveAs() { // this slot is called whenever the File->Save As menu is selected QString worksheetFilter = i18n("Cantor Worksheet (*.cws)"); QString filter = worksheetFilter; //if the backend supports scripts, also append their scriptFile endings to the filter Cantor::Backend * const backend=m_worksheet->session()->backend(); if (backend->extensions().contains(QLatin1String("ScriptExtension"))) { Cantor::ScriptExtension* e=dynamic_cast(backend->extension(QLatin1String("ScriptExtension"))); filter+=QLatin1Char('\n')+e->scriptFileFilter(); } QString selectedFilter; QString file_name = QFileDialog::getSaveFileName(widget(), i18n("Save as"), QString(), filter, &selectedFilter); if (file_name.isEmpty()) return; //depending on user's selection, save as a worksheet or as a plain script file if (selectedFilter == worksheetFilter) saveAs(QUrl::fromLocalFile(file_name)); else m_worksheet->savePlain(file_name); updateCaption(); } void CantorPart::fileSavePlain() { QString file_name = QFileDialog::getSaveFileName(widget(), i18n("Save"), QString(), QString()); if (!file_name.isEmpty()) m_worksheet->savePlain(file_name); } void CantorPart::exportToLatex() { // this slot is called whenever the File->Save As menu is selected, QString filter=i18n("*.tex|LaTeX Document"); QString file_name = QFileDialog::getSaveFileName(widget(), i18n("Export to LaTeX"), QString(), QString()); if (file_name.isEmpty() == false) m_worksheet->saveLatex(file_name); } void CantorPart::guiActivateEvent( KParts::GUIActivateEvent * event ) { KParts::ReadWritePart::guiActivateEvent(event); if(event->activated()) { if(m_scriptEditor) m_scriptEditor->show(); }else { if(m_scriptEditor) m_scriptEditor->hide(); } } void CantorPart::evaluateOrInterrupt() { qDebug()<<"evalorinterrupt"; if(m_worksheet->isRunning()) m_worksheet->interrupt(); else m_worksheet->evaluate(); } void CantorPart::restartBackend() { m_worksheet->session()->logout(); m_worksheet->session()->login(); } void CantorPart::worksheetStatusChanged(Cantor::Session::Status status) { qDebug()<<"wsStatusChange"<setText(i18n("Interrupt")); m_evaluate->setIcon(QIcon::fromTheme(QLatin1String("dialog-close"))); setStatusMessage(i18n("Calculating...")); }else { m_evaluate->setText(i18n("Evaluate Worksheet")); m_evaluate->setIcon(QIcon::fromTheme(QLatin1String("system-run"))); setStatusMessage(i18n("Ready")); } } void CantorPart::showSessionError(const QString& message) { qDebug()<<"Error: "<session(), SIGNAL(statusChanged(Cantor::Session::Status)), this, SLOT(worksheetStatusChanged(Cantor::Session::Status))); connect(m_worksheet->session(), SIGNAL(loginStarted()),this, SLOT(worksheetSessionLoginStarted())); connect(m_worksheet->session(), SIGNAL(loginDone()),this, SLOT(worksheetSessionLoginDone())); connect(m_worksheet->session(), SIGNAL(error(const QString&)), this, SLOT(showSessionError(const QString&))); loadAssistants(); m_panelHandler->setSession(m_worksheet->session()); adjustGuiToSession(); initialized(); } void CantorPart::initialized() { if (m_worksheet->isEmpty()) m_worksheet->appendCommandEntry(); m_worksheetview->setEnabled(true); m_worksheetview->setFocus(); setStatusMessage(i18n("Initialization complete")); updateCaption(); } void CantorPart::worksheetSessionLoginStarted() { setStatusMessage(i18n("Initializing...")); QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); } void CantorPart::worksheetSessionLoginDone() { QApplication::restoreOverrideCursor(); } void CantorPart::enableTypesetting(bool enable) { m_worksheet->session()->setTypesettingEnabled(enable); } void CantorPart::showBackendHelp() { qDebug()<<"showing backends help"; Cantor::Backend* backend=m_worksheet->session()->backend(); QUrl url = backend->helpUrl(); qDebug()<<"launching url "<session()->backend()->name(), filename)); } void CantorPart::pluginsChanged() { foreach(Cantor::PanelPlugin* plugin, m_panelHandler->plugins()) { connect(plugin, SIGNAL(requestRunCommand(QString)), this, SLOT(runCommand(QString))); } } void CantorPart::loadAssistants() { qDebug()<<"loading assistants..."; QStringList assistantDirs; foreach(const QString &dir, QCoreApplication::libraryPaths()){ assistantDirs << dir + QDir::separator() + QLatin1String("cantor/assistants"); } QPluginLoader loader; foreach(const QString &dir, assistantDirs){ qDebug() << "dir: " << dir; QStringList assistants; QDir assistantDir = QDir(dir); assistants = assistantDir.entryList(); foreach (const QString &assistant, assistants){ if (assistant==QLatin1String(".") || assistant==QLatin1String("..")) continue; loader.setFileName(dir + QDir::separator() + assistant); if (!loader.load()){ qDebug() << "Error while loading assistant: " << assistant; continue; } KPluginFactory* factory = KPluginLoader(loader.fileName()).factory(); Cantor::Assistant* plugin = factory->create(this); Cantor::Backend* backend=worksheet()->session()->backend(); KPluginMetaData info(loader); plugin->setPluginInfo(info); plugin->setBackend(backend); qDebug()<<"plugin "<requiredExtensions(); bool supported=true; foreach(const QString& req, plugin->requiredExtensions()) supported=supported && backend->extensions().contains(req); qDebug()<<"plugin "<name(); if(supported) { plugin->initActions(); connect(plugin, SIGNAL(requested()), this, SLOT(runAssistant())); }else { removeChildClient(plugin); plugin->deleteLater(); } } } } void CantorPart::runAssistant() { Cantor::Assistant* a=qobject_cast(sender()); QStringList cmds=a->run(widget()); qDebug()<appendCommandEntry(cmd); } void CantorPart::showSearchBar() { if (!m_searchBar) { m_searchBar = new SearchBar(widget(), m_worksheet); widget()->layout()->addWidget(m_searchBar); connect(m_searchBar, SIGNAL(destroyed(QObject*)), this, SLOT(searchBarDeleted())); } m_findNext->setEnabled(true); m_findPrev->setEnabled(true); m_searchBar->showStandard(); m_searchBar->setFocus(); } void CantorPart::showExtendedSearchBar() { if (!m_searchBar) { m_searchBar = new SearchBar(widget(), m_worksheet); widget()->layout()->addWidget(m_searchBar); connect(m_searchBar, SIGNAL(destroyed(QObject*)), this, SLOT(searchBarDeleted())); } m_findNext->setEnabled(true); m_findPrev->setEnabled(true); m_searchBar->showExtended(); m_searchBar->setFocus(); } void CantorPart::findNext() { if (m_searchBar) m_searchBar->next(); } void CantorPart::findPrev() { if (m_searchBar) m_searchBar->prev(); } void CantorPart::searchBarDeleted() { - m_searchBar = 0; + m_searchBar = nullptr; m_findNext->setEnabled(false); m_findPrev->setEnabled(false); } void CantorPart::adjustGuiToSession() { #ifdef WITH_EPS m_typeset->setVisible(m_worksheet->session()->backend()->capabilities().testFlag(Cantor::Backend::LaTexOutput)); #else m_typeset->setVisible(false); #endif m_completion->setVisible(m_worksheet->session()->backend()->capabilities().testFlag(Cantor::Backend::Completion)); //this is 0 on the first call if(m_showBackendHelp) m_showBackendHelp->setText(i18n("Show %1 Help", m_worksheet->session()->backend()->name())); } void CantorPart::publishWorksheet() { int ret = KMessageBox::questionYesNo(widget(), i18n("Do you want to upload current Worksheet to public web server?"), i18n("Question - Cantor")); if (ret != KMessageBox::Yes) return; if (isModified()||url().isEmpty()) { ret = KMessageBox::warningContinueCancel(widget(), i18n("The Worksheet is not saved. You should save it before uploading."), i18n("Warning - Cantor"), KStandardGuiItem::save(), KStandardGuiItem::cancel()); if (ret != KMessageBox::Continue) return; if (!saveFile()) return; } qDebug()<<"uploading file "<session()->backend()->id().toLower()), widget()); dialog.setUploadFile(url()); dialog.exec(); } void CantorPart::print() { QPrinter printer; QPointer dialog = new QPrintDialog(&printer, widget()); // TODO: Re-enable print selection //if (m_worksheet->textCursor().hasSelection()) // dialog->addEnabledOption(QAbstractPrintDialog::PrintSelection); if (dialog->exec() == QDialog::Accepted) m_worksheet->print(&printer); delete dialog; } void CantorPart::printPreview() { QPrintPreviewDialog *dialog = new QPrintPreviewDialog(widget()); connect(dialog, SIGNAL(paintRequested(QPrinter*)), m_worksheet, SLOT(print(QPrinter*))); dialog->exec(); } void CantorPart::showScriptEditor(bool show) { if(show) { if (m_scriptEditor) { return; } Cantor::ScriptExtension* scriptE=dynamic_cast(m_worksheet->session()->backend()->extension(QLatin1String("ScriptExtension"))); if (!scriptE) { return; } m_scriptEditor=new ScriptEditorWidget(scriptE->scriptFileFilter(), scriptE->highlightingMode(), widget()->window()); connect(m_scriptEditor, SIGNAL(runScript(const QString&)), this, SLOT(runScript(const QString&))); connect(m_scriptEditor, SIGNAL(destroyed()), this, SLOT(scriptEditorClosed())); m_scriptEditor->show(); }else { m_scriptEditor->deleteLater(); } } void CantorPart::scriptEditorClosed() { QAction* showEditor = actionCollection()->action(QLatin1String("show_editor")); if (showEditor) { showEditor->setChecked(false); } } void CantorPart::runScript(const QString& file) { Cantor::Backend* backend=m_worksheet->session()->backend(); if(!backend->extensions().contains(QLatin1String("ScriptExtension"))) { KMessageBox::error(widget(), i18n("This backend does not support scripts."), i18n("Error - Cantor")); return; } Cantor::ScriptExtension* scriptE=dynamic_cast(backend->extension(QLatin1String("ScriptExtension"))); m_worksheet->appendCommandEntry(scriptE->runExternalScript(file)); } void CantorPart::blockStatusBar() { m_statusBarBlocked=true; } void CantorPart::unblockStatusBar() { m_statusBarBlocked=false; if(!m_cachedStatusMessage.isNull()) setStatusMessage(m_cachedStatusMessage); m_cachedStatusMessage.clear(); } void CantorPart::setStatusMessage(const QString& message) { if(!m_statusBarBlocked) emit setStatusBarText(message); else m_cachedStatusMessage=message; } void CantorPart::showImportantStatusMessage(const QString& message) { setStatusMessage(message); blockStatusBar(); QTimer::singleShot(3000, this, SLOT(unblockStatusBar())); } K_PLUGIN_FACTORY_WITH_JSON(CantorPartFactory, "cantor_part.json", registerPlugin();) #include "cantor_part.moc" diff --git a/src/commandentry.cpp b/src/commandentry.cpp index a3d49b72..ecdde81b 100644 --- a/src/commandentry.cpp +++ b/src/commandentry.cpp @@ -1,786 +1,786 @@ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. --- Copyright (C) 2009 Alexander Rieder Copyright (C) 2012 Martin Kuettler */ #include "commandentry.h" #include "resultitem.h" #include "loadedexpression.h" #include "lib/result.h" #include "lib/helpresult.h" #include "lib/completionobject.h" #include "lib/syntaxhelpobject.h" #include "lib/session.h" #include #include #include #include #include #include const QString CommandEntry::Prompt=QLatin1String(">>> "); const double CommandEntry::HorizontalSpacing = 4; const double CommandEntry::VerticalSpacing = 4; CommandEntry::CommandEntry(Worksheet* worksheet) : WorksheetEntry(worksheet), m_promptItem(new WorksheetTextItem(this, Qt::NoTextInteraction)), m_commandItem(new WorksheetTextItem(this, Qt::TextEditorInteraction)), - m_resultItem(0), - m_errorItem(0), - m_expression(0), - m_completionObject(0), - m_syntaxHelpObject(0) + m_resultItem(nullptr), + m_errorItem(nullptr), + m_expression(nullptr), + m_completionObject(nullptr), + m_syntaxHelpObject(nullptr) { m_promptItem->setPlainText(Prompt); m_promptItem->setItemDragable(true); m_commandItem->enableCompletion(true); connect(m_commandItem, &WorksheetTextItem::tabPressed, this, &CommandEntry::showCompletion); connect(m_commandItem, &WorksheetTextItem::backtabPressed, this, &CommandEntry::selectPreviousCompletion); connect(m_commandItem, &WorksheetTextItem::applyCompletion, this, &CommandEntry::applySelectedCompletion); connect(m_commandItem, SIGNAL(execute()), this, SLOT(evaluate())); connect(m_commandItem, &WorksheetTextItem::moveToPrevious, this, &CommandEntry::moveToPreviousItem); connect(m_commandItem, &WorksheetTextItem::moveToNext, this, &CommandEntry::moveToNextItem); connect(m_commandItem, SIGNAL(receivedFocus(WorksheetTextItem*)), worksheet, SLOT(highlightItem(WorksheetTextItem*))); connect(m_promptItem, &WorksheetTextItem::drag, this, &CommandEntry::startDrag); connect(worksheet, SIGNAL(updatePrompt()), this, SLOT(updatePrompt())); } CommandEntry::~CommandEntry() { if (m_completionBox) m_completionBox->deleteLater(); } int CommandEntry::type() const { return Type; } void CommandEntry::populateMenu(QMenu *menu, const QPointF& pos) { qDebug() << "populate Menu"; WorksheetEntry::populateMenu(menu, pos); } void CommandEntry::moveToNextItem(int pos, qreal x) { WorksheetTextItem* item = qobject_cast(sender()); if (!item) return; if (item == m_commandItem) { if (m_informationItems.isEmpty() || !currentInformationItem()->isEditable()) moveToNextEntry(pos, x); else currentInformationItem()->setFocusAt(pos, x); } else if (item == currentInformationItem()) { moveToNextEntry(pos, x); } } void CommandEntry::moveToPreviousItem(int pos, qreal x) { WorksheetTextItem* item = qobject_cast(sender()); if (!item) return; - if (item == m_commandItem || item == 0) { + if (item == m_commandItem || item == nullptr) { moveToPreviousEntry(pos, x); } else if (item == currentInformationItem()) { m_commandItem->setFocusAt(pos, x); } } QString CommandEntry::command() { QString cmd = m_commandItem->toPlainText(); cmd.replace(QChar::ParagraphSeparator, QLatin1Char('\n')); //Replace the U+2029 paragraph break by a Normal Newline cmd.replace(QChar::LineSeparator, QLatin1Char('\n')); //Replace the line break by a Normal Newline return cmd; } void CommandEntry::setExpression(Cantor::Expression* expr) { /* if ( m_expression ) { if (m_expression->status() == Cantor::Expression::Computing) { qDebug() << "OLD EXPRESSION STILL ACTIVE"; m_expression->interrupt(); } m_expression->deleteLater(); }*/ // Delete any previus error if(m_errorItem) { m_errorItem->deleteLater(); - m_errorItem = 0; + m_errorItem = nullptr; } foreach(WorksheetTextItem* item, m_informationItems) { item->deleteLater(); } m_informationItems.clear(); - m_expression = 0; + m_expression = nullptr; // Delete any previous result removeResult(); m_expression=expr; connect(expr, SIGNAL(gotResult()), this, SLOT(updateEntry())); connect(expr, SIGNAL(idChanged()), this, SLOT(updatePrompt())); connect(expr, SIGNAL(statusChanged(Cantor::Expression::Status)), this, SLOT(expressionChangedStatus(Cantor::Expression::Status))); connect(expr, SIGNAL(needsAdditionalInformation(const QString&)), this, SLOT(showAdditionalInformationPrompt(const QString&))); connect(expr, SIGNAL(statusChanged(Cantor::Expression::Status)), this, SLOT(updatePrompt())); updatePrompt(); if(expr->result()) { worksheet()->gotResult(expr); updateEntry(); } if(expr->status()!=Cantor::Expression::Computing) { expressionChangedStatus(expr->status()); } } Cantor::Expression* CommandEntry::expression() { return m_expression; } bool CommandEntry::acceptRichText() { return false; } void CommandEntry::setContent(const QString& content) { m_commandItem->setPlainText(content); } void CommandEntry::setContent(const QDomElement& content, const KZip& file) { m_commandItem->setPlainText(content.firstChildElement(QLatin1String("Command")).text()); LoadedExpression* expr=new LoadedExpression( worksheet()->session() ); expr->loadFromXml(content, file); setExpression(expr); } void CommandEntry::showCompletion() { const QString line = currentLine(); if(!worksheet()->completionEnabled() || line.trimmed().isEmpty()) { if (m_commandItem->hasFocus()) m_commandItem->insertTab(); return; } else if (isShowingCompletionPopup()) { QString comp = m_completionObject->completion(); qDebug() << "command" << m_completionObject->command(); qDebug() << "completion" << comp; if (comp != m_completionObject->command() || !m_completionObject->hasMultipleMatches()) { if (m_completionObject->hasMultipleMatches()) { completeCommandTo(comp, PreliminaryCompletion); } else { completeCommandTo(comp, FinalCompletion); m_completionBox->hide(); } } else { m_completionBox->down(); } } else { int p = m_commandItem->textCursor().positionInBlock(); Cantor::CompletionObject* tco=worksheet()->session()->completionFor(line, p); if(tco) setCompletion(tco); } } void CommandEntry::selectPreviousCompletion() { if (isShowingCompletionPopup()) m_completionBox->up(); } QString CommandEntry::toPlain(const QString& commandSep, const QString& commentStartingSeq, const QString& commentEndingSeq) { Q_UNUSED(commentStartingSeq); Q_UNUSED(commentEndingSeq); if (command().isEmpty()) return QString(); return command() + commandSep; } QDomElement CommandEntry::toXml(QDomDocument& doc, KZip* archive) { if (expression()) { if ( archive ) expression()->saveAdditionalData( archive ); return expression()->toXml(doc); } QDomElement expr=doc.createElement( QLatin1String("Expression") ); QDomElement cmd=doc.createElement( QLatin1String("Command") ); QDomText cmdText=doc.createTextNode( command() ); cmd.appendChild( cmdText ); expr.appendChild( cmd ); return expr; } QString CommandEntry::currentLine() { if (!m_commandItem->hasFocus()) return QString(); QTextBlock block = m_commandItem->textCursor().block(); return block.text(); } bool CommandEntry::evaluateCurrentItem() { // we can't use m_commandItem->hasFocus() here, because // that doesn't work when the scene doesn't have the focus, // e.g. when an assistant is used. if (m_commandItem == worksheet()->focusItem()) { return evaluate(); } else if (informationItemHasFocus()) { addInformation(); return true; } return false; } bool CommandEntry::evaluate(EvaluationOption evalOp) { removeContextHelp(); QToolTip::hideText(); QString cmd = command(); qDebug()<<"evaluating: "<deleteLater(); } m_informationItems.clear(); recalculateSize(); evaluateNext(m_evaluationOption); return false; } Cantor::Expression* expr; expr = worksheet()->session()->evaluateExpression(cmd); connect(expr, SIGNAL(gotResult()), worksheet(), SLOT(gotResult())); setExpression(expr); return true; } void CommandEntry::interruptEvaluation() { Cantor::Expression *expr = expression(); if(expr) expr->interrupt(); } void CommandEntry::updateEntry() { qDebug() << "update Entry"; Cantor::Expression *expr = expression(); - if (expr == 0 || expr->result() == 0) + if (expr == nullptr || expr->result() == nullptr) return; if (expr->result()->type() == Cantor::HelpResult::Type) return; // Help is handled elsewhere if (expr->result()->type() == Cantor::TextResult::Type && expr->result()->toHtml().trimmed().isEmpty()) { return; } else if (!m_resultItem) { m_resultItem = ResultItem::create(this, expr->result()); qDebug() << "new result"; animateSizeChange(); } else { m_resultItem = m_resultItem->updateFromResult(expr->result()); qDebug() << "update result"; animateSizeChange(); } } void CommandEntry::expressionChangedStatus(Cantor::Expression::Status status) { QString text; switch (status) { case Cantor::Expression::Error: text = m_expression->errorMessage(); break; case Cantor::Expression::Interrupted: text = i18n("Interrupted"); break; case Cantor::Expression::Done: evaluateNext(m_evaluationOption); m_evaluationOption = DoNothing; return; default: return; } m_commandItem->setFocusAt(WorksheetTextItem::BottomRight, 0); if(!m_errorItem) { m_errorItem = new WorksheetTextItem(this, Qt::TextSelectableByMouse); } m_errorItem->setHtml(text); recalculateSize(); } bool CommandEntry::isEmpty() { if (m_commandItem->toPlainText().trimmed().isEmpty()) { if (m_resultItem) return false; return true; } return false; } bool CommandEntry::focusEntry(int pos, qreal xCoord) { if (aboutToBeRemoved()) return false; WorksheetTextItem* item; if (pos == WorksheetTextItem::TopLeft || pos == WorksheetTextItem::TopCoord) item = m_commandItem; else if (m_informationItems.size() && currentInformationItem()->isEditable()) item = currentInformationItem(); else item = m_commandItem; item->setFocusAt(pos, xCoord); return true; } void CommandEntry::setCompletion(Cantor::CompletionObject* tc) { if (m_completionObject) delete m_completionObject; m_completionObject = tc; connect(m_completionObject, &Cantor::CompletionObject::done, this, &CommandEntry::showCompletions); connect(m_completionObject, &Cantor::CompletionObject::lineDone, this, &CommandEntry::completeLineTo); } void CommandEntry::showCompletions() { disconnect(m_completionObject, &Cantor::CompletionObject::done, this, &CommandEntry::showCompletions); QString completion = m_completionObject->completion(); qDebug()<<"completion: "<allMatches(); if(m_completionObject->hasMultipleMatches()) { completeCommandTo(completion); QToolTip::showText(QPoint(), QString(), worksheetView()); if (!m_completionBox) m_completionBox = new KCompletionBox(worksheetView()); m_completionBox->clear(); m_completionBox->setItems(m_completionObject->allMatches()); QList items = m_completionBox->findItems(m_completionObject->command(), Qt::MatchFixedString|Qt::MatchCaseSensitive); if (!items.empty()) m_completionBox->setCurrentItem(items.first()); m_completionBox->setTabHandling(false); m_completionBox->setActivateOnSelect(true); connect(m_completionBox.data(), &KCompletionBox::activated, this, &CommandEntry::applySelectedCompletion); connect(m_commandItem->document(), SIGNAL(contentsChanged()), this, SLOT(completedLineChanged())); connect(m_completionObject, &Cantor::CompletionObject::done, this, &CommandEntry::updateCompletions); m_commandItem->activateCompletion(true); m_completionBox->popup(); m_completionBox->move(getPopupPosition()); } else { completeCommandTo(completion, FinalCompletion); } } bool CommandEntry::isShowingCompletionPopup() { return m_completionBox && m_completionBox->isVisible(); } void CommandEntry::applySelectedCompletion() { QListWidgetItem* item = m_completionBox->currentItem(); if(item) completeCommandTo(item->text(), FinalCompletion); m_completionBox->hide(); } void CommandEntry::completedLineChanged() { if (!isShowingCompletionPopup()) { // the completion popup is not visible anymore, so let's clean up removeContextHelp(); return; } const QString line = currentLine(); m_completionObject->updateLine(line, m_commandItem->textCursor().positionInBlock()); } void CommandEntry::updateCompletions() { if (!m_completionObject) return; QString completion = m_completionObject->completion(); qDebug()<<"completion: "<allMatches(); if(m_completionObject->hasMultipleMatches() || !completion.isEmpty()) { QToolTip::showText(QPoint(), QString(), worksheetView()); m_completionBox->setItems(m_completionObject->allMatches()); QList items = m_completionBox->findItems(m_completionObject->command(), Qt::MatchFixedString|Qt::MatchCaseSensitive); if (!items.empty()) m_completionBox->setCurrentItem(items.first()); m_completionBox->move(getPopupPosition()); } else { removeContextHelp(); } } void CommandEntry::completeCommandTo(const QString& completion, CompletionMode mode) { qDebug() << "completion: " << completion; Cantor::CompletionObject::LineCompletionMode cmode; if (mode == FinalCompletion) { cmode = Cantor::CompletionObject::FinalCompletion; Cantor::SyntaxHelpObject* obj = worksheet()->session()->syntaxHelpFor(completion); if(obj) setSyntaxHelp(obj); } else { cmode = Cantor::CompletionObject::PreliminaryCompletion; if(m_syntaxHelpObject) m_syntaxHelpObject->deleteLater(); - m_syntaxHelpObject=0; + m_syntaxHelpObject=nullptr; } m_completionObject->completeLine(completion, cmode); } void CommandEntry::completeLineTo(const QString& line, int index) { qDebug() << "line completion: " << line; QTextCursor cursor = m_commandItem->textCursor(); cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::MoveAnchor); cursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::KeepAnchor); int startPosition = cursor.position(); cursor.insertText(line); cursor.setPosition(startPosition + index); m_commandItem->setTextCursor(cursor); if (m_syntaxHelpObject) { m_syntaxHelpObject->fetchSyntaxHelp(); // If we are about to show syntax help, then this was the final // completion, and we should clean up. removeContextHelp(); } } void CommandEntry::setSyntaxHelp(Cantor::SyntaxHelpObject* sh) { if(m_syntaxHelpObject) m_syntaxHelpObject->deleteLater(); m_syntaxHelpObject=sh; connect(sh, SIGNAL(done()), this, SLOT(showSyntaxHelp())); } void CommandEntry::showSyntaxHelp() { const QString& msg = m_syntaxHelpObject->toHtml(); const QPointF cursorPos = m_commandItem->cursorPosition(); QToolTip::showText(toGlobalPosition(cursorPos), msg, worksheetView()); } void CommandEntry::resultDeleted() { qDebug()<<"result got removed..."; } void CommandEntry::addInformation() { WorksheetTextItem *answerItem = currentInformationItem(); answerItem->setTextInteractionFlags(Qt::TextSelectableByMouse); QString inf = answerItem->toPlainText(); inf.replace(QChar::ParagraphSeparator, QLatin1Char('\n')); inf.replace(QChar::LineSeparator, QLatin1Char('\n')); qDebug()<<"adding information: "<addInformation(inf); } void CommandEntry::showAdditionalInformationPrompt(const QString& question) { WorksheetTextItem* questionItem = new WorksheetTextItem(this, Qt::TextSelectableByMouse); WorksheetTextItem* answerItem = new WorksheetTextItem(this, Qt::TextEditorInteraction); questionItem->setPlainText(question); m_informationItems.append(questionItem); m_informationItems.append(answerItem); connect(answerItem, &WorksheetTextItem::moveToPrevious, this, &CommandEntry::moveToPreviousItem); connect(answerItem, &WorksheetTextItem::moveToNext, this, &CommandEntry::moveToNextItem); connect(answerItem, &WorksheetTextItem::execute, this, &CommandEntry::addInformation); answerItem->setFocus(); recalculateSize(); } void CommandEntry::removeResult() { if(m_expression) { m_expression->clearResult(); } if (m_resultItem) { QGraphicsObject* obj = m_resultItem->graphicsObject(); - m_resultItem = 0; + m_resultItem = nullptr; fadeOutItem(obj); } } void CommandEntry::removeContextHelp() { disconnect(m_commandItem->document(), SIGNAL(contentsChanged()), this, SLOT(completedLineChanged())); m_commandItem->activateCompletion(false); if (m_completionBox) m_completionBox->hide(); } void CommandEntry::updatePrompt() { KColorScheme color = KColorScheme( QPalette::Normal, KColorScheme::View); m_promptItem->setPlainText(QLatin1String("")); QTextCursor c = m_promptItem->textCursor(); QTextCharFormat cformat = c.charFormat(); cformat.clearForeground(); c.setCharFormat(cformat); cformat.setFontWeight(QFont::Bold); //insert the session id if available if(m_expression && worksheet()->showExpressionIds()&&m_expression->id()!=-1) c.insertText(QString::number(m_expression->id()),cformat); //detect the correct color for the prompt, depending on the //Expression state if(m_expression) { if(m_expression ->status() == Cantor::Expression::Computing&&worksheet()->isRunning()) cformat.setForeground(color.foreground(KColorScheme::PositiveText)); else if(m_expression ->status() == Cantor::Expression::Error) cformat.setForeground(color.foreground(KColorScheme::NegativeText)); else if(m_expression ->status() == Cantor::Expression::Interrupted) cformat.setForeground(color.foreground(KColorScheme::NeutralText)); else cformat.setFontWeight(QFont::Normal); } c.insertText(CommandEntry::Prompt,cformat); recalculateSize(); } WorksheetTextItem* CommandEntry::currentInformationItem() { if (m_informationItems.isEmpty()) - return 0; + return nullptr; return m_informationItems.last(); } bool CommandEntry::informationItemHasFocus() { if (m_informationItems.isEmpty()) return false; return m_informationItems.last()->hasFocus(); } bool CommandEntry::focusWithinThisItem() { - return focusItem() != 0; + return focusItem() != nullptr; } QPoint CommandEntry::getPopupPosition() { const QPointF cursorPos = m_commandItem->cursorPosition(); const QPoint globalPos = toGlobalPosition(cursorPos); const QDesktopWidget* desktop = QApplication::desktop(); const QRect screenRect = desktop->screenGeometry(globalPos); if (globalPos.y() + m_completionBox->height() < screenRect.bottom()) { return (globalPos); } else { QTextBlock block = m_commandItem->textCursor().block(); QTextLayout* layout = block.layout(); int pos = m_commandItem->textCursor().position() - block.position(); QTextLine line = layout->lineForTextPosition(pos); int dy = - m_completionBox->height() - line.height() - line.leading(); return QPoint(globalPos.x(), globalPos.y() + dy); } } void CommandEntry::invalidate() { qDebug() << "ToDo: Invalidate here"; } bool CommandEntry::wantToEvaluate() { return !isEmpty(); } QPoint CommandEntry::toGlobalPosition(const QPointF& localPos) { const QPointF scenePos = mapToScene(localPos); const QPoint viewportPos = worksheetView()->mapFromScene(scenePos); return worksheetView()->viewport()->mapToGlobal(viewportPos); } WorksheetCursor CommandEntry::search(QString pattern, unsigned flags, QTextDocument::FindFlags qt_flags, const WorksheetCursor& pos) { if (pos.isValid() && pos.entry() != this) return WorksheetCursor(); WorksheetCursor p = pos; QTextCursor cursor; if (flags & WorksheetEntry::SearchCommand) { cursor = m_commandItem->search(pattern, qt_flags, p); if (!cursor.isNull()) return WorksheetCursor(this, m_commandItem, cursor); } if (p.textItem() == m_commandItem) p = WorksheetCursor(); if (m_errorItem && flags & WorksheetEntry::SearchError) { cursor = m_errorItem->search(pattern, qt_flags, p); if (!cursor.isNull()) return WorksheetCursor(this, m_errorItem, cursor); } if (p.textItem() == m_errorItem) p = WorksheetCursor(); WorksheetTextItem* textResult = dynamic_cast (m_resultItem); if (textResult && flags & WorksheetEntry::SearchResult) { cursor = textResult->search(pattern, qt_flags, p); if (!cursor.isNull()) return WorksheetCursor(this, textResult, cursor); } return WorksheetCursor(); } void CommandEntry::layOutForWidth(qreal w, bool force) { if (w == size().width() && !force) return; m_promptItem->setPos(0,0); double x = 0 + m_promptItem->width() + HorizontalSpacing; double y = 0; double width = 0; m_commandItem->setGeometry(x,y, w-x); width = qMax(width, m_commandItem->width()); y += qMax(m_commandItem->height(), m_promptItem->height()); foreach(WorksheetTextItem* information, m_informationItems) { y += VerticalSpacing; y += information->setGeometry(x,y,w-x); width = qMax(width, information->width()); } if (m_errorItem) { y += VerticalSpacing; y += m_errorItem->setGeometry(x,y,w-x); width = qMax(width, m_errorItem->width()); } if (m_resultItem) { y += VerticalSpacing; y += m_resultItem->setGeometry(x, y, w-x); width = qMax(width, m_resultItem->width()); } y += VerticalMargin; QSizeF s(x+ width, y); if (animationActive()) { updateSizeAnimation(s); } else { setSize(s); } } void CommandEntry::startRemoving() { m_promptItem->setItemDragable(false); WorksheetEntry::startRemoving(); } WorksheetTextItem* CommandEntry::highlightItem() { return m_commandItem; } diff --git a/src/epsrenderer.h b/src/epsrenderer.h index 1f7bc283..5ed215d1 100644 --- a/src/epsrenderer.h +++ b/src/epsrenderer.h @@ -1,59 +1,59 @@ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. --- Copyright (C) 2012 Martin Kuettler */ #ifndef EPSRENDERER_H #define EPSRENDERER_H #include #include #include #include #include #include "lib/latexrenderer.h" class EpsRenderer { public: EpsRenderer(); ~EpsRenderer(); enum FormulaProperties {CantorFormula = 1, ImagePath = 2, Code = 3, Delimiter = 4}; enum FormulaType {LatexFormula = Cantor::LatexRenderer::LatexMethod, MmlFormula = Cantor::LatexRenderer::MmlMethod}; QTextImageFormat render(QTextDocument *document, const QUrl& url); QTextImageFormat render(QTextDocument *document, const Cantor::LatexRenderer* latex); void setScale(qreal scale); qreal scale(); void useHighResolution(bool b); QSizeF renderToResource(QTextDocument *document, const QUrl& url); - QImage renderToImage(const QUrl& url, QSizeF* size = 0); + QImage renderToImage(const QUrl& url, QSizeF* size = nullptr); private: double m_scale; bool m_useHighRes; }; #endif //EPSRENDERER_H diff --git a/src/imageentry.cpp b/src/imageentry.cpp index 6b51b95e..049bf406 100644 --- a/src/imageentry.cpp +++ b/src/imageentry.cpp @@ -1,340 +1,340 @@ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. --- Copyright (C) 2012 martin Kuettler */ #include "imageentry.h" #include "worksheetimageitem.h" #include "actionbar.h" #include #include #include #include ImageEntry::ImageEntry(Worksheet* worksheet) : WorksheetEntry(worksheet) { - m_imageItem = 0; + m_imageItem = nullptr; m_textItem = new WorksheetTextItem(this); m_imageWatcher = new QFileSystemWatcher(this); m_displaySize.width = -1; m_displaySize.height = -1; m_printSize.width = -1; m_printSize.height = -1; m_displaySize.widthUnit = ImageSize::Auto; m_displaySize.heightUnit = ImageSize::Auto; m_printSize.widthUnit = ImageSize::Auto; m_printSize.heightUnit = ImageSize::Auto; m_useDisplaySizeForPrinting = true; connect(m_imageWatcher, &QFileSystemWatcher::fileChanged, this, &ImageEntry::updateEntry); setFlag(QGraphicsItem::ItemIsFocusable); updateEntry(); startConfigDialog(); } ImageEntry::~ImageEntry() { } void ImageEntry::populateMenu(QMenu *menu, const QPointF& pos) { menu->addAction(QIcon::fromTheme(QLatin1String("configure")), i18n("Configure Image"), this, SLOT(startConfigDialog())); menu->addSeparator(); WorksheetEntry::populateMenu(menu, pos); } bool ImageEntry::isEmpty() { return false; } int ImageEntry::type() const { return Type; } bool ImageEntry::acceptRichText() { return false; } void ImageEntry::setContent(const QString& content) { Q_UNUSED(content); return; } void ImageEntry::setContent(const QDomElement& content, const KZip& file) { Q_UNUSED(file); static QStringList unitNames; if (unitNames.isEmpty()) unitNames << QLatin1String("(auto)") << QLatin1String("px") << QLatin1String("%"); QDomElement pathElement = content.firstChildElement(QLatin1String("Path")); QDomElement displayElement = content.firstChildElement(QLatin1String("Display")); QDomElement printElement = content.firstChildElement(QLatin1String("Print")); m_imagePath = pathElement.text(); m_displaySize.width = displayElement.attribute(QLatin1String("width")).toDouble(); m_displaySize.height = displayElement.attribute(QLatin1String("height")).toDouble(); m_displaySize.widthUnit = unitNames.indexOf(displayElement.attribute(QLatin1String("widthUnit"))); m_displaySize.heightUnit = unitNames.indexOf(displayElement.attribute(QLatin1String("heightUnit"))); m_useDisplaySizeForPrinting = printElement.attribute(QLatin1String("useDisplaySize")).toInt(); m_printSize.width = printElement.attribute(QLatin1String("width")).toDouble(); m_printSize.height = printElement.attribute(QLatin1String("height")).toDouble(); m_printSize.widthUnit = unitNames.indexOf(printElement.attribute(QLatin1String("widthUnit"))); m_printSize.heightUnit = unitNames.indexOf(printElement.attribute(QLatin1String("heightUnit"))); updateEntry(); } QDomElement ImageEntry::toXml(QDomDocument& doc, KZip* archive) { Q_UNUSED(archive); static QStringList unitNames; if (unitNames.isEmpty()) unitNames << QLatin1String("(auto)") << QLatin1String("px") << QLatin1String("%"); QDomElement image = doc.createElement(QLatin1String("Image")); QDomElement path = doc.createElement(QLatin1String("Path")); QDomText pathText = doc.createTextNode(m_imagePath); path.appendChild(pathText); image.appendChild(path); QDomElement display = doc.createElement(QLatin1String("Display")); display.setAttribute(QLatin1String("width"), m_displaySize.width); display.setAttribute(QLatin1String("widthUnit"), unitNames[m_displaySize.widthUnit]); display.setAttribute(QLatin1String("height"), m_displaySize.height); display.setAttribute(QLatin1String("heightUnit"), unitNames[m_displaySize.heightUnit]); image.appendChild(display); QDomElement print = doc.createElement(QLatin1String("Print")); print.setAttribute(QLatin1String("useDisplaySize"), m_useDisplaySizeForPrinting); print.setAttribute(QLatin1String("width"), m_printSize.width); print.setAttribute(QLatin1String("widthUnit"), unitNames[m_printSize.widthUnit]); print.setAttribute(QLatin1String("height"), m_printSize.height); print.setAttribute(QLatin1String("heightUnit"), unitNames[m_printSize.heightUnit]); image.appendChild(print); // For the conversion to latex QDomElement latexSize = doc.createElement(QLatin1String("LatexSizeString")); QString sizeString; if (m_useDisplaySizeForPrinting) sizeString = latexSizeString(m_displaySize); else sizeString = latexSizeString(m_printSize); QDomText latexSizeString = doc.createTextNode(sizeString); latexSize.appendChild(latexSizeString); image.appendChild(latexSize); return image; } QString ImageEntry::toPlain(const QString& commandSep, const QString& commentStartingSeq, const QString& commentEndingSeq) { Q_UNUSED(commandSep); return commentStartingSeq + QLatin1String("image: ") + m_imagePath + commentEndingSeq; } QString ImageEntry::latexSizeString(const ImageSize& imgSize) { // We use the transformation 1 px = 1/72 in ( = 1 pt in Latex) QString sizeString=QLatin1String(""); if (imgSize.widthUnit == ImageSize::Auto && imgSize.heightUnit == ImageSize::Auto) return QLatin1String(""); if (imgSize.widthUnit == ImageSize::Percent) { if (imgSize.heightUnit == ImageSize::Auto || (imgSize.heightUnit == ImageSize::Percent && imgSize.width == imgSize.height)) return QLatin1String("[scale=") + QString::number(imgSize.width / 100) + QLatin1String("]"); // else? We could set the size based on the actual image size } else if (imgSize.widthUnit == ImageSize::Auto && imgSize.heightUnit == ImageSize::Percent) { return QLatin1String("[scale=") + QString::number(imgSize.height / 100) + QLatin1String("]"); } if (imgSize.heightUnit == ImageSize::Pixel) sizeString = QLatin1String("height=") + QString::number(imgSize.height) + QLatin1String("pt"); if (imgSize.widthUnit == ImageSize::Pixel) { if (!sizeString.isEmpty()) sizeString += QLatin1String(","); sizeString += QLatin1String("width=") + QString::number(imgSize.width) + QLatin1String("pt"); } return QLatin1String("[") + sizeString + QLatin1String("]"); } void ImageEntry::interruptEvaluation() { } bool ImageEntry::evaluate(EvaluationOption evalOp) { evaluateNext(evalOp); return true; } qreal ImageEntry::height() { if (m_imageItem && m_imageItem->isVisible()) return m_imageItem->height(); else return m_textItem->height(); } void ImageEntry::updateEntry() { qreal oldHeight = height(); if (m_imagePath.isEmpty()) { m_textItem->setPlainText(i18n("Right click here to insert image")); m_textItem->setVisible(true); if (m_imageItem) m_imageItem->setVisible(false); } else { if (!m_imageItem) m_imageItem = new WorksheetImageItem(this); if (m_imagePath.toLower().endsWith(QLatin1String(".eps"))) { m_imageItem->setEps(QUrl::fromLocalFile(m_imagePath)); } else { QImage img(m_imagePath); m_imageItem->setImage(img); } if (!m_imageItem->imageIsValid()) { const QString msg = i18n("Cannot load image %1").arg(m_imagePath); m_textItem->setPlainText(msg); m_textItem->setVisible(true); m_imageItem->setVisible(false); } else { QSizeF size; if (worksheet()->isPrinting() && ! m_useDisplaySizeForPrinting) size = imageSize(m_printSize); else size = imageSize(m_displaySize); // Hack: Eps images need to be scaled if (m_imagePath.toLower().endsWith(QLatin1String(".eps"))) size /= worksheet()->epsRenderer()->scale(); m_imageItem->setSize(size); qDebug() << size; m_textItem->setVisible(false); m_imageItem->setVisible(true); } } qDebug() << oldHeight << height(); if (oldHeight != height()) recalculateSize(); } QSizeF ImageEntry::imageSize(const ImageSize& imgSize) { const QSize& srcSize = m_imageItem->imageSize(); qreal w, h; if (imgSize.heightUnit == ImageSize::Percent) h = srcSize.height() * imgSize.height / 100; else if (imgSize.heightUnit == ImageSize::Pixel) h = imgSize.height; if (imgSize.widthUnit == ImageSize::Percent) w = srcSize.width() * imgSize.width / 100; else if (imgSize.widthUnit == ImageSize::Pixel) w = imgSize.width; if (imgSize.widthUnit == ImageSize::Auto) { if (imgSize.heightUnit == ImageSize::Auto) return QSizeF(srcSize.width(), srcSize.height()); else if (h == 0) w = 0; else w = h / srcSize.height() * srcSize.width(); } else if (imgSize.heightUnit == ImageSize::Auto) { if (w == 0) h = 0; else h = w / srcSize.width() * srcSize.height(); } return QSizeF(w,h); } void ImageEntry::startConfigDialog() { ImageSettingsDialog* dialog = new ImageSettingsDialog(worksheet()->worksheetView()); dialog->setData(m_imagePath, m_displaySize, m_printSize, m_useDisplaySizeForPrinting); connect(dialog, &ImageSettingsDialog::dataChanged, this, &ImageEntry::setImageData); dialog->show(); } void ImageEntry::setImageData(const QString& path, const ImageSize& displaySize, const ImageSize& printSize, bool useDisplaySizeForPrinting) { if (path != m_imagePath) { m_imageWatcher->removePath(m_imagePath); m_imageWatcher->addPath(path); m_imagePath = path; } m_displaySize = displaySize; m_printSize = printSize; m_useDisplaySizeForPrinting = useDisplaySizeForPrinting; updateEntry(); } void ImageEntry::addActionsToBar(ActionBar* actionBar) { actionBar->addButton(QIcon::fromTheme(QLatin1String("configure")), i18n("Configure Image"), this, SLOT(startConfigDialog())); } void ImageEntry::layOutForWidth(qreal w, bool force) { if (size().width() == w && !force) return; double width; if (m_imageItem && m_imageItem->isVisible()) { m_imageItem->setGeometry(0, 0, w, true); width = m_imageItem->width(); } else { m_textItem->setGeometry(0, 0, w, true); width = m_textItem->width(); } setSize(QSizeF(width, height() + VerticalMargin)); } bool ImageEntry::wantToEvaluate() { return false; } bool ImageEntry::wantFocus() { return false; } diff --git a/src/lib/backend.cpp b/src/lib/backend.cpp index 92f1ecea..fdc84f75 100644 --- a/src/lib/backend.cpp +++ b/src/lib/backend.cpp @@ -1,207 +1,207 @@ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. --- Copyright (C) 2009 Alexander Rieder */ #include "backend.h" using namespace Cantor; #include #include #include #include #include #include #include #include #include "extension.h" class Cantor::BackendPrivate { public: QString name; QString comment; QString icon; QString url; bool enabled; }; Backend::Backend(QObject* parent, const QList args) : QObject(parent), d(new BackendPrivate) { Q_UNUSED(args) d->enabled=true; } Backend::~Backend() { delete d; } QString Backend::name() const { return d->name; } QString Backend::comment() const { return d->comment; } QString Backend::description() const { return comment(); } QString Backend::icon() const { return d->icon; } QString Backend::version() const { return QLatin1String(); } QString Backend::url() const { return d->url; } QUrl Backend::helpUrl() const { return QUrl(); } bool Backend::isEnabled() const { return d->enabled&&requirementsFullfilled(); } void Backend::setEnabled(bool enabled) { d->enabled=enabled; } static QList backendCache; QStringList Backend::listAvailableBackends() { QList backends=availableBackends(); QStringList l; foreach(Backend* b, backends) { if(b->isEnabled()) l<name(); } return l; } QList Backend::availableBackends() { //if we already have all backends Cached, just return the cache. //otherwise create the available backends if(!backendCache.isEmpty()) { return backendCache; } QStringList pluginDirs; foreach(const QString &dir, QCoreApplication::libraryPaths()){ pluginDirs << dir + QDir::separator() + QLatin1String("cantor/backends"); } QPluginLoader loader; foreach(const QString &dir, pluginDirs){ qDebug() << "dir: " << dir; QStringList plugins; QDir pluginDir = QDir(dir); plugins = pluginDir.entryList(); foreach (const QString &plugin, plugins){ if (plugin==QLatin1String(".") || plugin==QLatin1String("..")) continue; loader.setFileName(dir + QDir::separator() + plugin); if (!loader.load()){ qDebug() << "Error while loading plugin: " << plugin; continue; } KPluginFactory* factory = KPluginLoader(loader.fileName()).factory(); Backend* backend = factory->create(); KPluginMetaData info(loader); backend->d->name=info.name(); backend->d->comment=info.description(); backend->d->icon=info.iconName(); backend->d->url=info.website(); backendCache< backends=availableBackends(); foreach(Backend* b, backends) { if(b->name().toLower()==name.toLower() || b->id().toLower()==name.toLower()) return b; } - return 0; + return nullptr; } QWidget* Backend::settingsWidget(QWidget* parent) const { Q_UNUSED(parent) - return 0; + return nullptr; } KConfigSkeleton* Backend::config() const { - return 0; + return nullptr; } QStringList Backend::extensions() const { QList extensions=findChildren(QRegExp(QLatin1String(".*Extension"))); QStringList names; foreach(Extension* e, extensions) names<objectName(); return names; } Extension* Backend::extension(const QString& name) const { return findChild(name); } bool Backend::requirementsFullfilled() const { return true; } diff --git a/src/lib/backend.h b/src/lib/backend.h index 61b6c17e..8f7febcf 100644 --- a/src/lib/backend.h +++ b/src/lib/backend.h @@ -1,218 +1,218 @@ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. --- Copyright (C) 2009 Alexander Rieder */ #ifndef _BACKEND_H #define _BACKEND_H #include #include #include #include #include "cantor_export.h" class KConfigSkeleton; class QWidget; /** * Namespace collecting all Classes of the Cantor Libraries */ namespace Cantor { class Session; class Extension; class BackendPrivate; /** * The Backend class provides access to information about the backend. * It provides access to what features are supported by the backend, and * a factory method to create a new Session * It needs to be subclassed by all Backends. * * @author Alexander Rieder */ class CANTOR_EXPORT Backend : public QObject, public KXMLGUIClient { Q_OBJECT public: /** * This enum is used to specify the Features, supported by a backend. */ enum Capability{ Nothing = 0x0, ///< the Backend doesn't support any of the optional features LaTexOutput = 0x1, ///< it can output results as LaTeX code InteractiveMode = 0x2, /**< it supports an interactive workflow. (It means a command can ask for additional input while running */ SyntaxHighlighting = 0x4, ///< it offers a custom Syntax Highlighter Completion = 0x8, ///< it offers completion of partially typed commands SyntaxHelp = 0x10, /**< it offers help about a commands syntax, that will be shown in a tooltip */ VariableManagement= 0x20 ///< it offers access to the variables (for variable management panel) }; Q_DECLARE_FLAGS(Capabilities, Capability) protected: /** * Create a new Backend. Normally the static createBackend factory method * should be used. * @param parent the Parent object * @param args optional arguments (not used) */ - explicit Backend( QObject* parent = 0,const QList args=QList() ); + explicit Backend( QObject* parent = nullptr,const QList args=QList() ); /** * Destructor. Doesn't anything. */ ~Backend() override; public: /** * Creates a new Session. It is the way to go to create a Session, * don't call new Session on your own. * @return a new Session of this Backend, or 0 if creating failed */ virtual Session* createSession() = 0; /** * Returns list of the supported optional features * @return a list of features, containing items of the Capabiltiy enum, ORed together */ virtual Capabilities capabilities() const = 0; /** * Returns whether all of this backends requirements are fulfiled, or if some are missing. * @return @c true if all the requirements needed to use this Backend are fulfilled * @return @c false some requirements are missing. e.g. the maxima executable can not be found * @see Capablility */ virtual bool requirementsFullfilled() const; /** * Returns a unique string to identify this backend. * In contrast to name() this string isn't translated * @return string to identify backend */ virtual QString id() const = 0; /** * Returns the recommended version of the backend supported by Cantor * @return the recommended version of the backend */ virtual QString version() const; //Stuff extracted from the .desktop file /** * Returns the name of the backend * @return the backends name */ QString name() const; /** * Returns a short comment about the backend. * @return comment about the backend */ QString comment() const; /** * Returns the icon to use with this backend * @return name of the icon */ QString icon() const; /** * Returns the Url of the Homepage for the Backend * @return the url */ QString url() const; /** * Returns an Url pointing to the Help of the Backend * The method should be overwritten by all Backends(who have an online help) * You should make the returned Url translateble, e.g. by doing something like: * return i18nc("the url to the documentation of KAlgebra, please check if there is a translated version and use the correct url", * "http://docs.kde.org/stable/en/kdeedu/kalgebra/"); * @return Url of the help */ virtual QUrl helpUrl() const; /** * Returns if the backend should be enabled (shown in the Backend dialog) * @return @c true, if the enabled flag is set to true, and the requirements are fulfiled * @return @c false, if the backend was purposedly disabled, or requirements are missing * @see requirementsFullfilled() */ bool isEnabled() const; /** * Enables/disables this backend * @param enabled true to enable backend false to disable */ void setEnabled(bool enabled); /** * Returns a longer description of the Backend, e.g. purpose, strengths etc. * It should help the user to decide between the different Backends * @return a description of the backend. It can contain html */ virtual QString description() const; /** * Returns a Widget for configuring this backend * @return Widget for usage in the Settings dialog */ virtual QWidget* settingsWidget(QWidget* parent) const; /** * Returns a KConfig object, containing all the settings, * the backend might need * @return a KConfigSkeleton object, for configuring this backend */ virtual KConfigSkeleton* config() const; /** * Returns a list of the names of all the Extensions supported by this backend * @return a list of the names of all the Extensions supported by this backend * @see extension(const QString& name) */ QStringList extensions() const; /** * Returns an Extension of this backend for the given name, or null * if the Backend doesn't have an extension with this name. * @return Pointer to the Extension object with the given name */ Extension * extension(const QString& name) const; /** * Returns a list of the names of all the installed and enabled backends * @return a list of the names of all the installed and enabled backends * @see isEnabled() */ static QStringList listAvailableBackends(); /** * Returns Pointers to all the installed backends * @return Pointers to all the installed backends */ static QList availableBackends(); /** * Returns the backend with the given name, or null if it isn't found * @return the backend with the given name, or null if it isn't found */ static Backend* createBackend(const QString& name); private: BackendPrivate* d; }; Q_DECLARE_OPERATORS_FOR_FLAGS(Backend::Capabilities) } #endif /* _BACKEND_H */ diff --git a/src/lib/completionobject.cpp b/src/lib/completionobject.cpp index b111be16..0840677d 100644 --- a/src/lib/completionobject.cpp +++ b/src/lib/completionobject.cpp @@ -1,292 +1,292 @@ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. --- Copyright (C) 2009 Alexander Rieder */ #include "completionobject.h" using namespace Cantor; #include #include #include #include "session.h" class Cantor::CompletionObjectPrivate { public: QStringList completions; QString line; QString command; QString identifier; QString completion; int position; Session* session; bool parenCompletion; }; CompletionObject::CompletionObject(Session* session) : d(new CompletionObjectPrivate) { setParent(session); d->position = -1; d->session=session; connect(this, &CompletionObject::fetchingDone, this, &CompletionObject::findCompletion); connect(this, &CompletionObject::fetchingTypeDone, this, &CompletionObject::completeLineWithType); setCompletionMode(KCompletion::CompletionShell); } CompletionObject::~CompletionObject() { delete d; } QString CompletionObject::command() const { return d->command; } Session* CompletionObject::session() const { return d->session; } QStringList CompletionObject::completions() const { return d->completions; } QString CompletionObject::identifier() const { return d->identifier; } QString CompletionObject::completion() const { return d->completion; } void CompletionObject::setLine(const QString& line, int index) { d->parenCompletion = false; d->line = line; if (index < 0) index = line.length(); if (index > 1 && line[index-1] == QLatin1Char('(')) { --index; // move before the parenthesis d->parenCompletion = true; // but remember it was there } int cmd_index = locateIdentifier(line, index-1); if (cmd_index < 0) cmd_index = index; d->position=cmd_index; d->command=line.mid(cmd_index, index-cmd_index); //start a delayed fetch QTimer::singleShot(0, this, SLOT(fetchCompletions())); } void CompletionObject::updateLine(const QString& line, int index) { d->line = line; if (index < 0) index = line.length(); int cmd_index = locateIdentifier(line, index-1); if (cmd_index < 0) cmd_index = index; d->command=line.mid(cmd_index, index-cmd_index); // start a delayed fetch // For some backends this is a lot of unnecessary work... QTimer::singleShot(0, this, SLOT(fetchCompletions())); } void CompletionObject::completeLine(const QString& comp, CompletionObject::LineCompletionMode mode) { d->identifier = comp; if (comp.isEmpty()) { int index = d->position + d->command.length(); emit lineDone(d->line, index); } else if (mode == PreliminaryCompletion) { completeUnknownLine(); } else /* mode == FinalCompletion */ { QTimer::singleShot(0, this, SLOT(fetchIdentifierType())); } } void CompletionObject::fetchIdentifierType() { emit fetchingTypeDone(UnknownType); } void CompletionObject::setCompletions(const QStringList& completions) { d->completions=completions; this->setItems(completions); } void CompletionObject::setCommand(const QString& cmd) { d->command=cmd; } int CompletionObject::locateIdentifier(const QString& cmd, int index) const { if (index < 0) return -1; int i; for (i=index; i>=0 && mayIdentifierContain(cmd[i]); --i) {} if (i==index || !mayIdentifierBeginWith(cmd[i+1])) return -1; return i+1; } bool CompletionObject::mayIdentifierContain(QChar c) const { return c.isLetter() || c.isDigit() || c == QLatin1Char('_'); } bool CompletionObject::mayIdentifierBeginWith(QChar c) const { return c.isLetter() || c == QLatin1Char('_'); } void CompletionObject::findCompletion() { if (d->parenCompletion) { - disconnect(this, SIGNAL(fetchingTypeDone(IdentifierType)), 0, 0); + disconnect(this, SIGNAL(fetchingTypeDone(IdentifierType)), nullptr, nullptr); connect(this, &CompletionObject::fetchingTypeDone, this, &CompletionObject::handleParenCompletionWithType); d->identifier = d->command; fetchIdentifierType(); return; } d->completion = makeCompletion(command()); emit done(); } void CompletionObject::handleParenCompletionWithType(IdentifierType type) { - disconnect(this, SIGNAL(fetchingTypeDone(IdentifierType)), 0, 0); + disconnect(this, SIGNAL(fetchingTypeDone(IdentifierType)), nullptr, nullptr); connect(this, &CompletionObject::fetchingTypeDone, this, &CompletionObject::completeLineWithType); if (type == FunctionWithArguments || type == FunctionWithoutArguments) { d->completion = d->command; emit done(); } } void CompletionObject::completeLineWithType(IdentifierType type) { switch(type) { case VariableType: completeVariableLine(); break; case FunctionWithArguments: case FunctionWithoutArguments: completeFunctionLine(type); break; case KeywordType: completeKeywordLine(); break; case UnknownType: completeUnknownLine(); break; } } void CompletionObject::completeFunctionLine(IdentifierType type) { QString newline; int newindex; QString func = d->identifier; int after_command = d->position + d->command.length(); QString part1 = d->line.left(d->position) + func; int index = d->position + func.length() + 1; if (after_command < d->line.length() && d->line.at(after_command) == QLatin1Char('(')) { QString part2 = d->line.mid(after_command+1); int i; // search for next non-space position for (i = after_command+1; i < d->line.length() && d->line.at(i).isSpace(); ++i) {} if (type == FunctionWithArguments) { if (i < d->line.length()) { newline = part1+QLatin1Char('(')+part2; newindex = index; } else { newline = part1+QLatin1String("()")+part2; newindex = index; } } else /*type == FunctionWithoutArguments*/ { if (i < d->line.length() && d->line.at(i) == QLatin1Char(')')) { newline = part1+QLatin1Char('(')+part2; newindex = index+i-after_command; } else { newline = part1+QLatin1String("()")+part2; newindex = index+1; } } } else { QString part2 = d->line.mid(after_command); if (type == FunctionWithArguments) { newline = part1+QLatin1String("()")+part2; newindex = index; } else /*type == FunctionWithoutArguments*/ { newline = part1+QLatin1String("()")+part2; newindex = index+1; } } emit lineDone(newline, newindex); } void CompletionObject::completeKeywordLine() { QString keyword = d->identifier; int after_command = d->position + d->command.length(); int newindex = d->position + keyword.length() + 1; QString part1 = d->line.left(d->position) + keyword; QString part2 = d->line.mid(after_command); if (after_command < d->line.length() && d->line.at(after_command) == QLatin1Char(' ')) emit lineDone(part1+part2, newindex); else emit lineDone(part1+QLatin1Char(' ')+part2, newindex); } void CompletionObject::completeVariableLine() { QString var = d->identifier; int after_command = d->position + d->command.length(); QString newline = d->line.left(d->position) + var + d->line.mid(after_command); int newindex = d->position + var.length(); emit lineDone(newline, newindex); } void CompletionObject::completeUnknownLine() { // identifiers of unknown type are completed like variables completeVariableLine(); } diff --git a/src/lib/expression.cpp b/src/lib/expression.cpp index 250094d1..61e9c16d 100644 --- a/src/lib/expression.cpp +++ b/src/lib/expression.cpp @@ -1,281 +1,281 @@ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. --- Copyright (C) 2009 Alexander Rieder */ #include "expression.h" using namespace Cantor; #include #include "session.h" #include "result.h" #include "textresult.h" #include "imageresult.h" #include "latexresult.h" #include "settings.h" #include "latexrenderer.h" #include #include #include #include #include class Cantor::ExpressionPrivate { public: ExpressionPrivate() { - result=0; - session=0; + result=nullptr; + session=nullptr; isInternal=false; } int id; QString command; QString error; QList information; Result* result; Expression::Status status; Session* session; Expression::FinishingBehavior finishingBehavior; bool isInternal; }; static const QString tex=QLatin1String("\\documentclass[12pt,fleqn]{article} \n "\ "\\usepackage{latexsym,amsfonts,amssymb,ulem} \n "\ "\\usepackage[dvips]{graphicx} \n "\ "\\setlength\\textwidth{5in} \n "\ "\\setlength{\\parindent}{0pt} \n "\ "%1 \n "\ "\\pagestyle{empty} \n "\ "\\begin{document} \n "\ "%2 \n "\ "\\end{document}\n"); Expression::Expression( Session* session ) : QObject( session ), d(new ExpressionPrivate) { d->session=session; d->id=session->nextExpressionId(); } Expression::~Expression() { delete d->result; delete d; } void Expression::setCommand(const QString& command) { d->command=command; } QString Expression::command() { return d->command; } void Expression::setErrorMessage(const QString& error) { d->error=error; } QString Expression::errorMessage() { return d->error; } void Expression::setResult(Result* result) { if(d->result) delete d->result; d->result=result; - if(result!=0) + if(result!=nullptr) { qDebug()<<"settting result to a type "<type()<<" result"; #ifdef WITH_EPS //If it's text, and latex typesetting is enabled, render it if ( session()->isTypesettingEnabled()&& result->type()==TextResult::Type && dynamic_cast(result)->format()==TextResult::LatexFormat && !result->toHtml().trimmed().isEmpty() && finishingBehavior()!=DeleteOnFinish && !isInternal() ) { renderResultAsLatex(); } #endif } emit gotResult(); } Result* Expression::result() { return d->result; } void Expression::clearResult() { if(d->result) delete d->result; - d->result=0; + d->result=nullptr; } void Expression::setStatus(Expression::Status status) { d->status=status; emit statusChanged(status); if(status==Expression::Done&&d->finishingBehavior==Expression::DeleteOnFinish) deleteLater(); } Expression::Status Expression::status() { return d->status; } Session* Expression::session() { return d->session; } void Expression::renderResultAsLatex() { qDebug()<<"rendering as latex"; qDebug()<<"checking if it really is a formula that can be typeset"; LatexRenderer* renderer=new LatexRenderer(this); renderer->setLatexCode(result()->data().toString().trimmed()); renderer->addHeader(additionalLatexHeaders()); connect(renderer, &LatexRenderer::done, this, &Expression::latexRendered); connect(renderer, &LatexRenderer::error, this, &Expression::latexRendered); renderer->render(); } void Expression::latexRendered() { LatexRenderer* renderer=qobject_cast(sender()); qDebug()<<"rendered a result to "<imagePath(); //replace the textresult with the rendered latex image result //ImageResult* latex=new ImageResult( d->latexFilename ); if(renderer->renderingSuccessful()&&result()) { if (result()->type() == TextResult::Type) { TextResult* r=dynamic_cast(result()); LatexResult* latex=new LatexResult(r->data().toString().trimmed(), QUrl::fromLocalFile(renderer->imagePath()), r->plain()); setResult( latex ); } else if (result()->type() == LatexResult::Type) { LatexResult* previousLatexResult=dynamic_cast(result()); LatexResult* latex=new LatexResult(previousLatexResult->data().toString().trimmed(), QUrl::fromLocalFile(renderer->imagePath()), previousLatexResult->plain()); setResult( latex ); } }else { //if rendering with latex was not successful, just use the plain text version //if available TextResult* r=dynamic_cast(result()); setResult(new TextResult(r->plain())); qDebug()<<"error rendering latex: "<errorMessage(); } renderer->deleteLater(); } //saving code QDomElement Expression::toXml(QDomDocument& doc) { QDomElement expr=doc.createElement( QLatin1String("Expression") ); QDomElement cmd=doc.createElement( QLatin1String("Command") ); QDomText cmdText=doc.createTextNode( command() ); cmd.appendChild( cmdText ); expr.appendChild( cmd ); if ( result() ) { qDebug()<<"result: "<toXml( doc ); expr.appendChild( resXml ); } return expr; } void Expression::saveAdditionalData(KZip* archive) { //just pass this call to the result if(result()) result()->saveAdditionalData(archive); } void Expression::addInformation(const QString& information) { d->information.append(information); } QString Expression::additionalLatexHeaders() { return QString(); } int Expression::id() { return d->id; } void Expression::setId(int id) { d->id=id; emit idChanged(); } void Expression::setFinishingBehavior(Expression::FinishingBehavior behavior) { d->finishingBehavior=behavior; } Expression::FinishingBehavior Expression::finishingBehavior() { return d->finishingBehavior; } void Expression::setInternal(bool internal) { d->isInternal=internal; } bool Expression::isInternal() { return d->isInternal; } diff --git a/src/lib/extension.cpp b/src/lib/extension.cpp index 98a389cb..b761c195 100644 --- a/src/lib/extension.cpp +++ b/src/lib/extension.cpp @@ -1,166 +1,166 @@ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. --- Copyright (C) 2009 Alexander Rieder */ #include "extension.h" using namespace Cantor; #include #define EXTENSION_CONSTRUCTORS(name) name::name(QObject* parent) : Extension(QLatin1String(#name),parent) {} \ name::~name() {} Extension::Extension(const QString& name, QObject* parent) : QObject(parent) { setObjectName(name); } Extension::~Extension() { } EXTENSION_CONSTRUCTORS(HistoryExtension) EXTENSION_CONSTRUCTORS(ScriptExtension) EXTENSION_CONSTRUCTORS(CASExtension) EXTENSION_CONSTRUCTORS(CalculusExtension) EXTENSION_CONSTRUCTORS(PlotExtension) EXTENSION_CONSTRUCTORS(AdvancedPlotExtension) EXTENSION_CONSTRUCTORS(LinearAlgebraExtension) EXTENSION_CONSTRUCTORS(VariableManagementExtension) EXTENSION_CONSTRUCTORS(PackagingExtension) //implement this here, as it's ";" most of the time QString ScriptExtension::commandSeparator() { return QLatin1String(";\n"); } //implement this here, as it's "#" most of the time QString ScriptExtension::commentStartingSequence() { return QLatin1String("#"); } //implement this here, as it's "" most of the time QString ScriptExtension::commentEndingSequence() { return QLatin1String(""); } //some convenience functions, but normally backends have a special command to create //these matrices/vectors. QString LinearAlgebraExtension::nullVector(int size, VectorType type) { QStringList values; for (int i=0;i directives) const { QString params = QLatin1String(""); foreach (PlotDirective* dir, directives) { QString param=dispatchDirective(*dir); if (param.length()>0) params+=separatorSymbol()+param; } return plotCommand() + QLatin1String("(") + expression + params + QLatin1String(")"); } QString AdvancedPlotExtension::dispatchDirective(const PlotDirective& directive) const { const AcceptorBase* acceptor=dynamic_cast(this); - if (acceptor==NULL) + if (acceptor==nullptr) { qDebug()<<"Plotting extension does not support any directives, but was asked to process one"; return QLatin1String(""); } return directive.dispatch(*acceptor); } QString AdvancedPlotExtension::separatorSymbol() const { return QLatin1String(","); } QWidget* AdvancedPlotExtension::PlotDirective::widget(QWidget* parent) { return new QWidget(parent); } AdvancedPlotExtension::PlotDirective::PlotDirective() { } AdvancedPlotExtension::PlotDirective::~PlotDirective() { } AdvancedPlotExtension::AcceptorBase::AcceptorBase() : m_widgets() { } AdvancedPlotExtension::AcceptorBase::~AcceptorBase() { } const QVector& AdvancedPlotExtension::AcceptorBase::widgets() const { return m_widgets; } AdvancedPlotExtension::DirectiveProducer::DirectiveProducer(QWidget* parent) : QWidget(parent) { } diff --git a/src/lib/latexrenderer.h b/src/lib/latexrenderer.h index 616b8624..40ff9626 100644 --- a/src/lib/latexrenderer.h +++ b/src/lib/latexrenderer.h @@ -1,78 +1,78 @@ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. --- Copyright (C) 2011 Alexander Rieder */ #ifndef _LATEXRENDERER_H #define _LATEXRENDERER_H #include #include "cantor_export.h" namespace Cantor{ class LatexRendererPrivate; class CANTOR_EXPORT LatexRenderer : public QObject { Q_OBJECT public: enum Method{ LatexMethod = 0, MmlMethod = 1}; enum EquationType{ InlineEquation = 0, FullEquation = 1}; - LatexRenderer( QObject* parent = 0); + LatexRenderer( QObject* parent = nullptr); ~LatexRenderer() override; QString latexCode() const; void setLatexCode(const QString& src); QString header() const; void addHeader(const QString& header); void setHeader(const QString& header); Method method() const; void setMethod( Method method); void setEquationOnly(bool isEquationOnly); bool isEquationOnly() const; void setEquationType(EquationType type); EquationType equationType() const; QString errorMessage() const; bool renderingSuccessful() const; QString imagePath() const; Q_SIGNALS: void done(); void error(); public Q_SLOTS: void render(); void renderBlocking(); private: void setErrorMessage(const QString& msg); private Q_SLOTS: void renderWithLatex(); void renderWithMml(); void convertToPs(); void convertingDone(); private: LatexRendererPrivate* d; }; } #endif /* _LATEXRENDERER_H */ diff --git a/src/lib/panelplugin.cpp b/src/lib/panelplugin.cpp index 299f9e03..df0c1f40 100644 --- a/src/lib/panelplugin.cpp +++ b/src/lib/panelplugin.cpp @@ -1,97 +1,97 @@ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. --- Copyright (C) 2010 Alexander Rieder */ #include "panelplugin.h" using namespace Cantor; #include #include class Cantor::PanelPluginPrivate { public: QString name; QStringList requiredExtensions; Session* session; QWidget* parentWidget; }; PanelPlugin::PanelPlugin( QObject* parent) : QObject(parent), /* KXMLGUIClient(dynamic_cast(parent)),*/ d(new PanelPluginPrivate) { - d->parentWidget=0; - d->session=0; + d->parentWidget=nullptr; + d->session=nullptr; } PanelPlugin::~PanelPlugin() { delete d; } void PanelPlugin::setParentWidget(QWidget* widget) { d->parentWidget=widget; } QWidget* PanelPlugin::parentWidget() { return d->parentWidget; } void PanelPlugin::setPluginInfo(KPluginMetaData info) { d->name=info.name(); d->requiredExtensions=info.value(QLatin1String("RequiredExtensions")).split(QLatin1Char(',')); } QStringList PanelPlugin::requiredExtensions() { return d->requiredExtensions; } Backend::Capabilities PanelPlugin::requiredCapabilities() { return Backend::Nothing; } QString PanelPlugin::name() { return d->name; } Session* PanelPlugin::session() { return d->session; } void PanelPlugin::setSession(Session* session) { qDebug()<<"setting session to "<session=session; onSessionChanged(); } void PanelPlugin::onSessionChanged() { } diff --git a/src/lib/panelpluginhandler.cpp b/src/lib/panelpluginhandler.cpp index 6b62aac9..05636b14 100644 --- a/src/lib/panelpluginhandler.cpp +++ b/src/lib/panelpluginhandler.cpp @@ -1,133 +1,133 @@ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. --- Copyright (C) 2010 Alexander Rieder */ #include "panelpluginhandler.h" using namespace Cantor; #include #include #include #include #include #include "session.h" #include "panelplugin.h" #include "backend.h" class Cantor::PanelPluginHandlerPrivate { public: QList plugins; Cantor::Session* session; }; PanelPluginHandler::PanelPluginHandler( QObject* parent ) : QObject(parent) , d(new PanelPluginHandlerPrivate) { setObjectName(QLatin1String("PanelPluginHandler")); - d->session=0; + d->session=nullptr; } PanelPluginHandler::~PanelPluginHandler() { delete d; } void PanelPluginHandler::loadPlugins() { - if(d->session==0) + if(d->session==nullptr) return; qDebug()<<"loading panel plugins for session of type "<session->backend()->name(); QStringList panelDirs; foreach(const QString &dir, QCoreApplication::libraryPaths()){ panelDirs << dir + QDir::separator() + QLatin1String("cantor/panels"); } QPluginLoader loader; foreach(const QString &dir, panelDirs){ qDebug() << "dir: " << dir; QStringList panels; QDir panelDir = QDir(dir); panels = panelDir.entryList(); foreach (const QString &panel, panels){ if (panel==QLatin1String(".") || panel==QLatin1String("..")) continue; loader.setFileName(dir + QDir::separator() + panel); if (!loader.load()){ qDebug() << "Error while loading panel: " << panel; continue; } KPluginFactory* factory = KPluginLoader(loader.fileName()).factory(); PanelPlugin* plugin = factory->create(this); KPluginMetaData info(loader); plugin->setPluginInfo(info); qDebug()<<"plugin "<requiredExtensions(); bool supported=true; foreach(const QString& req, plugin->requiredExtensions()){ // FIXME: That req.isEmpty() is there just because Help Panel has req // empty, returning FALSE when the comparision must to return TRUE. supported=supported && (d->session->backend()->extensions().contains(req) || req.isEmpty()); } supported=supported && ( (d->session->backend()->capabilities() & plugin->requiredCapabilities()) == plugin->requiredCapabilities()); qDebug()<<"plugin "<plugins.append(plugin); plugin->setSession(d->session); }else { plugin->deleteLater(); } } } emit pluginsChanged(); } void PanelPluginHandler::setSession(Session* session) { qDeleteAll(d->plugins); d->plugins.clear(); d->session=session; loadPlugins(); } QList PanelPluginHandler::plugins() { return d->plugins; } void PanelPluginHandler::addPlugin(PanelPlugin* plugin) { d->plugins.append(plugin); } diff --git a/src/lib/session.cpp b/src/lib/session.cpp index 97afe3fe..9795b109 100644 --- a/src/lib/session.cpp +++ b/src/lib/session.cpp @@ -1,125 +1,125 @@ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. --- Copyright (C) 2009 Alexander Rieder */ #include "session.h" using namespace Cantor; #include "backend.h" class Cantor::SessionPrivate { public: SessionPrivate() { - backend=0; + backend=nullptr; expressionCount=0; typesettingEnabled=false; } Backend* backend; Session::Status status; bool typesettingEnabled; int expressionCount; }; Session::Session( Backend* backend ) : QObject(backend), d(new SessionPrivate) { d->backend=backend; } Session::~Session() { delete d; } Expression* Session::evaluateExpression(const QString& command) { return evaluateExpression(command, Expression::DoNotDelete); } Backend* Session::backend() { return d->backend; } Cantor::Session::Status Session::status() { return d->status; } void Session::changeStatus(Session::Status newStatus) { d->status=newStatus; emit statusChanged(newStatus); } void Session::setTypesettingEnabled(bool enable) { d->typesettingEnabled=enable; } bool Session::isTypesettingEnabled() { return d->typesettingEnabled; } CompletionObject* Session::completionFor(const QString& cmd, int index) { Q_UNUSED(cmd); Q_UNUSED(index); //Return 0 per default, so Backends not offering tab completions don't have //to reimplement this. This method should only be called on backends with //the Completion Capability flag - return 0; + return nullptr; } SyntaxHelpObject* Session::syntaxHelpFor(const QString& cmd) { Q_UNUSED(cmd); //Return 0 per default, so Backends not offering tab completions don't have //to reimplement this. This method should only be called on backends with //the SyntaxHelp Capability flag - return 0; + return nullptr; } QSyntaxHighlighter* Session::syntaxHighlighter(QObject* parent) { Q_UNUSED(parent); - return 0; + return nullptr; } QAbstractItemModel* Session::variableModel() { //Return 0 per default, so Backends not offering variable management don't //have to reimplement this. This method should only be called on backends with //VariableManagement Capability flag - return 0; + return nullptr; } int Session::nextExpressionId() { return d->expressionCount++; } diff --git a/src/lib/test/backendtest.cpp b/src/lib/test/backendtest.cpp index d9eb20c2..37eadb0c 100644 --- a/src/lib/test/backendtest.cpp +++ b/src/lib/test/backendtest.cpp @@ -1,107 +1,107 @@ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. --- Copyright (C) 2009 Alexander Rieder */ #include "backendtest.h" #include "backend.h" #include "session.h" #include #include void BackendTest::createSession() { Cantor::Backend* b=Cantor::Backend::createBackend( backendName() ); if(!b || !b->requirementsFullfilled() ) { - m_session = 0; + m_session = nullptr; return; } m_session=b->createSession(); QSignalSpy spy(m_session, SIGNAL( loginDone() ) ); m_session->login(); if(spy.isEmpty()) waitForSignal(m_session, SIGNAL( loginDone() ) ); QVERIFY(!spy.isEmpty()); } Cantor::Expression* BackendTest::evalExp(const QString& exp ) { Cantor::Expression* e=m_session->evaluateExpression(exp); if(e->status()==Cantor::Expression::Computing) { waitForSignal( e, SIGNAL( statusChanged( Cantor::Expression::Status ) ) ); } return e; } QString BackendTest::cleanOutput(const QString& out) { QString cleaned=out; cleaned.replace( QLatin1String(" "),QLatin1String(" ") ); cleaned.remove( QLatin1String("
    ") ); cleaned.replace( QChar::ParagraphSeparator, QLatin1Char('\n') ); cleaned.replace( QRegExp( QLatin1String("\\n\\n") ), QLatin1String("\n") ); cleaned.replace( QRegExp( QLatin1String("\\n\\s*") ), QLatin1String("\n") ); return cleaned.trimmed(); } void BackendTest::initTestCase() { createSession(); if (!m_session) { QString reason = i18n("This test requires a functioning %1 backend", backendName() ); QSKIP( reason.toStdString().c_str(), SkipAll ); } } void BackendTest::cleanupTestCase() { if (m_session) { m_session->logout(); } } Cantor::Session* BackendTest::session() { return m_session; } void BackendTest::waitForSignal(QObject* sender, const char* signal) { QTimer timeout( this ); timeout.setSingleShot( true ); QEventLoop loop; connect( sender, signal, &loop, SLOT( quit() ) ); connect(&timeout, &QTimer::timeout, &loop, &QEventLoop::quit); timeout.start( 5000 ); loop.exec(); } diff --git a/src/loadedexpression.cpp b/src/loadedexpression.cpp index a35133cb..951d8aa7 100644 --- a/src/loadedexpression.cpp +++ b/src/loadedexpression.cpp @@ -1,89 +1,89 @@ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. --- Copyright (C) 2009 Alexander Rieder */ #include "loadedexpression.h" #include "lib/imageresult.h" #include "lib/epsresult.h" #include "lib/textresult.h" #include "lib/latexresult.h" #include "lib/animationresult.h" #include #include LoadedExpression::LoadedExpression( Cantor::Session* session ) : Cantor::Expression( session ) { } LoadedExpression::~LoadedExpression() { } void LoadedExpression::interrupt() { //Do nothing } void LoadedExpression::evaluate() { //Do nothing } void LoadedExpression::loadFromXml(const QDomElement& xml, const KZip& file) { setCommand(xml.firstChildElement(QLatin1String("Command")).text()); QDomElement resultElement=xml.firstChildElement(QLatin1String("Result")); - Cantor::Result* result=0; + Cantor::Result* result=nullptr; const QString& type=resultElement.attribute(QLatin1String("type")); if ( type == QLatin1String("text")) { result=new Cantor::TextResult(resultElement.text()); } else if (type == QLatin1String("image") || type == QLatin1String("latex") || type == QLatin1String("animation")) { const KArchiveEntry* imageEntry=file.directory()->entry(resultElement.attribute(QLatin1String("filename"))); if (imageEntry&&imageEntry->isFile()) { const KArchiveFile* imageFile=static_cast(imageEntry); QString dir=QStandardPaths::writableLocation(QStandardPaths::TempLocation) + QLatin1String("/") + QLatin1String("cantor"); imageFile->copyTo(dir); QUrl imageUrl = QUrl::fromLocalFile(QDir(dir).absoluteFilePath(imageFile->name())); if(type==QLatin1String("latex")) { result=new Cantor::LatexResult(resultElement.text(), imageUrl); }else if(type==QLatin1String("animation")) { result=new Cantor::AnimationResult(imageUrl); }else if(imageFile->name().endsWith(QLatin1String(".eps"))) { result=new Cantor::EpsResult(imageUrl); }else { result=new Cantor::ImageResult(imageUrl); } } } setResult(result); } diff --git a/src/panelplugins/helppanel/helppanelplugin.cpp b/src/panelplugins/helppanel/helppanelplugin.cpp index 9c9719e1..831e268c 100644 --- a/src/panelplugins/helppanel/helppanelplugin.cpp +++ b/src/panelplugins/helppanel/helppanelplugin.cpp @@ -1,74 +1,74 @@ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. --- Copyright (C) 2010 Alexander Rieder */ #include "helppanelplugin.h" #include #include #include "cantor_macros.h" HelpPanelPlugin::HelpPanelPlugin(QObject* parent, QList args) : Cantor::PanelPlugin(parent) { Q_UNUSED(args); - m_edit=0; + m_edit=nullptr; } HelpPanelPlugin::~HelpPanelPlugin() { delete m_edit; } QWidget* HelpPanelPlugin::widget() { - if(m_edit==0) + if(m_edit==nullptr) { m_edit=new KTextEdit(parentWidget()); setHelpHtml(i18n("

    Cantor

    The KDE way to do Mathematics")); m_edit->setTextInteractionFlags(Qt::TextBrowserInteraction); connect(parent()->parent(), SIGNAL(showHelp(QString)), this, SLOT(setHelpHtml(QString))); connect(parent()->parent(), SIGNAL(showHelp(QString)), this, SIGNAL(visibilityRequested())); } return m_edit; } void HelpPanelPlugin::setHelpHtml(const QString& help) { if(!m_edit) return; m_edit->setHtml(help); m_edit->selectAll(); m_edit->setFontFamily(QLatin1String("Monospace")); m_edit->moveCursor(QTextCursor::Start); } void HelpPanelPlugin::showHelp(const QString& help) { if(m_edit) m_edit->setHtml(help); } K_PLUGIN_FACTORY_WITH_JSON(helppanelplugin, "helppanelplugin.json", registerPlugin();) #include "helppanelplugin.moc" diff --git a/src/panelplugins/variablemgr/variablemanagerplugin.cpp b/src/panelplugins/variablemgr/variablemanagerplugin.cpp index 233ba3c6..aa0852c4 100644 --- a/src/panelplugins/variablemgr/variablemanagerplugin.cpp +++ b/src/panelplugins/variablemgr/variablemanagerplugin.cpp @@ -1,65 +1,65 @@ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. --- Copyright (C) 2010 Alexander Rieder */ #include "variablemanagerplugin.h" #include #include "cantor_macros.h" #include "session.h" #include "variablemanagerwidget.h" VariableManagerPlugin::VariableManagerPlugin(QObject* parent, QList args) : Cantor::PanelPlugin(parent) { Q_UNUSED(args); - m_widget=0; + m_widget=nullptr; } VariableManagerPlugin::~VariableManagerPlugin() { delete m_widget; } void VariableManagerPlugin::onSessionChanged() { if(m_widget) m_widget->setSession(session()); } QWidget* VariableManagerPlugin::widget() { - if(m_widget==0) + if(m_widget==nullptr) { qDebug()<<"creating new widget"; m_widget=new VariableManagerWidget(session(), parentWidget()); connect(m_widget.data(), &VariableManagerWidget::runCommand, this, &VariableManagerPlugin::requestRunCommand); } return m_widget; } Cantor::Backend::Capabilities VariableManagerPlugin::requiredCapabilities() { return Cantor::Backend::VariableManagement; } K_PLUGIN_FACTORY_WITH_JSON(variablemanagerplugin, "variablemanagerplugin.json", registerPlugin();) #include "variablemanagerplugin.moc" diff --git a/src/panelplugins/variablemgr/variablemanagerwidget.cpp b/src/panelplugins/variablemgr/variablemanagerwidget.cpp index b4edcb22..2102f6d1 100644 --- a/src/panelplugins/variablemgr/variablemanagerwidget.cpp +++ b/src/panelplugins/variablemgr/variablemanagerwidget.cpp @@ -1,194 +1,194 @@ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. --- Copyright (C) 2010 Alexander Rieder */ #include "variablemanagerwidget.h" #include #include #include #include #include #include #include #include #include "session.h" #include "extension.h" #include "backend.h" #include "ui_newvardlg.h" -VariableManagerWidget::VariableManagerWidget(Cantor::Session* session, QWidget* parent) : QWidget(parent), m_session(0) +VariableManagerWidget::VariableManagerWidget(Cantor::Session* session, QWidget* parent) : QWidget(parent), m_session(nullptr) { QVBoxLayout* layout=new QVBoxLayout(this); m_table=new QTreeView(this); m_table->setRootIsDecorated(false); layout->addWidget(m_table, 1); QHBoxLayout* btnLayout=new QHBoxLayout(); int size=KIconLoader::global()->currentSize(KIconLoader::MainToolbar); QToolButton* m_newBtn=new QToolButton(this); m_newBtn->setIcon(QIcon::fromTheme(QLatin1String("document-new"))); m_newBtn->setToolTip(i18n("Add new variable")); m_newBtn->setIconSize(QSize(size, size)); connect(m_newBtn, &QToolButton::clicked, this, &VariableManagerWidget::newVariable); btnLayout->addWidget(m_newBtn); QToolButton* m_loadBtn=new QToolButton(this); m_loadBtn->setIcon(QIcon::fromTheme(QLatin1String("document-open"))); m_loadBtn->setToolTip(i18n("Load Variables")); m_loadBtn->setIconSize(QSize(size, size)); connect(m_loadBtn, &QToolButton::clicked, this, &VariableManagerWidget::load); btnLayout->addWidget(m_loadBtn); QToolButton* m_saveBtn=new QToolButton(this); m_saveBtn->setIcon(QIcon::fromTheme(QLatin1String("document-save"))); m_saveBtn->setToolTip(i18n("Store Variables")); m_saveBtn->setIconSize(QSize(size, size)); connect(m_saveBtn, &QToolButton::clicked, this, &VariableManagerWidget::save); btnLayout->addWidget(m_saveBtn); QToolButton* m_clearBtn=new QToolButton(this); m_clearBtn->setIcon(QIcon::fromTheme(QLatin1String("edit-clear"))); m_clearBtn->setToolTip(i18n("Clear Variables")); m_clearBtn->setIconSize(QSize(size, size)); connect(m_clearBtn, &QToolButton::clicked, this, &VariableManagerWidget::clearVariables); btnLayout->addWidget(m_clearBtn); layout->addLayout(btnLayout); setSession(session); //check for the methods the backend actually supports, and disable the buttons accordingly Cantor::VariableManagementExtension* ext= dynamic_cast(m_session->backend()->extension(QLatin1String("VariableManagementExtension"))); if(ext->loadVariables(QString()).isNull()) m_loadBtn->setDisabled(true); if(ext->saveVariables(QString()).isNull()) m_saveBtn->setDisabled(true); if(ext->addVariable(QString(), QString()).isNull()) m_newBtn->setDisabled(true); if(ext->clearVariables().isNull()) m_clearBtn->setDisabled(true); } VariableManagerWidget::~VariableManagerWidget() { } void VariableManagerWidget::setSession(Cantor::Session* session) { qDebug()<<"setting session to "<variableModel(); qDebug()<<"model: "<setModel(m_model); } } void VariableManagerWidget::clearVariables() { int btn=KMessageBox::questionYesNo(this, i18n("Are you sure you want to remove all variables?"), i18n("Confirmation - Cantor")); if(btn==KMessageBox::Yes) { qDebug()<<"removing it all"; m_model->removeRows(0, m_model->rowCount()); //evaluate the "clear" command Cantor::VariableManagementExtension* ext= dynamic_cast(m_session->backend()->extension(QLatin1String("VariableManagementExtension"))); const QString& cmd=ext->clearVariables(); emit runCommand(cmd); //HACK? should the model detect that this happened on its own? //inform the model that all variables have been removed. //Do so by trying to evaluate the clearVariables slot of //DefaultVariableModel. If our model isn't one of those, //this call will just do nothing. QMetaObject::invokeMethod(m_model, "clearVariables", Qt::QueuedConnection); } } void VariableManagerWidget::save() { const QString file=QFileDialog::getSaveFileName(this, i18n("Save"), QString(), QString()); if (file.trimmed().isEmpty()) return; Cantor::VariableManagementExtension* ext= dynamic_cast(m_session->backend()->extension(QLatin1String("VariableManagementExtension"))); const QString& cmd=ext->saveVariables(file); emit runCommand(cmd); } void VariableManagerWidget::load() { const QString file=QFileDialog::getOpenFileName(this, i18n("Load file"), QString(), QString()); if (file.trimmed().isEmpty()) return; Cantor::VariableManagementExtension* ext= dynamic_cast(m_session->backend()->extension(QLatin1String("VariableManagementExtension"))); const QString& cmd=ext->loadVariables(file); emit runCommand(cmd); } void VariableManagerWidget::newVariable() { QPointer dlg=new QDialog(this); QWidget *widget=new QWidget(dlg); Ui::NewVariableDialogBase base; base.setupUi(widget); QVBoxLayout *mainLayout = new QVBoxLayout; dlg->setLayout(mainLayout); base.buttonBox->button(QDialogButtonBox::Ok)->setIcon(QApplication::style()->standardIcon(QStyle::SP_DialogOkButton)); base.buttonBox->button(QDialogButtonBox::Cancel)->setIcon(QApplication::style()->standardIcon(QStyle::SP_DialogCancelButton)); connect(base.buttonBox, SIGNAL(accepted()), dlg, SLOT(accept()) ); connect(base.buttonBox, SIGNAL(rejected()), dlg, SLOT(reject()) ); mainLayout->addWidget(widget); if( dlg->exec()) { const QString& name=base.name->text(); const QString& val=base.value->text(); Cantor::VariableManagementExtension* ext= dynamic_cast(m_session->backend()->extension(QLatin1String("VariableManagementExtension"))); const QString& cmd=ext->addVariable(name, val); emit runCommand(cmd); } delete dlg; } diff --git a/src/resultitem.cpp b/src/resultitem.cpp index a579ce1e..94b212e6 100644 --- a/src/resultitem.cpp +++ b/src/resultitem.cpp @@ -1,86 +1,86 @@ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. --- Copyright (C) 2012 Martin Kuettler */ #include "resultitem.h" #include "textresultitem.h" #include "imageresultitem.h" #include "animationresultitem.h" #include "worksheetentry.h" #include "lib/result.h" #include "lib/textresult.h" #include "lib/latexresult.h" #include "lib/imageresult.h" #include "lib/epsresult.h" #include "lib/animationresult.h" #include #include #include #include ResultItem::ResultItem() { } ResultItem::~ResultItem() { } ResultItem* ResultItem::create(WorksheetEntry* parent, Cantor::Result* result) { switch(result->type()) { case Cantor::TextResult::Type: case Cantor::LatexResult::Type: { TextResultItem* item = new TextResultItem(parent); item->updateFromResult(result); return item; } case Cantor::ImageResult::Type: case Cantor::EpsResult::Type: { ImageResultItem* item = new ImageResultItem(parent); item->updateFromResult(result); return item; } case Cantor::AnimationResult::Type: { AnimationResultItem* item = new AnimationResultItem(parent); item->updateFromResult(result); return item; } default: - return 0; + return nullptr; } } void ResultItem::addCommonActions(QObject* self, QMenu* menu) { menu->addAction(i18n("Save result"), self, SLOT(saveResult())); menu->addAction(QIcon::fromTheme(QLatin1String("edit-delete")), i18n("Remove result"), self, SIGNAL(removeResult())); } QGraphicsObject* ResultItem::graphicsObject() { return dynamic_cast(this); } diff --git a/src/scripteditorwidget.cpp b/src/scripteditorwidget.cpp index 63e9a909..79cd52be 100644 --- a/src/scripteditorwidget.cpp +++ b/src/scripteditorwidget.cpp @@ -1,155 +1,155 @@ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. --- Copyright (C) 2009 Alexander Rieder */ #include "scripteditorwidget.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // #include #include ScriptEditorWidget::ScriptEditorWidget(const QString& filter, const QString& highlightingMode, QWidget* parent) : KXmlGuiWindow(parent) { setObjectName(QLatin1String("ScriptEditor")); m_filter=filter; - m_tmpFile=0; + m_tmpFile=nullptr; KStandardAction::openNew(this, SLOT(newScript()), actionCollection()); KStandardAction::open(this, SLOT(open()), actionCollection()); KStandardAction::close(this, SLOT(close()), actionCollection()); QAction * runAction = actionCollection()->addAction(QLatin1String("file_execute"), this, SLOT(run())); runAction->setIcon(QIcon::fromTheme(QLatin1String("system-run"))); runAction->setText(i18n("Run Script")); KTextEditor::Editor* editor = KTextEditor::Editor::instance(); if (!editor) { KMessageBox::error(this, i18n("A KDE text-editor component could not be found;\n" "please check your KDE installation.")); - m_script=0; + m_script=nullptr; } else { - m_script=editor->createDocument(0); + m_script=editor->createDocument(nullptr); m_editor=qobject_cast(m_script->createView(this)); m_script->setHighlightingMode(highlightingMode); KConfigGroup cg(KSharedConfig::openConfig(), "ScriptEditor"); setAutoSaveSettings(cg, true); setCentralWidget(m_editor); setupGUI(QSize(500,600), Default, QLatin1String("cantor_scripteditor.rc")); guiFactory()->addClient(m_editor); KWindowConfig::restoreWindowSize(this->windowHandle(), cg); connect(m_script, &KTextEditor::Document::modifiedChanged, this, &ScriptEditorWidget::updateCaption); connect(m_script, &KTextEditor::Document::documentUrlChanged, this, &ScriptEditorWidget::updateCaption); updateCaption(); } } ScriptEditorWidget::~ScriptEditorWidget() { } void ScriptEditorWidget::newScript() { QString highlightingMode = m_script->highlightingMode(); m_script->closeUrl(); m_script->setHighlightingMode(highlightingMode); } void ScriptEditorWidget::open() { QUrl url = QFileDialog::getOpenFileUrl(this, QString(), QUrl(), m_filter); m_script->openUrl(url); } void ScriptEditorWidget::run() { QString filename; if(!m_script->url().isLocalFile()) { // If the script is not in a local file, write it to a temporary file - if(m_tmpFile==0) + if(m_tmpFile==nullptr) { m_tmpFile=new QTemporaryFile(); } else { m_tmpFile->resize(0); } m_tmpFile->open(); QString text=m_script->text(); m_tmpFile->write(text.toUtf8()); m_tmpFile->close(); filename=m_tmpFile->fileName(); }else { m_script->save(); filename=m_script->url().toLocalFile(); } qDebug()<<"running "<queryClose(); else return true; } void ScriptEditorWidget::updateCaption() { QString fileName = m_script->url().toLocalFile(); bool modified = m_script->isModified(); if (fileName.isEmpty()) { setCaption(i18n("Script Editor"), modified); }else { setCaption(i18n("Script Editor - %1", fileName), modified); } } diff --git a/src/scripteditorwidget.h b/src/scripteditorwidget.h index 59d5d0e4..fd16ef53 100644 --- a/src/scripteditorwidget.h +++ b/src/scripteditorwidget.h @@ -1,61 +1,61 @@ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. --- Copyright (C) 2009 Alexander Rieder */ #ifndef _SCRIPTEDITORWIDGET_H #define _SCRIPTEDITORWIDGET_H #include class QTemporaryFile; class QGridLayout; namespace KTextEditor { class View; class Document; } class ScriptEditorWidget : public KXmlGuiWindow { Q_OBJECT public: - explicit ScriptEditorWidget( const QString& filter, const QString& highlightingMode, QWidget* parent = 0 ); + explicit ScriptEditorWidget( const QString& filter, const QString& highlightingMode, QWidget* parent = nullptr ); ~ScriptEditorWidget() override; Q_SIGNALS: void runScript(const QString& filename); private Q_SLOTS: void newScript(); void open(); void run(); void updateCaption(); protected: bool queryClose() Q_DECL_OVERRIDE; private: QString m_filter; KTextEditor::View* m_editor; KTextEditor::Document* m_script; QTemporaryFile* m_tmpFile; }; #endif /* _SCRIPTEDITORWIDGET_H */ diff --git a/src/searchbar.cpp b/src/searchbar.cpp index 7308c412..34b4c24e 100644 --- a/src/searchbar.cpp +++ b/src/searchbar.cpp @@ -1,502 +1,502 @@ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. --- Copyright (C) 2012 Martin Kuettler */ #include "searchbar.h" #include "worksheet.h" #include "worksheetentry.h" #include "worksheettextitem.h" #include #include #include #include SearchBar::SearchBar(QWidget* parent, Worksheet* worksheet) : QWidget(parent) { m_worksheet = worksheet; m_stdUi = new Ui::StandardSearchBar(); - m_extUi = 0; + m_extUi = nullptr; setupStdUi(); - m_qtFlags = 0; + m_qtFlags = nullptr; setStartCursor(worksheet->worksheetCursor()); setCurrentCursor(m_startCursor); m_atBeginning = false; m_atEnd = false; m_notFound = false; m_searchFlags = WorksheetEntry::SearchAll; } SearchBar::~SearchBar() { if (m_stdUi) delete m_stdUi; else delete m_extUi; if (m_currentCursor.isValid()) { worksheet()->worksheetView()->setFocus(); m_currentCursor.entry()->focusEntry(); } else if (m_startCursor.isValid()) { worksheet()->worksheetView()->setFocus(); m_startCursor.entry()->focusEntry(); } } void SearchBar::showStandard() { if (m_stdUi) return; delete m_extUi; - m_extUi = 0; + m_extUi = nullptr; foreach(QObject* child, children()) { delete child; } delete layout(); m_stdUi = new Ui::StandardSearchBar(); setupStdUi(); } void SearchBar::showExtended() { if (m_extUi) return; delete m_stdUi; - m_stdUi = 0; + m_stdUi = nullptr; foreach(QObject* child, children()) { delete child; } delete layout(); m_extUi = new Ui::ExtendedSearchBar(); setupExtUi(); } void SearchBar::next() { if (!m_currentCursor.isValid() && !m_currentCursor.entry() && !m_atEnd) return; searchForward(true); } void SearchBar::prev() { if (!m_currentCursor.isValid() && !m_currentCursor.entry() && !m_atBeginning) return; searchBackward(true); } void SearchBar::searchBackward(bool skipFirstChar) { WorksheetCursor result; WorksheetEntry* entry; worksheet()->setWorksheetCursor(WorksheetCursor()); QTextDocument::FindFlags f = m_qtFlags | QTextDocument::FindBackward; if (m_currentCursor.isValid()) { bool atBeginningOfEntry = false; if (skipFirstChar) { QTextCursor c = m_currentCursor.textCursor(); c.movePosition(QTextCursor::PreviousCharacter); atBeginningOfEntry = (c == m_currentCursor.textCursor()); setCurrentCursor(WorksheetCursor(m_currentCursor.entry(), m_currentCursor.textItem(), c)); } if (!atBeginningOfEntry) result = m_currentCursor.entry()->search(m_pattern, m_searchFlags, f, m_currentCursor); entry = m_currentCursor.entry()->previous(); } else if (m_currentCursor.entry() && m_currentCursor.entry()->previous()) { entry = m_currentCursor.entry()->previous(); } else { entry = worksheet()->lastEntry(); } setCurrentCursor(WorksheetCursor()); while (!result.isValid() && entry) { result = entry->search(m_pattern, m_searchFlags, f); entry = entry->previous(); } if (result.isValid()) { m_atBeginning = false; QTextCursor c = result.textCursor(); if (result.textCursor().hasSelection()) c.setPosition(result.textCursor().selectionStart()); setCurrentCursor(WorksheetCursor(result.entry(), result.textItem(), c)); worksheet()->makeVisible(m_currentCursor); clearStatus(); worksheet()->setWorksheetCursor(result); } else { if (m_atBeginning) { m_notFound = true; setStatus(i18n("Not found")); } else { m_atBeginning = true; setStatus(i18n("Reached beginning")); } worksheet()->setWorksheetCursor(m_startCursor); } } void SearchBar::searchForward(bool skipFirstChar) { WorksheetCursor result; WorksheetEntry* entry; worksheet()->setWorksheetCursor(WorksheetCursor()); if (m_currentCursor.isValid()) { if (skipFirstChar) { QTextCursor c = m_currentCursor.textCursor(); c.movePosition(QTextCursor::NextCharacter); qDebug() << c.position(); setCurrentCursor(WorksheetCursor(m_currentCursor.entry(), m_currentCursor.textItem(), c)); } result = m_currentCursor.entry()->search(m_pattern, m_searchFlags, m_qtFlags, m_currentCursor); entry = m_currentCursor.entry()->next(); } else if (m_currentCursor.entry()) { entry = m_currentCursor.entry(); } else { entry = worksheet()->firstEntry(); } setCurrentCursor(WorksheetCursor()); while (!result.isValid() && entry) { result = entry->search(m_pattern, m_searchFlags, m_qtFlags); entry = entry->next(); } if (result.isValid()) { m_atEnd = false; QTextCursor c = result.textCursor(); if (result.textCursor().hasSelection()) c.setPosition(result.textCursor().selectionStart()); setCurrentCursor(WorksheetCursor(result.entry(), result.textItem(), c)); worksheet()->makeVisible(m_currentCursor); clearStatus(); worksheet()->setWorksheetCursor(result); } else { if (m_atEnd) { m_notFound = true; setStatus(i18n("Not found")); } else { m_atEnd = true; setStatus(i18n("Reached end")); } worksheet()->setWorksheetCursor(m_startCursor); } } void SearchBar::on_close_clicked() { deleteLater(); } void SearchBar::on_openExtended_clicked() { showExtended(); } void SearchBar::on_openStandard_clicked() { showStandard(); } void SearchBar::on_next_clicked() { next(); } void SearchBar::on_previous_clicked() { prev(); } void SearchBar::on_replace_clicked() { if (!m_currentCursor.isValid()) return; QTextCursor cursor = m_currentCursor.textCursor(); cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, m_pattern.length()); cursor.insertText(m_replacement); next(); } void SearchBar::on_replaceAll_clicked() { int count = 0; WorksheetEntry* entry = worksheet()->firstEntry(); WorksheetCursor cursor; for (; entry; entry = entry->next()) { cursor = entry->search(m_pattern, m_searchFlags, m_qtFlags); while (cursor.isValid()) { cursor.textCursor().insertText(m_replacement); cursor = entry->search(m_pattern, m_searchFlags, m_qtFlags, cursor); ++count; } } setStatus(i18np("Replaced %1 instance", "Replaced %1 instances", count)); } void SearchBar::on_pattern_textChanged(const QString& p) { worksheet()->setWorksheetCursor(WorksheetCursor()); m_atBeginning = m_atEnd = m_notFound = false; if (!p.startsWith(m_pattern)) setCurrentCursor(m_startCursor); m_pattern = p; if (!m_pattern.isEmpty()) { searchForward(); nextButton()->setEnabled(true); previousButton()->setEnabled(true); if (m_extUi) { m_extUi->replace->setEnabled(true); m_extUi->replaceAll->setEnabled(true); } } else { worksheet()->setWorksheetCursor(m_startCursor); nextButton()->setEnabled(false); previousButton()->setEnabled(false); if (m_extUi) { m_extUi->replace->setEnabled(false); m_extUi->replaceAll->setEnabled(false); } } } void SearchBar::on_replacement_textChanged(const QString& r) { m_replacement = r; } void SearchBar::on_removeFlag_clicked() { QMenu* menu = new QMenu(this); fillLocationsMenu(menu, m_searchFlags); connect(menu, SIGNAL("aboutToHide()"), menu, SLOT("deleteLater()")); menu->exec(mapToGlobal(m_extUi->removeFlag->geometry().topLeft())); } void SearchBar::on_addFlag_clicked() { QMenu* menu = new QMenu(this); fillLocationsMenu(menu, WorksheetEntry::SearchAll ^ m_searchFlags); connect(menu, SIGNAL("aboutToHide()"), menu, SLOT("deleteLater()")); menu->exec(mapToGlobal(m_extUi->addFlag->geometry().topLeft())); } void SearchBar::invalidateStartCursor() { if (!m_startCursor.isValid()) return; WorksheetEntry* entry = m_startCursor.entry()->next(); if (!entry && worksheet()->firstEntry() != m_startCursor.entry()) entry = worksheet()->firstEntry(); - setStartCursor(WorksheetCursor(entry, 0, QTextCursor())); + setStartCursor(WorksheetCursor(entry, nullptr, QTextCursor())); } void SearchBar::invalidateCurrentCursor() { if (!m_currentCursor.isValid()) return; WorksheetEntry* entry = m_currentCursor.entry()->next(); if (!entry) entry = worksheet()->firstEntry(); - setCurrentCursor(WorksheetCursor(entry, 0, QTextCursor())); + setCurrentCursor(WorksheetCursor(entry, nullptr, QTextCursor())); } void SearchBar::toggleFlag() { if (!sender()) return; int flag = sender()->property("searchFlag").toInt(); m_searchFlags ^= flag; updateSearchLocations(); } void SearchBar::on_matchCase_toggled(bool b) { m_qtFlags &= ~QTextDocument::FindCaseSensitively; if (b) m_qtFlags |= QTextDocument::FindCaseSensitively; searchForward(); } void SearchBar::updateSearchLocations() { static QList names; if (names.empty()) names << i18n("Commands") << i18n("Results") << i18n("Errors") << i18n("Text") << i18n("LaTeX Code"); QString text = QLatin1String(""); int flag = 1; for (int i = 0; flag < WorksheetEntry::SearchAll; flag = (1<<(++i))) { if (m_searchFlags & flag) { if (!text.isEmpty()) text += QLatin1String(", "); text += names.at(i); } } m_extUi->searchFlagsList->setText(text); if (m_searchFlags == 0) { m_extUi->removeFlag->setEnabled(false); m_extUi->addFlag->setEnabled(true); } else if (m_searchFlags == WorksheetEntry::SearchAll) { m_extUi->removeFlag->setEnabled(true); m_extUi->addFlag->setEnabled(false); } else { m_extUi->addFlag->setEnabled(true); m_extUi->removeFlag->setEnabled(true); } } void SearchBar::fillLocationsMenu(QMenu* menu, int flags) { static QList names; if (names.empty()) names << i18n("Commands") << i18n("Results") << i18n("Errors") << i18n("Text") << i18n("LaTeX Code"); int flag = 1; for (int i = 0; flag < WorksheetEntry::SearchAll; flag = (1<<(++i))) { if (flags & flag) { QAction* a = menu->addAction(names.at(i), this, SLOT(toggleFlag())); a->setProperty("searchFlag", flag); } } } void SearchBar::setStartCursor(WorksheetCursor cursor) { if (m_startCursor.entry()) disconnect(m_startCursor.entry(), SIGNAL(aboutToBeDeleted()), this, SLOT(invalidateStartCursor())); if (cursor.entry()) connect(cursor.entry(), SIGNAL(aboutToBeDeleted()), this, SLOT(invalidateStartCursor()), Qt::DirectConnection); m_startCursor = cursor; } void SearchBar::setCurrentCursor(WorksheetCursor cursor) { if (m_currentCursor.entry()) disconnect(m_currentCursor.entry(), SIGNAL(aboutToBeDeleted()), this, SLOT(invalidateCurrentCursor())); if (cursor.entry()) connect(cursor.entry(), SIGNAL(aboutToBeDeleted()), this, SLOT(invalidateCurrentCursor()), Qt::DirectConnection); m_currentCursor = cursor; } void SearchBar::setStatus(QString message) { KSqueezedTextLabel* status; if (m_stdUi) status = m_stdUi->status; else status = m_extUi->status; status->setText(message); } void SearchBar::clearStatus() { setStatus(QLatin1String("")); } void SearchBar::setupStdUi() { if (!m_stdUi) return; m_stdUi->setupUi(this); m_stdUi->close->setIcon(QIcon::fromTheme(QLatin1String("dialog-close"))); m_stdUi->openExtended->setIcon(QIcon::fromTheme(QLatin1String("arrow-up-double"))); m_stdUi->pattern->setText(m_pattern); m_stdUi->matchCase->setChecked(m_qtFlags & QTextDocument::FindCaseSensitively); m_stdUi->next->setIcon(QIcon::fromTheme(QLatin1String("go-down-search"))); m_stdUi->previous->setIcon(QIcon::fromTheme(QLatin1String("go-up-search"))); if (m_pattern.isEmpty()) { m_stdUi->next->setEnabled(false); m_stdUi->previous->setEnabled(false); } m_stdUi->close->setShortcut(Qt::Key_Escape); setFocusProxy(m_stdUi->pattern); } void SearchBar::setupExtUi() { if (!m_extUi) return; m_extUi->setupUi(this); m_extUi->close->setIcon(QIcon::fromTheme(QLatin1String("dialog-close"))); m_extUi->openStandard->setIcon(QIcon::fromTheme(QLatin1String("arrow-down-double"))); m_extUi->pattern->setText(m_pattern); m_extUi->replacement->setText(m_replacement); m_extUi->matchCase->setChecked(m_qtFlags & QTextDocument::FindCaseSensitively); m_extUi->next->setIcon(QIcon::fromTheme(QLatin1String("go-down-search"))); m_extUi->previous->setIcon(QIcon::fromTheme(QLatin1String("go-up-search"))); if (m_pattern.isEmpty()) { m_extUi->next->setEnabled(false); m_extUi->previous->setEnabled(false); m_extUi->replace->setEnabled(false); m_extUi->replaceAll->setEnabled(false); } m_extUi->addFlag->setIcon(QIcon::fromTheme(QLatin1String("list-add"))); m_extUi->removeFlag->setIcon(QIcon::fromTheme(QLatin1String("list-remove"))); m_extUi->close->setShortcut(Qt::Key_Escape); setFocusProxy(m_extUi->pattern); updateSearchLocations(); } QPushButton* SearchBar::previousButton() { if (m_stdUi) return m_stdUi->previous; else return m_extUi->previous; } QPushButton* SearchBar::nextButton() { if (m_stdUi) return m_stdUi->next; else return m_extUi->next; } Worksheet* SearchBar::worksheet() { return m_worksheet; } diff --git a/src/textresultitem.cpp b/src/textresultitem.cpp index 81bcf97b..6665fd82 100644 --- a/src/textresultitem.cpp +++ b/src/textresultitem.cpp @@ -1,182 +1,182 @@ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. --- Copyright (C) 2012 Martin Kuettler */ #include "commandentry.h" #include "textresultitem.h" #include "lib/result.h" #include "lib/textresult.h" #include "lib/latexresult.h" #include #include #include #include #include #include TextResultItem::TextResultItem(QGraphicsObject* parent) : WorksheetTextItem(parent), ResultItem() { setTextInteractionFlags(Qt::TextSelectableByMouse); connect(this, SIGNAL(removeResult()), parentEntry(), SLOT(removeResult())); } TextResultItem::~TextResultItem() { } double TextResultItem::setGeometry(double x, double y, double w) { return WorksheetTextItem::setGeometry(x, y, w); } void TextResultItem::populateMenu(QMenu* menu, const QPointF& pos) { QAction * copy = KStandardAction::copy(this, SLOT(copy()), menu); if (!textCursor().hasSelection()) copy->setEnabled(false); menu->addAction(copy); addCommonActions(this, menu); Cantor::Result* res = result(); if (res->type() == Cantor::LatexResult::Type) { - QAction* showCodeAction = 0; + QAction* showCodeAction = nullptr; Cantor::LatexResult* lres = dynamic_cast(res); if (lres->isCodeShown()) showCodeAction = menu->addAction(i18n("Show Rendered")); else showCodeAction = menu->addAction(i18n("Show Code")); connect(showCodeAction, &QAction::triggered, this, &TextResultItem::toggleLatexCode); } menu->addSeparator(); qDebug() << "populate Menu"; emit menuCreated(menu, mapToParent(pos)); } ResultItem* TextResultItem::updateFromResult(Cantor::Result* result) { switch(result->type()) { case Cantor::TextResult::Type: { QTextCursor cursor = textCursor(); cursor.movePosition(QTextCursor::Start); cursor.movePosition(QTextCursor::End, QTextCursor::KeepAnchor); QString html = result->toHtml(); if (html.isEmpty()) cursor.removeSelectedText(); else cursor.insertHtml(html); return this; } case Cantor::LatexResult::Type: setLatex(dynamic_cast(result)); return this; default: deleteLater(); return create(parentEntry(), result); } } void TextResultItem::setLatex(Cantor::LatexResult* result) { QTextCursor cursor = textCursor(); cursor.movePosition(QTextCursor::Start); cursor.movePosition(QTextCursor::End, QTextCursor::KeepAnchor); QString latex = result->toLatex().trimmed(); if (latex.startsWith(QLatin1String("\\begin{eqnarray*}")) && latex.endsWith(QLatin1String("\\end{eqnarray*}"))) { latex = latex.mid(17); latex = latex.left(latex.size() - 15); } if (result->isCodeShown()) { if (latex.isEmpty()) cursor.removeSelectedText(); else cursor.insertText(latex); } else { QTextImageFormat format; format = epsRenderer()->render(cursor.document(), result->data().toUrl()); format.setProperty(EpsRenderer::CantorFormula, EpsRenderer::LatexFormula); format.setProperty(EpsRenderer::Code, latex); format.setProperty(EpsRenderer::Delimiter, QLatin1String("$$")); if(format.isValid()) cursor.insertText(QString(QChar::ObjectReplacementCharacter), format); else cursor.insertText(i18n("Cannot render Eps file. You may need additional packages")); } } double TextResultItem::width() const { return WorksheetTextItem::width(); } double TextResultItem::height() const { return WorksheetTextItem::height(); } void TextResultItem::toggleLatexCode() { Cantor::LatexResult* lr = dynamic_cast(result()); if(lr->isCodeShown()) lr->showRendered(); else lr->showCode(); parentEntry()->updateEntry(); } void TextResultItem::saveResult() { Cantor::Result* res = result(); const QString& filename = QFileDialog::getSaveFileName(worksheet()->worksheetView(), i18n("Save result"), QString(), res->mimeType()); qDebug() << "saving result to " << filename; res->save(filename); } void TextResultItem::deleteLater() { WorksheetTextItem::deleteLater(); } EpsRenderer* TextResultItem::epsRenderer() { return qobject_cast(scene())->epsRenderer(); } CommandEntry* TextResultItem::parentEntry() { return qobject_cast(parentObject()); } Cantor::Result* TextResultItem::result() { return parentEntry()->expression()->result(); } diff --git a/src/worksheet.cpp b/src/worksheet.cpp index ccb1d453..e6452416 100644 --- a/src/worksheet.cpp +++ b/src/worksheet.cpp @@ -1,1685 +1,1685 @@ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. --- Copyright (C) 2009 Alexander Rieder Copyright (C) 2012 Martin Kuettler */ #include #include #include #include #include #include #include #include #include #include #include #include "worksheet.h" #include "settings.h" #include "commandentry.h" #include "textentry.h" #include "latexentry.h" #include "imageentry.h" #include "pagebreakentry.h" #include "placeholderentry.h" #include "lib/backend.h" #include "lib/extension.h" #include "lib/helpresult.h" #include "lib/session.h" #include "lib/defaulthighlighter.h" const double Worksheet::LeftMargin = 4; const double Worksheet::RightMargin = 4; const double Worksheet::TopMargin = 4; Worksheet::Worksheet(Cantor::Backend* backend, QWidget* parent) : QGraphicsScene(parent) { m_session = backend->createSession(); - m_highlighter = 0; + m_highlighter = nullptr; - m_firstEntry = 0; - m_lastEntry = 0; - m_lastFocusedTextItem = 0; - m_dragEntry = 0; - m_placeholderEntry = 0; + m_firstEntry = nullptr; + m_lastEntry = nullptr; + m_lastFocusedTextItem = nullptr; + m_dragEntry = nullptr; + m_placeholderEntry = nullptr; m_viewWidth = 0; m_protrusion = 0; - m_dragScrollTimer = 0; + m_dragScrollTimer = nullptr; m_isPrinting = false; m_loginDone = false; enableHighlighting(Settings::self()->highlightDefault()); enableCompletion(Settings::self()->completionDefault()); enableExpressionNumbering(Settings::self()->expressionNumberingDefault()); enableAnimations(Settings::self()->animationDefault()); #ifdef WITH_EPS session()->setTypesettingEnabled(Settings::self()->typesetDefault()); #else session()->setTypesettingEnabled(false); #endif } Worksheet::~Worksheet() { // This is necessary, because a SeachBar might access firstEntry() // while the scene is deleted. Maybe there is a better solution to // this problem, but I can't seem to find it. - m_firstEntry = 0; + m_firstEntry = nullptr; if (m_loginDone) m_session->logout(); } void Worksheet::loginToSession() { m_session->login(); m_loginDone = true; } void Worksheet::print(QPrinter* printer) { m_epsRenderer.useHighResolution(true); m_isPrinting = true; QRect pageRect = printer->pageRect(); qreal scale = 1; // todo: find good scale for page size // todo: use epsRenderer()->scale() for printing ? const qreal width = pageRect.width()/scale; const qreal height = pageRect.height()/scale; setViewSize(width, height, scale, true); QPainter painter(printer); painter.scale(scale, scale); painter.setRenderHint(QPainter::Antialiasing); WorksheetEntry* entry = firstEntry(); qreal y = 0; while (entry) { qreal h = 0; do { if (entry->type() == PageBreakEntry::Type) { entry = entry->next(); break; } h += entry->size().height(); entry = entry->next(); } while (entry && h + entry->size().height() <= height); render(&painter, QRectF(0, 0, width, height), QRectF(0, y, width, h)); y += h; if (entry) printer->newPage(); } //render(&painter); painter.end(); m_isPrinting = false; m_epsRenderer.useHighResolution(false); m_epsRenderer.setScale(-1); // force update in next call to setViewSize, worksheetView()->updateSceneSize(); // ... which happens in here } bool Worksheet::isPrinting() { return m_isPrinting; } void Worksheet::setViewSize(qreal w, qreal h, qreal s, bool forceUpdate) { Q_UNUSED(h); m_viewWidth = w; if (s != m_epsRenderer.scale() || forceUpdate) { m_epsRenderer.setScale(s); for (WorksheetEntry *entry = firstEntry(); entry; entry = entry->next()) entry->updateEntry(); } updateLayout(); } void Worksheet::updateLayout() { bool cursorRectVisible = false; bool atEnd = worksheetView()->isAtEnd(); if (currentTextItem()) { QRectF cursorRect = currentTextItem()->sceneCursorRect(); cursorRectVisible = worksheetView()->isVisible(cursorRect); } const qreal w = m_viewWidth - LeftMargin - RightMargin; qreal y = TopMargin; const qreal x = LeftMargin; for (WorksheetEntry *entry = firstEntry(); entry; entry = entry->next()) y += entry->setGeometry(x, y, w); setSceneRect(QRectF(0, 0, m_viewWidth + m_protrusion, y)); if (cursorRectVisible) makeVisible(worksheetCursor()); else if (atEnd) worksheetView()->scrollToEnd(); } void Worksheet::updateEntrySize(WorksheetEntry* entry) { bool cursorRectVisible = false; bool atEnd = worksheetView()->isAtEnd(); if (currentTextItem()) { QRectF cursorRect = currentTextItem()->sceneCursorRect(); cursorRectVisible = worksheetView()->isVisible(cursorRect); } qreal y = entry->y() + entry->size().height(); for (entry = entry->next(); entry; entry = entry->next()) { entry->setY(y); y += entry->size().height(); } setSceneRect(QRectF(0, 0, m_viewWidth + m_protrusion, y)); if (cursorRectVisible) makeVisible(worksheetCursor()); else if (atEnd) worksheetView()->scrollToEnd(); } void Worksheet::addProtrusion(qreal width) { if (m_itemProtrusions.contains(width)) ++m_itemProtrusions[width]; else m_itemProtrusions.insert(width, 1); if (width > m_protrusion) { m_protrusion = width; qreal y = lastEntry()->size().height() + lastEntry()->y(); setSceneRect(QRectF(0, 0, m_viewWidth + m_protrusion, y)); } } void Worksheet::updateProtrusion(qreal oldWidth, qreal newWidth) { removeProtrusion(oldWidth); addProtrusion(newWidth); } void Worksheet::removeProtrusion(qreal width) { if (--m_itemProtrusions[width] == 0) { m_itemProtrusions.remove(width); if (width == m_protrusion) { qreal max = -1; foreach (qreal p, m_itemProtrusions.keys()) { if (p > max) max = p; } m_protrusion = max; qreal y = lastEntry()->size().height() + lastEntry()->y(); setSceneRect(QRectF(0, 0, m_viewWidth + m_protrusion, y)); } } } bool Worksheet::isEmpty() { return !m_firstEntry; } void Worksheet::makeVisible(WorksheetEntry* entry) { QRectF r = entry->boundingRect(); r = entry->mapRectToScene(r); r.adjust(0, -10, 0, 10); worksheetView()->makeVisible(r); } void Worksheet::makeVisible(const WorksheetCursor& cursor) { if (cursor.textCursor().isNull()) { if (cursor.entry()) makeVisible(cursor.entry()); return; } QRectF r = cursor.textItem()->sceneCursorRect(cursor.textCursor()); QRectF er = cursor.entry()->boundingRect(); er = cursor.entry()->mapRectToScene(er); er.adjust(0, -10, 0, 10); r.adjust(0, qMax(qreal(-100.0), er.top() - r.top()), 0, qMin(qreal(100.0), er.bottom() - r.bottom())); worksheetView()->makeVisible(r); } WorksheetView* Worksheet::worksheetView() { return qobject_cast(views()[0]); } void Worksheet::setModified() { emit modified(); } WorksheetCursor Worksheet::worksheetCursor() { WorksheetEntry* entry = currentEntry(); WorksheetTextItem* item = currentTextItem(); if (!entry || !item) return WorksheetCursor(); return WorksheetCursor(entry, item, item->textCursor()); } void Worksheet::setWorksheetCursor(const WorksheetCursor& cursor) { if (!cursor.isValid()) return; if (m_lastFocusedTextItem) m_lastFocusedTextItem->clearSelection(); m_lastFocusedTextItem = cursor.textItem(); cursor.textItem()->setTextCursor(cursor.textCursor()); } WorksheetEntry* Worksheet::currentEntry() { QGraphicsItem* item = focusItem(); if (!item /*&& !hasFocus()*/) item = m_lastFocusedTextItem; /*else m_focusItem = item;*/ while (item && (item->type() < QGraphicsItem::UserType || item->type() >= QGraphicsItem::UserType + 100)) item = item->parentItem(); if (item) { WorksheetEntry* entry = qobject_cast(item->toGraphicsObject()); if (entry && entry->aboutToBeRemoved()) { if (entry->isAncestorOf(m_lastFocusedTextItem)) - m_lastFocusedTextItem = 0; - return 0; + m_lastFocusedTextItem = nullptr; + return nullptr; } return entry; } - return 0; + return nullptr; } WorksheetEntry* Worksheet::firstEntry() { return m_firstEntry; } WorksheetEntry* Worksheet::lastEntry() { return m_lastEntry; } void Worksheet::setFirstEntry(WorksheetEntry* entry) { if (m_firstEntry) disconnect(m_firstEntry, SIGNAL(aboutToBeDeleted()), this, SLOT(invalidateFirstEntry())); m_firstEntry = entry; if (m_firstEntry) connect(m_firstEntry, SIGNAL(aboutToBeDeleted()), this, SLOT(invalidateFirstEntry()), Qt::DirectConnection); } void Worksheet::setLastEntry(WorksheetEntry* entry) { if (m_lastEntry) disconnect(m_lastEntry, SIGNAL(aboutToBeDeleted()), this, SLOT(invalidateLastEntry())); m_lastEntry = entry; if (m_lastEntry) connect(m_lastEntry, SIGNAL(aboutToBeDeleted()), this, SLOT(invalidateLastEntry()), Qt::DirectConnection); } void Worksheet::invalidateFirstEntry() { if (m_firstEntry) setFirstEntry(m_firstEntry->next()); } void Worksheet::invalidateLastEntry() { if (m_lastEntry) setLastEntry(m_lastEntry->previous()); } WorksheetEntry* Worksheet::entryAt(qreal x, qreal y) { QGraphicsItem* item = itemAt(x, y, QTransform()); while (item && (item->type() <= QGraphicsItem::UserType || item->type() >= QGraphicsItem::UserType + 100)) item = item->parentItem(); if (item) return qobject_cast(item->toGraphicsObject()); - return 0; + return nullptr; } WorksheetEntry* Worksheet::entryAt(QPointF p) { return entryAt(p.x(), p.y()); } void Worksheet::focusEntry(WorksheetEntry *entry) { if (!entry) return; entry->focusEntry(); //bool rt = entry->acceptRichText(); //setActionsEnabled(rt); //setAcceptRichText(rt); //ensureCursorVisible(); } void Worksheet::startDrag(WorksheetEntry* entry, QDrag* drag) { m_dragEntry = entry; WorksheetEntry* prev = entry->previous(); WorksheetEntry* next = entry->next(); m_placeholderEntry = new PlaceHolderEntry(this, entry->size()); m_placeholderEntry->setPrevious(prev); m_placeholderEntry->setNext(next); if (prev) prev->setNext(m_placeholderEntry); else setFirstEntry(m_placeholderEntry); if (next) next->setPrevious(m_placeholderEntry); else setLastEntry(m_placeholderEntry); m_dragEntry->hide(); Qt::DropAction action = drag->exec(); qDebug() << action; if (action == Qt::MoveAction && m_placeholderEntry) { qDebug() << "insert in new position"; prev = m_placeholderEntry->previous(); next = m_placeholderEntry->next(); } m_dragEntry->setPrevious(prev); m_dragEntry->setNext(next); if (prev) prev->setNext(m_dragEntry); else setFirstEntry(m_dragEntry); if (next) next->setPrevious(m_dragEntry); else setLastEntry(m_dragEntry); m_dragEntry->show(); m_dragEntry->focusEntry(); const QPointF scenePos = worksheetView()->sceneCursorPos(); if (entryAt(scenePos) != m_dragEntry) m_dragEntry->hideActionBar(); updateLayout(); if (m_placeholderEntry) { - m_placeholderEntry->setPrevious(0); - m_placeholderEntry->setNext(0); + m_placeholderEntry->setPrevious(nullptr); + m_placeholderEntry->setNext(nullptr); m_placeholderEntry->hide(); m_placeholderEntry->deleteLater(); - m_placeholderEntry = 0; + m_placeholderEntry = nullptr; } - m_dragEntry = 0; + m_dragEntry = nullptr; } void Worksheet::evaluate() { qDebug()<<"evaluate worksheet"; if (!m_loginDone) loginToSession(); firstEntry()->evaluate(WorksheetEntry::EvaluateNext); emit modified(); } void Worksheet::evaluateCurrentEntry() { if (!m_loginDone) loginToSession(); WorksheetEntry* entry = currentEntry(); if(!entry) return; entry->evaluateCurrentItem(); } bool Worksheet::completionEnabled() { return m_completionEnabled; } void Worksheet::showCompletion() { WorksheetEntry* current = currentEntry(); current->showCompletion(); } WorksheetEntry* Worksheet::appendEntry(const int type) { WorksheetEntry* entry = WorksheetEntry::create(type, this); if (entry) { qDebug() << "Entry Appended"; entry->setPrevious(lastEntry()); if (lastEntry()) lastEntry()->setNext(entry); if (!firstEntry()) setFirstEntry(entry); setLastEntry(entry); updateLayout(); makeVisible(entry); focusEntry(entry); } return entry; } WorksheetEntry* Worksheet::appendCommandEntry() { return appendEntry(CommandEntry::Type); } WorksheetEntry* Worksheet::appendTextEntry() { return appendEntry(TextEntry::Type); } WorksheetEntry* Worksheet::appendPageBreakEntry() { return appendEntry(PageBreakEntry::Type); } WorksheetEntry* Worksheet::appendImageEntry() { return appendEntry(ImageEntry::Type); } WorksheetEntry* Worksheet::appendLatexEntry() { return appendEntry(LatexEntry::Type); } void Worksheet::appendCommandEntry(const QString& text) { WorksheetEntry* entry = lastEntry(); if(!entry->isEmpty()) { entry = appendCommandEntry(); } if (entry) { focusEntry(entry); entry->setContent(text); evaluateCurrentEntry(); } } WorksheetEntry* Worksheet::insertEntry(const int type, WorksheetEntry* current) { if (!current) current = currentEntry(); if (!current) return appendEntry(type); WorksheetEntry *next = current->next(); - WorksheetEntry *entry = 0; + WorksheetEntry *entry = nullptr; if (!next || next->type() != type || !next->isEmpty()) { entry = WorksheetEntry::create(type, this); entry->setPrevious(current); entry->setNext(next); current->setNext(entry); if (next) next->setPrevious(entry); else setLastEntry(entry); updateLayout(); } else { entry = next; } focusEntry(entry); makeVisible(entry); return entry; } WorksheetEntry* Worksheet::insertTextEntry(WorksheetEntry* current) { return insertEntry(TextEntry::Type, current); } WorksheetEntry* Worksheet::insertCommandEntry(WorksheetEntry* current) { return insertEntry(CommandEntry::Type, current); } WorksheetEntry* Worksheet::insertImageEntry(WorksheetEntry* current) { return insertEntry(ImageEntry::Type, current); } WorksheetEntry* Worksheet::insertPageBreakEntry(WorksheetEntry* current) { return insertEntry(PageBreakEntry::Type, current); } WorksheetEntry* Worksheet::insertLatexEntry(WorksheetEntry* current) { return insertEntry(LatexEntry::Type, current); } void Worksheet::insertCommandEntry(const QString& text) { WorksheetEntry* entry = insertCommandEntry(); if(entry&&!text.isNull()) { entry->setContent(text); evaluateCurrentEntry(); } } WorksheetEntry* Worksheet::insertEntryBefore(int type, WorksheetEntry* current) { if (!current) current = currentEntry(); if (!current) - return 0; + return nullptr; WorksheetEntry *prev = current->previous(); - WorksheetEntry *entry = 0; + WorksheetEntry *entry = nullptr; if(!prev || prev->type() != type || !prev->isEmpty()) { entry = WorksheetEntry::create(type, this); entry->setNext(current); entry->setPrevious(prev); current->setPrevious(entry); if (prev) prev->setNext(entry); else setFirstEntry(entry); updateLayout(); } focusEntry(entry); return entry; } WorksheetEntry* Worksheet::insertTextEntryBefore(WorksheetEntry* current) { return insertEntryBefore(TextEntry::Type, current); } WorksheetEntry* Worksheet::insertCommandEntryBefore(WorksheetEntry* current) { return insertEntryBefore(CommandEntry::Type, current); } WorksheetEntry* Worksheet::insertPageBreakEntryBefore(WorksheetEntry* current) { return insertEntryBefore(PageBreakEntry::Type, current); } WorksheetEntry* Worksheet::insertImageEntryBefore(WorksheetEntry* current) { return insertEntryBefore(ImageEntry::Type, current); } WorksheetEntry* Worksheet::insertLatexEntryBefore(WorksheetEntry* current) { return insertEntryBefore(LatexEntry::Type, current); } void Worksheet::interrupt() { m_session->interrupt(); emit updatePrompt(); } void Worksheet::interruptCurrentEntryEvaluation() { currentEntry()->interruptEvaluation(); } void Worksheet::highlightItem(WorksheetTextItem* item) { if (!m_highlighter) return; QTextDocument *oldDocument = m_highlighter->document(); QList > formats; if (oldDocument) { for (QTextBlock b = oldDocument->firstBlock(); b.isValid(); b = b.next()) { formats.append(b.layout()->additionalFormats()); } } // Not every highlighter is a Cantor::DefaultHighligther (e.g. the // highlighter for KAlgebra) Cantor::DefaultHighlighter* hl = qobject_cast(m_highlighter); if (hl) { hl->setTextItem(item); } else { m_highlighter->setDocument(item->document()); } if (oldDocument) { QTextCursor cursor(oldDocument); cursor.beginEditBlock(); for (QTextBlock b = oldDocument->firstBlock(); b.isValid(); b = b.next()) { b.layout()->setAdditionalFormats(formats.first()); formats.pop_front(); } cursor.endEditBlock(); } } void Worksheet::rehighlight() { if(m_highlighter) { // highlight every entry WorksheetEntry* entry; for (entry = firstEntry(); entry; entry = entry->next()) { WorksheetTextItem* item = entry->highlightItem(); if (!item) continue; highlightItem(item); m_highlighter->rehighlight(); } entry = currentEntry(); - WorksheetTextItem* textitem = entry ? entry->highlightItem() : 0; + WorksheetTextItem* textitem = entry ? entry->highlightItem() : nullptr; if (textitem && textitem->hasFocus()) highlightItem(textitem); } else { // remove highlighting from entries WorksheetEntry* entry; for (entry = firstEntry(); entry; entry = entry->next()) { WorksheetTextItem* item = entry->highlightItem(); if (!item) continue; for (QTextBlock b = item->document()->firstBlock(); b.isValid(); b = b.next()) { b.layout()->clearAdditionalFormats(); } } update(); } } void Worksheet::enableHighlighting(bool highlight) { if(highlight) { if(m_highlighter) m_highlighter->deleteLater(); m_highlighter=session()->syntaxHighlighter(this); if(!m_highlighter) m_highlighter=new Cantor::DefaultHighlighter(this); connect(m_highlighter, SIGNAL(rulesChanged()), this, SLOT(rehighlight())); }else { if(m_highlighter) m_highlighter->deleteLater(); - m_highlighter=0; + m_highlighter=nullptr; } rehighlight(); } void Worksheet::enableCompletion(bool enable) { m_completionEnabled=enable; } Cantor::Session* Worksheet::session() { return m_session; } bool Worksheet::isRunning() { return m_session->status()==Cantor::Session::Running; } bool Worksheet::showExpressionIds() { return m_showExpressionIds; } bool Worksheet::animationsEnabled() { return m_animationsEnabled; } void Worksheet::enableAnimations(bool enable) { m_animationsEnabled = enable; } void Worksheet::enableExpressionNumbering(bool enable) { m_showExpressionIds=enable; emit updatePrompt(); } QDomDocument Worksheet::toXML(KZip* archive) { QDomDocument doc( QLatin1String("CantorWorksheet") ); QDomElement root=doc.createElement( QLatin1String("Worksheet") ); root.setAttribute(QLatin1String("backend"), m_session->backend()->name()); doc.appendChild(root); for( WorksheetEntry* entry = firstEntry(); entry; entry = entry->next()) { QDomElement el = entry->toXml(doc, archive); root.appendChild( el ); } return doc; } void Worksheet::save( const QString& filename ) { QFile file(filename); if ( !file.open(QIODevice::WriteOnly) ) { KMessageBox::error( worksheetView(), i18n( "Cannot write file %1." , filename ), i18n( "Error - Cantor" )); return; } save(&file); } QByteArray Worksheet::saveToByteArray() { QBuffer buffer; save(&buffer); return buffer.buffer(); } void Worksheet::save( QIODevice* device) { qDebug()<<"saving to filename"; KZip zipFile( device ); if ( !zipFile.open(QIODevice::WriteOnly) ) { KMessageBox::error( worksheetView(), i18n( "Cannot write file." ), i18n( "Error - Cantor" )); return; } QByteArray content = toXML(&zipFile).toByteArray(); qDebug()<<"content: "<backend(); if (backend->extensions().contains(QLatin1String("ScriptExtension"))) { Cantor::ScriptExtension* e=dynamic_cast(backend->extension(QLatin1String(("ScriptExtension")))); cmdSep=e->commandSeparator(); commentStartingSeq = e->commentStartingSequence(); commentEndingSeq = e->commentEndingSequence(); } QTextStream stream(&file); for(WorksheetEntry * entry = firstEntry(); entry; entry = entry->next()) { const QString& str=entry->toPlain(cmdSep, commentStartingSeq, commentEndingSeq); if(!str.isEmpty()) stream << str + QLatin1Char('\n'); } file.close(); } void Worksheet::saveLatex(const QString& filename) { qDebug()<<"exporting to Latex: " <entry(QLatin1String("content.xml")); if (!contentEntry->isFile()) { qDebug()<<"error"; } const KArchiveFile* content=static_cast(contentEntry); QByteArray data=content->data(); qDebug()<<"read: "<isEnabled()) { KMessageBox::information(worksheetView(), i18n("There are some problems with the %1 backend,\n"\ "please check your configuration or install the needed packages.\n" "You will only be able to view this worksheet.", backendName), i18n("Cantor")); } //cleanup the worksheet and all it contains delete m_session; - m_session=0; + m_session=nullptr; //file can only be loaded in a worksheet that was not eidted/modified yet (s.a. CantorShell::load()) //in this case on the default "first entry" is available -> delete it. if (m_firstEntry) { delete m_firstEntry; - m_firstEntry = 0; + m_firstEntry = nullptr; } //delete all items from the scene clear(); m_session=b->createSession(); qDebug()<<"loading entries"; QDomElement expressionChild = root.firstChildElement(); WorksheetEntry* entry; while (!expressionChild.isNull()) { QString tag = expressionChild.tagName(); if (tag == QLatin1String("Expression")) { entry = appendCommandEntry(); entry->setContent(expressionChild, file); } else if (tag == QLatin1String("Text")) { entry = appendTextEntry(); entry->setContent(expressionChild, file); } else if (tag == QLatin1String("Latex")) { entry = appendLatexEntry(); entry->setContent(expressionChild, file); } else if (tag == QLatin1String("PageBreak")) { entry = appendPageBreakEntry(); entry->setContent(expressionChild, file); } else if (tag == QLatin1String("Image")) { entry = appendImageEntry(); entry->setContent(expressionChild, file); } expressionChild = expressionChild.nextSiblingElement(); } //login to the session, but let Qt process all the events in its pipeline //first. QTimer::singleShot(0, this, SLOT(loginToSession())); //Set the Highlighting, depending on the current state //If the session isn't logged in, use the default - enableHighlighting( m_highlighter!=0 || Settings::highlightDefault() ); + enableHighlighting( m_highlighter!=nullptr || Settings::highlightDefault() ); emit sessionChanged(); } void Worksheet::gotResult(Cantor::Expression* expr) { - if(expr==0) + if(expr==nullptr) expr=qobject_cast(sender()); - if(expr==0) + if(expr==nullptr) return; //We're only interested in help results, others are handled by the WorksheetEntry if(expr->result()&&expr->result()->type()==Cantor::HelpResult::Type) { QString help=expr->result()->toHtml(); //Do some basic LaTeX replacing help.replace(QRegExp(QLatin1String("\\\\code\\{([^\\}]*)\\}")), QLatin1String("\\1")); help.replace(QRegExp(QLatin1String("\\$([^\\$])\\$")), QLatin1String("\\1")); emit showHelp(help); } } void Worksheet::removeCurrentEntry() { qDebug()<<"removing current entry"; WorksheetEntry* entry=currentEntry(); if(!entry) return; // In case we just removed this if (entry->isAncestorOf(m_lastFocusedTextItem)) - m_lastFocusedTextItem = 0; + m_lastFocusedTextItem = nullptr; entry->startRemoving(); } EpsRenderer* Worksheet::epsRenderer() { return &m_epsRenderer; } QMenu* Worksheet::createContextMenu() { QMenu *menu = new QMenu(worksheetView()); connect(menu, SIGNAL(aboutToHide()), menu, SLOT(deleteLater())); return menu; } void Worksheet::populateMenu(QMenu *menu, const QPointF& pos) { WorksheetEntry* entry = entryAt(pos); if (entry && !entry->isAncestorOf(m_lastFocusedTextItem)) { WorksheetTextItem* item = qgraphicsitem_cast(itemAt(pos, QTransform())); if (item && item->isEditable()) m_lastFocusedTextItem = item; } if (!isRunning()) menu->addAction(QIcon::fromTheme(QLatin1String("system-run")), i18n("Evaluate Worksheet"), this, SLOT(evaluate()), 0); else menu->addAction(QIcon::fromTheme(QLatin1String("process-stop")), i18n("Interrupt"), this, SLOT(interrupt()), 0); menu->addSeparator(); if (entry) { QMenu* insert = new QMenu(menu); QMenu* insertBefore = new QMenu(menu); insert->addAction(i18n("Command Entry"), entry, SLOT(insertCommandEntry())); insert->addAction(i18n("Text Entry"), entry, SLOT(insertTextEntry())); insert->addAction(i18n("LaTeX Entry"), entry, SLOT(insertLatexEntry())); insert->addAction(i18n("Image"), entry, SLOT(insertImageEntry())); insert->addAction(i18n("Page Break"), entry, SLOT(insertPageBreakEntry())); insertBefore->addAction(i18n("Command Entry"), entry, SLOT(insertCommandEntryBefore())); insertBefore->addAction(i18n("Text Entry"), entry, SLOT(insertTextEntryBefore())); insertBefore->addAction(i18n("LaTeX Entry"), entry, SLOT(insertLatexEntryBefore())); insertBefore->addAction(i18n("Image"), entry, SLOT(insertImageEntryBefore())); insertBefore->addAction(i18n("Page Break"), entry, SLOT(insertPageBreakEntryBefore())); insert->setTitle(i18n("Insert")); insertBefore->setTitle(i18n("Insert Before")); menu->addMenu(insert); menu->addMenu(insertBefore); } else { menu->addAction(i18n("Insert Command Entry"), this, SLOT(appendCommandEntry())); menu->addAction(i18n("Insert Text Entry"), this, SLOT(appendTextEntry())); menu->addAction(i18n("Insert LaTeX Entry"), this, SLOT(appendLatexEntry())); menu->addAction(i18n("Insert Image"), this, SLOT(appendImageEntry())); menu->addAction(i18n("Insert Page Break"), this, SLOT(appendPageBreakEntry())); } } void Worksheet::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) { // forward the event to the items QGraphicsScene::contextMenuEvent(event); if (!event->isAccepted()) { event->accept(); QMenu *menu = createContextMenu(); populateMenu(menu, event->scenePos()); menu->popup(event->screenPos()); } } void Worksheet::mousePressEvent(QGraphicsSceneMouseEvent* event) { QGraphicsScene::mousePressEvent(event); if (event->button() == Qt::LeftButton && !focusItem() && lastEntry() && event->scenePos().y() > lastEntry()->y() + lastEntry()->size().height()) lastEntry()->focusEntry(WorksheetTextItem::BottomRight); } void Worksheet::createActions(KActionCollection* collection) { // Mostly copied from KRichTextWidget::createActions(KActionCollection*) // It would be great if this wasn't necessary. // Text color QAction * action; /* This is "format-stroke-color" in KRichTextWidget */ action = new QAction(QIcon::fromTheme(QLatin1String("format-text-color")), i18nc("@action", "Text &Color..."), collection); action->setIconText(i18nc("@label text color", "Color")); action->setPriority(QAction::LowPriority); m_richTextActionList.append(action); collection->addAction(QLatin1String("format_text_foreground_color"), action); connect(action, SIGNAL(triggered()), this, SLOT(setTextForegroundColor())); // Text color action = new QAction(QIcon::fromTheme(QLatin1String("format-fill-color")), i18nc("@action", "Text &Highlight..."), collection); action->setPriority(QAction::LowPriority); m_richTextActionList.append(action); collection->addAction(QLatin1String("format_text_background_color"), action); connect(action, SIGNAL(triggered()), this, SLOT(setTextBackgroundColor())); // Font Family m_fontAction = new KFontAction(i18nc("@action", "&Font"), collection); m_richTextActionList.append(m_fontAction); collection->addAction(QLatin1String("format_font_family"), m_fontAction); connect(m_fontAction, SIGNAL(triggered(QString)), this, SLOT(setFontFamily(QString))); // Font Size m_fontSizeAction = new KFontSizeAction(i18nc("@action", "Font &Size"), collection); m_richTextActionList.append(m_fontSizeAction); collection->addAction(QLatin1String("format_font_size"), m_fontSizeAction); connect(m_fontSizeAction, SIGNAL(fontSizeChanged(int)), this, SLOT(setFontSize(int))); // Bold m_boldAction = new KToggleAction(QIcon::fromTheme(QLatin1String("format-text-bold")), i18nc("@action boldify selected text", "&Bold"), collection); m_boldAction->setPriority(QAction::LowPriority); QFont bold; bold.setBold(true); m_boldAction->setFont(bold); m_richTextActionList.append(m_boldAction); collection->addAction(QLatin1String("format_text_bold"), m_boldAction); collection->setDefaultShortcut(m_boldAction, Qt::CTRL + Qt::Key_B); connect(m_boldAction, SIGNAL(triggered(bool)), this, SLOT(setTextBold(bool))); // Italic m_italicAction = new KToggleAction(QIcon::fromTheme(QLatin1String("format-text-italic")), i18nc("@action italicize selected text", "&Italic"), collection); m_italicAction->setPriority(QAction::LowPriority); QFont italic; italic.setItalic(true); m_italicAction->setFont(italic); m_richTextActionList.append(m_italicAction); collection->addAction(QLatin1String("format_text_italic"), m_italicAction); collection->setDefaultShortcut(m_italicAction, Qt::CTRL + Qt::Key_I); connect(m_italicAction, SIGNAL(triggered(bool)), this, SLOT(setTextItalic(bool))); // Underline m_underlineAction = new KToggleAction(QIcon::fromTheme(QLatin1String("format-text-underline")), i18nc("@action underline selected text", "&Underline"), collection); m_underlineAction->setPriority(QAction::LowPriority); QFont underline; underline.setUnderline(true); m_underlineAction->setFont(underline); m_richTextActionList.append(m_underlineAction); collection->addAction(QLatin1String("format_text_underline"), m_underlineAction); collection->setDefaultShortcut(m_underlineAction, Qt::CTRL + Qt::Key_U); connect(m_underlineAction, SIGNAL(triggered(bool)), this, SLOT(setTextUnderline(bool))); // Strike m_strikeOutAction = new KToggleAction(QIcon::fromTheme(QLatin1String("format-text-strikethrough")), i18nc("@action", "&Strike Out"), collection); m_strikeOutAction->setPriority(QAction::LowPriority); m_richTextActionList.append(m_strikeOutAction); collection->addAction(QLatin1String("format_text_strikeout"), m_strikeOutAction); collection->setDefaultShortcut(m_strikeOutAction, Qt::CTRL + Qt::Key_L); connect(m_strikeOutAction, SIGNAL(triggered(bool)), this, SLOT(setTextStrikeOut(bool))); // Alignment QActionGroup *alignmentGroup = new QActionGroup(this); // Align left m_alignLeftAction = new KToggleAction(QIcon::fromTheme(QLatin1String("format-justify-left")), i18nc("@action", "Align &Left"), collection); m_alignLeftAction->setPriority(QAction::LowPriority); m_alignLeftAction->setIconText(i18nc("@label left justify", "Left")); m_richTextActionList.append(m_alignLeftAction); collection->addAction(QLatin1String("format_align_left"), m_alignLeftAction); connect(m_alignLeftAction, SIGNAL(triggered()), this, SLOT(setAlignLeft())); alignmentGroup->addAction(m_alignLeftAction); // Align center m_alignCenterAction = new KToggleAction(QIcon::fromTheme(QLatin1String("format-justify-center")), i18nc("@action", "Align &Center"), collection); m_alignCenterAction->setPriority(QAction::LowPriority); m_alignCenterAction->setIconText(i18nc("@label center justify", "Center")); m_richTextActionList.append(m_alignCenterAction); collection->addAction(QLatin1String("format_align_center"), m_alignCenterAction); connect(m_alignCenterAction, SIGNAL(triggered()), this, SLOT(setAlignCenter())); alignmentGroup->addAction(m_alignCenterAction); // Align right m_alignRightAction = new KToggleAction(QIcon::fromTheme(QLatin1String("format-justify-right")), i18nc("@action", "Align &Right"), collection); m_alignRightAction->setPriority(QAction::LowPriority); m_alignRightAction->setIconText(i18nc("@label right justify", "Right")); m_richTextActionList.append(m_alignRightAction); collection->addAction(QLatin1String("format_align_right"), m_alignRightAction); connect(m_alignRightAction, SIGNAL(triggered()), this, SLOT(setAlignRight())); alignmentGroup->addAction(m_alignRightAction); // Align justify m_alignJustifyAction = new KToggleAction(QIcon::fromTheme(QLatin1String("format-justify-fill")), i18nc("@action", "&Justify"), collection); m_alignJustifyAction->setPriority(QAction::LowPriority); m_alignJustifyAction->setIconText(i18nc("@label justify fill", "Justify")); m_richTextActionList.append(m_alignJustifyAction); collection->addAction(QLatin1String("format_align_justify"), m_alignJustifyAction); connect(m_alignJustifyAction, SIGNAL(triggered()), this, SLOT(setAlignJustify())); alignmentGroup->addAction(m_alignJustifyAction); /* // List style KSelectAction* selAction; selAction = new KSelectAction(QIcon::fromTheme("format-list-unordered"), i18nc("@title:menu", "List Style"), collection); QStringList listStyles; listStyles << i18nc("@item:inmenu no list style", "None") << i18nc("@item:inmenu disc list style", "Disc") << i18nc("@item:inmenu circle list style", "Circle") << i18nc("@item:inmenu square list style", "Square") << i18nc("@item:inmenu numbered lists", "123") << i18nc("@item:inmenu lowercase abc lists", "abc") << i18nc("@item:inmenu uppercase abc lists", "ABC"); selAction->setItems(listStyles); selAction->setCurrentItem(0); action = selAction; m_richTextActionList.append(action); collection->addAction("format_list_style", action); connect(action, SIGNAL(triggered(int)), this, SLOT(_k_setListStyle(int))); connect(action, SIGNAL(triggered()), this, SLOT(_k_updateMiscActions())); // Indent action = new QAction(QIcon::fromTheme("format-indent-more"), i18nc("@action", "Increase Indent"), collection); action->setPriority(QAction::LowPriority); m_richTextActionList.append(action); collection->addAction("format_list_indent_more", action); connect(action, SIGNAL(triggered()), this, SLOT(indentListMore())); connect(action, SIGNAL(triggered()), this, SLOT(_k_updateMiscActions())); // Dedent action = new QAction(QIcon::fromTheme("format-indent-less"), i18nc("@action", "Decrease Indent"), collection); action->setPriority(QAction::LowPriority); m_richTextActionList.append(action); collection->addAction("format_list_indent_less", action); connect(action, SIGNAL(triggered()), this, SLOT(indentListLess())); connect(action, SIGNAL(triggered()), this, SLOT(_k_updateMiscActions())); */ } WorksheetTextItem* Worksheet::lastFocusedTextItem() { return m_lastFocusedTextItem; } void Worksheet::updateFocusedTextItem(WorksheetTextItem* newItem) { if (m_lastFocusedTextItem && m_lastFocusedTextItem != newItem) { disconnect(m_lastFocusedTextItem, SIGNAL(undoAvailable(bool)), this, SIGNAL(undoAvailable(bool))); disconnect(m_lastFocusedTextItem, SIGNAL(redoAvailable(bool)), this, SIGNAL(redoAvailable(bool))); disconnect(this, SIGNAL(undo()), m_lastFocusedTextItem, SLOT(undo())); disconnect(this, SIGNAL(redo()), m_lastFocusedTextItem, SLOT(redo())); disconnect(m_lastFocusedTextItem, SIGNAL(cutAvailable(bool)), this, SIGNAL(cutAvailable(bool))); disconnect(m_lastFocusedTextItem, SIGNAL(copyAvailable(bool)), this, SIGNAL(copyAvailable(bool))); disconnect(m_lastFocusedTextItem, SIGNAL(pasteAvailable(bool)), this, SIGNAL(pasteAvailable(bool))); disconnect(this, SIGNAL(cut()), m_lastFocusedTextItem, SLOT(cut())); disconnect(this, SIGNAL(copy()), m_lastFocusedTextItem, SLOT(copy())); disconnect(this, SIGNAL(paste()), m_lastFocusedTextItem, SLOT(paste())); m_lastFocusedTextItem->clearSelection(); } if (newItem && m_lastFocusedTextItem != newItem) { setAcceptRichText(newItem->richTextEnabled()); emit undoAvailable(newItem->isUndoAvailable()); emit redoAvailable(newItem->isRedoAvailable()); connect(newItem, SIGNAL(undoAvailable(bool)), this, SIGNAL(undoAvailable(bool))); connect(newItem, SIGNAL(redoAvailable(bool)), this, SIGNAL(redoAvailable(bool))); connect(this, SIGNAL(undo()), newItem, SLOT(undo())); connect(this, SIGNAL(redo()), newItem, SLOT(redo())); emit cutAvailable(newItem->isCutAvailable()); emit copyAvailable(newItem->isCopyAvailable()); emit pasteAvailable(newItem->isPasteAvailable()); connect(newItem, SIGNAL(cutAvailable(bool)), this, SIGNAL(cutAvailable(bool))); connect(newItem, SIGNAL(copyAvailable(bool)), this, SIGNAL(copyAvailable(bool))); connect(newItem, SIGNAL(pasteAvailable(bool)), this, SIGNAL(pasteAvailable(bool))); connect(this, SIGNAL(cut()), newItem, SLOT(cut())); connect(this, SIGNAL(copy()), newItem, SLOT(copy())); connect(this, SIGNAL(paste()), newItem, SLOT(paste())); } else if (!newItem) { emit undoAvailable(false); emit redoAvailable(false); emit cutAvailable(false); emit copyAvailable(false); emit pasteAvailable(false); } m_lastFocusedTextItem = newItem; } void Worksheet::setRichTextInformation(const RichTextInfo& info) { m_boldAction->setChecked(info.bold); m_italicAction->setChecked(info.italic); m_underlineAction->setChecked(info.underline); m_strikeOutAction->setChecked(info.strikeOut); m_fontAction->setFont(info.font); if (info.fontSize > 0) m_fontSizeAction->setFontSize(info.fontSize); if (info.align & Qt::AlignLeft) m_alignLeftAction->setChecked(true); else if (info.align & Qt::AlignCenter) m_alignCenterAction->setChecked(true); else if (info.align & Qt::AlignRight) m_alignRightAction->setChecked(true); else if (info.align & Qt::AlignJustify) m_alignJustifyAction->setChecked(true); } void Worksheet::setAcceptRichText(bool b) { foreach(QAction * action, m_richTextActionList) { action->setEnabled(b); } /* foreach(QWidget* widget, m_fontAction->createdWidgets()) { widget->setEnabled(b); } foreach(QWidget* widget, m_fontSizeAction->createdWidgets()) { widget->setEnabled(b); } */ } WorksheetTextItem* Worksheet::currentTextItem() { QGraphicsItem* item = focusItem(); if (!item) item = m_lastFocusedTextItem; while (item && item->type() != WorksheetTextItem::Type) item = item->parentItem(); return qgraphicsitem_cast(item); } void Worksheet::setTextForegroundColor() { WorksheetTextItem* item = currentTextItem(); if (item) item->setTextForegroundColor(); } void Worksheet::setTextBackgroundColor() { WorksheetTextItem* item = currentTextItem(); if (item) item->setTextBackgroundColor(); } void Worksheet::setTextBold(bool b) { WorksheetTextItem* item = currentTextItem(); if (item) item->setTextBold(b); } void Worksheet::setTextItalic(bool b) { WorksheetTextItem* item = currentTextItem(); if (item) item->setTextItalic(b); } void Worksheet::setTextUnderline(bool b) { WorksheetTextItem* item = currentTextItem(); if (item) item->setTextUnderline(b); } void Worksheet::setTextStrikeOut(bool b) { WorksheetTextItem* item = currentTextItem(); if (item) item->setTextStrikeOut(b); } void Worksheet::setAlignLeft() { WorksheetTextItem* item = currentTextItem(); if (item) item->setAlignment(Qt::AlignLeft); } void Worksheet::setAlignRight() { WorksheetTextItem* item = currentTextItem(); if (item) item->setAlignment(Qt::AlignRight); } void Worksheet::setAlignCenter() { WorksheetTextItem* item = currentTextItem(); if (item) item->setAlignment(Qt::AlignCenter); } void Worksheet::setAlignJustify() { WorksheetTextItem* item = currentTextItem(); if (item) item->setAlignment(Qt::AlignJustify); } void Worksheet::setFontFamily(QString font) { WorksheetTextItem* item = currentTextItem(); if (item) item->setFontFamily(font); } void Worksheet::setFontSize(int size) { WorksheetTextItem* item = currentTextItem(); if (item) item->setFontSize(size); } bool Worksheet::isShortcut(QKeySequence sequence) { return m_shortcuts.contains(sequence); } void Worksheet::registerShortcut(QAction* action) { foreach(QKeySequence shortcut, action->shortcuts()) { m_shortcuts.insert(shortcut, action); } connect(action, SIGNAL(changed()), this, SLOT(updateShortcut())); } void Worksheet::updateShortcut() { QAction* action = qobject_cast(sender()); if (!action) return; // delete the old shortcuts of this action QList shortcuts = m_shortcuts.keys(action); foreach(QKeySequence shortcut, shortcuts) { m_shortcuts.remove(shortcut); } // add the new shortcuts foreach(QKeySequence shortcut, action->shortcuts()) { m_shortcuts.insert(shortcut, action); } } void Worksheet::dragEnterEvent(QGraphicsSceneDragDropEvent* event) { qDebug() << "enter"; if (m_dragEntry) event->accept(); else QGraphicsScene::dragEnterEvent(event); } void Worksheet::dragLeaveEvent(QGraphicsSceneDragDropEvent* event) { if (!m_dragEntry) { QGraphicsScene::dragLeaveEvent(event); return; } qDebug() << "leave"; event->accept(); if (m_placeholderEntry) { m_placeholderEntry->startRemoving(); - m_placeholderEntry = 0; + m_placeholderEntry = nullptr; } } void Worksheet::dragMoveEvent(QGraphicsSceneDragDropEvent* event) { if (!m_dragEntry) { QGraphicsScene::dragMoveEvent(event); return; } QPointF pos = event->scenePos(); WorksheetEntry* entry = entryAt(pos); - WorksheetEntry* prev = 0; - WorksheetEntry* next = 0; + WorksheetEntry* prev = nullptr; + WorksheetEntry* next = nullptr; if (entry) { if (pos.y() < entry->y() + entry->size().height()/2) { prev = entry->previous(); next = entry; } else if (pos.y() >= entry->y() + entry->size().height()/2) { prev = entry; next = entry->next(); } } else { WorksheetEntry* last = lastEntry(); if (last && pos.y() > last->y() + last->size().height()) { prev = last; - next = 0; + next = nullptr; } } if (prev || next) { PlaceHolderEntry* oldPlaceHolder = m_placeholderEntry; if (prev && prev->type() == PlaceHolderEntry::Type && (!prev->aboutToBeRemoved() || prev->stopRemoving())) { m_placeholderEntry = qgraphicsitem_cast(prev); m_placeholderEntry->changeSize(m_dragEntry->size()); } else if (next && next->type() == PlaceHolderEntry::Type && (!next->aboutToBeRemoved() || next->stopRemoving())) { m_placeholderEntry = qgraphicsitem_cast(next); m_placeholderEntry->changeSize(m_dragEntry->size()); } else { m_placeholderEntry = new PlaceHolderEntry(this, QSizeF(0,0)); m_placeholderEntry->setPrevious(prev); m_placeholderEntry->setNext(next); if (prev) prev->setNext(m_placeholderEntry); else setFirstEntry(m_placeholderEntry); if (next) next->setPrevious(m_placeholderEntry); else setLastEntry(m_placeholderEntry); m_placeholderEntry->changeSize(m_dragEntry->size()); } if (oldPlaceHolder && oldPlaceHolder != m_placeholderEntry) oldPlaceHolder->startRemoving(); updateLayout(); } const QPoint viewPos = worksheetView()->mapFromScene(pos); const int viewHeight = worksheetView()->viewport()->height(); if ((viewPos.y() < 10 || viewPos.y() > viewHeight - 10) && !m_dragScrollTimer) { m_dragScrollTimer = new QTimer(this); m_dragScrollTimer->setSingleShot(true); m_dragScrollTimer->setInterval(100); connect(m_dragScrollTimer, SIGNAL(timeout()), this, SLOT(updateDragScrollTimer())); m_dragScrollTimer->start(); } event->accept(); } void Worksheet::dropEvent(QGraphicsSceneDragDropEvent* event) { if (!m_dragEntry) QGraphicsScene::dropEvent(event); event->accept(); } void Worksheet::updateDragScrollTimer() { if (!m_dragScrollTimer) return; const QPoint viewPos = worksheetView()->viewCursorPos(); const QWidget* viewport = worksheetView()->viewport(); const int viewHeight = viewport->height(); if (!m_dragEntry || !(viewport->rect().contains(viewPos)) || (viewPos.y() >= 10 && viewPos.y() <= viewHeight - 10)) { delete m_dragScrollTimer; - m_dragScrollTimer = 0; + m_dragScrollTimer = nullptr; return; } if (viewPos.y() < 10) worksheetView()->scrollBy(-10*(10 - viewPos.y())); else worksheetView()->scrollBy(10*(viewHeight - viewPos.y())); m_dragScrollTimer->start(); } diff --git a/src/worksheet.h b/src/worksheet.h index 09ac16aa..7ffbdb5c 100644 --- a/src/worksheet.h +++ b/src/worksheet.h @@ -1,278 +1,278 @@ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. --- Copyright (C) 2009 Alexander Rieder Copyright (C) 2012 Martin Kuettler */ #ifndef WORKSHEET_H #define WORKSHEET_H #include #include #include #include #include #include #include #include "worksheetview.h" #include "epsrenderer.h" #include "worksheetcursor.h" namespace Cantor { class Backend; class Session; class Expression; } class WorksheetEntry; class PlaceHolderEntry; class WorksheetTextItem; class QDrag; class QAction; class KActionCollection; class KToggleAction; class KFontAction; class KFontSizeAction; class Worksheet : public QGraphicsScene { Q_OBJECT public: Worksheet(Cantor::Backend* backend, QWidget* parent); ~Worksheet() override; Cantor::Session* session(); bool isRunning(); bool showExpressionIds(); bool animationsEnabled(); bool isPrinting(); void setViewSize(qreal w, qreal h, qreal s, bool forceUpdate = false); WorksheetView* worksheetView(); void makeVisible(WorksheetEntry* entry); void makeVisible(const WorksheetCursor& cursor); void setModified(); void startDrag(WorksheetEntry* entry, QDrag* drag); void createActions(KActionCollection* collection); QMenu* createContextMenu(); void populateMenu(QMenu* menu, const QPointF& pos); EpsRenderer* epsRenderer(); bool isEmpty(); WorksheetEntry* currentEntry(); WorksheetEntry* firstEntry(); WorksheetEntry* lastEntry(); WorksheetTextItem* currentTextItem(); WorksheetTextItem* lastFocusedTextItem(); WorksheetCursor worksheetCursor(); void setWorksheetCursor(const WorksheetCursor&); void addProtrusion(qreal width); void updateProtrusion(qreal oldWidth, qreal newWidth); void removeProtrusion(qreal width); bool isShortcut(QKeySequence sequence); // richtext struct RichTextInfo { bool bold; bool italic; bool underline; bool strikeOut; QString font; qreal fontSize; Qt::Alignment align; }; public Q_SLOTS: WorksheetEntry* appendCommandEntry(); void appendCommandEntry(const QString& text); WorksheetEntry* appendTextEntry(); WorksheetEntry* appendImageEntry(); WorksheetEntry* appendPageBreakEntry(); WorksheetEntry* appendLatexEntry(); - WorksheetEntry* insertCommandEntry(WorksheetEntry* current = 0); + WorksheetEntry* insertCommandEntry(WorksheetEntry* current = nullptr); void insertCommandEntry(const QString& text); - WorksheetEntry* insertTextEntry(WorksheetEntry* current = 0); - WorksheetEntry* insertImageEntry(WorksheetEntry* current = 0); - WorksheetEntry* insertPageBreakEntry(WorksheetEntry* current = 0); - WorksheetEntry* insertLatexEntry(WorksheetEntry* current = 0); - WorksheetEntry* insertCommandEntryBefore(WorksheetEntry* current = 0); - WorksheetEntry* insertTextEntryBefore(WorksheetEntry* current = 0); - WorksheetEntry* insertImageEntryBefore(WorksheetEntry* current = 0); - WorksheetEntry* insertPageBreakEntryBefore(WorksheetEntry* current = 0); - WorksheetEntry* insertLatexEntryBefore(WorksheetEntry* current = 0); + WorksheetEntry* insertTextEntry(WorksheetEntry* current = nullptr); + WorksheetEntry* insertImageEntry(WorksheetEntry* current = nullptr); + WorksheetEntry* insertPageBreakEntry(WorksheetEntry* current = nullptr); + WorksheetEntry* insertLatexEntry(WorksheetEntry* current = nullptr); + WorksheetEntry* insertCommandEntryBefore(WorksheetEntry* current = nullptr); + WorksheetEntry* insertTextEntryBefore(WorksheetEntry* current = nullptr); + WorksheetEntry* insertImageEntryBefore(WorksheetEntry* current = nullptr); + WorksheetEntry* insertPageBreakEntryBefore(WorksheetEntry* current = nullptr); + WorksheetEntry* insertLatexEntryBefore(WorksheetEntry* current = nullptr); void updateLayout(); void updateEntrySize(WorksheetEntry* entry); void print(QPrinter* printer); void focusEntry(WorksheetEntry * entry); void evaluate(); void evaluateCurrentEntry(); void interrupt(); void interruptCurrentEntryEvaluation(); bool completionEnabled(); //void showCompletion(); void highlightItem(WorksheetTextItem*); void rehighlight(); void enableHighlighting(bool highlight); void enableCompletion(bool enable); void enableExpressionNumbering(bool enable); void enableAnimations(bool enable); - QDomDocument toXML(KZip* archive=0); + QDomDocument toXML(KZip* archive=nullptr); void save(const QString& filename); void save(QIODevice* device); QByteArray saveToByteArray(); void savePlain(const QString& filename); void saveLatex(const QString& filename); void load(QIODevice* device); void load(QByteArray* data); void load(const QString& filename); - void gotResult(Cantor::Expression* expr=0); + void gotResult(Cantor::Expression* expr=nullptr); void removeCurrentEntry(); void setFirstEntry(WorksheetEntry* entry); void setLastEntry(WorksheetEntry* entry); void invalidateFirstEntry(); void invalidateLastEntry(); void updateFocusedTextItem(WorksheetTextItem* item); void updateDragScrollTimer(); void registerShortcut(QAction*); void updateShortcut(); // richtext void setRichTextInformation(const RichTextInfo&); void setAcceptRichText(bool b); void setTextForegroundColor(); void setTextBackgroundColor(); void setTextBold(bool b); void setTextItalic(bool b); void setTextUnderline(bool b); void setTextStrikeOut(bool b); void setAlignLeft(); void setAlignRight(); void setAlignCenter(); void setAlignJustify(); void setFontFamily(QString font); void setFontSize(int size); Q_SIGNALS: void modified(); void sessionChanged(); void showHelp(const QString& help); void updatePrompt(); void undoAvailable(bool); void redoAvailable(bool); void undo(); void redo(); void cutAvailable(bool); void copyAvailable(bool); void pasteAvailable(bool); void cut(); void copy(); void paste(); protected: void contextMenuEvent(QGraphicsSceneContextMenuEvent *event) Q_DECL_OVERRIDE; void mousePressEvent(QGraphicsSceneMouseEvent* event) Q_DECL_OVERRIDE; void dragEnterEvent(QGraphicsSceneDragDropEvent* event) Q_DECL_OVERRIDE; void dragLeaveEvent(QGraphicsSceneDragDropEvent* event) Q_DECL_OVERRIDE; void dragMoveEvent(QGraphicsSceneDragDropEvent* event) Q_DECL_OVERRIDE; void dropEvent(QGraphicsSceneDragDropEvent* event) Q_DECL_OVERRIDE; private Q_SLOTS: void loginToSession(); void showCompletion(); //void checkEntriesForSanity(); WorksheetEntry* appendEntry(int type); - WorksheetEntry* insertEntry(int type, WorksheetEntry* current = 0); - WorksheetEntry* insertEntryBefore(int type, WorksheetEntry* current = 0); + WorksheetEntry* insertEntry(int type, WorksheetEntry* current = nullptr); + WorksheetEntry* insertEntryBefore(int type, WorksheetEntry* current = nullptr); private: WorksheetEntry* entryAt(qreal x, qreal y); WorksheetEntry* entryAt(QPointF p); WorksheetEntry* entryAt(int row); int entryCount(); private: static const double LeftMargin; static const double RightMargin; static const double TopMargin; Cantor::Session *m_session; QSyntaxHighlighter* m_highlighter; EpsRenderer m_epsRenderer; WorksheetEntry* m_firstEntry; WorksheetEntry* m_lastEntry; WorksheetEntry* m_dragEntry; PlaceHolderEntry* m_placeholderEntry; WorksheetTextItem* m_lastFocusedTextItem; QTimer* m_dragScrollTimer; double m_viewWidth; double m_protrusion; QMap m_itemProtrusions; QMap m_shortcuts; QList m_richTextActionList; KToggleAction* m_boldAction; KToggleAction* m_italicAction; KToggleAction* m_underlineAction; KToggleAction* m_strikeOutAction; KFontAction* m_fontAction; KFontSizeAction* m_fontSizeAction; KToggleAction* m_alignLeftAction; KToggleAction* m_alignCenterAction; KToggleAction* m_alignRightAction; KToggleAction* m_alignJustifyAction; bool m_completionEnabled; bool m_showExpressionIds; bool m_animationsEnabled; bool m_loginDone; bool m_isPrinting; }; #endif // WORKSHEET_H diff --git a/src/worksheetcursor.cpp b/src/worksheetcursor.cpp index 09a9fa99..befa98ad 100644 --- a/src/worksheetcursor.cpp +++ b/src/worksheetcursor.cpp @@ -1,61 +1,61 @@ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. --- Copyright (C) 2012 Martin Kuettler */ #include "worksheetcursor.h" WorksheetCursor::WorksheetCursor() { - m_entry = 0; - m_textItem = 0; + m_entry = nullptr; + m_textItem = nullptr; m_textCursor = QTextCursor(); } WorksheetCursor::WorksheetCursor(WorksheetEntry* entry, WorksheetTextItem* item, const QTextCursor& cursor) { m_entry = entry; m_textItem = item; m_textCursor = cursor; } WorksheetCursor::~WorksheetCursor() { } WorksheetEntry* WorksheetCursor::entry() const { return m_entry; } WorksheetTextItem* WorksheetCursor::textItem() const { return m_textItem; } QTextCursor WorksheetCursor::textCursor() const { return m_textCursor; } bool WorksheetCursor::isValid() const { return m_entry && m_textItem; } diff --git a/src/worksheetentry.cpp b/src/worksheetentry.cpp index f468f911..496ca93b 100644 --- a/src/worksheetentry.cpp +++ b/src/worksheetentry.cpp @@ -1,792 +1,792 @@ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. --- Copyright (C) 2012 Martin Kuettler */ #include "worksheetentry.h" #include "commandentry.h" #include "textentry.h" #include "latexentry.h" #include "imageentry.h" #include "pagebreakentry.h" #include "settings.h" #include "actionbar.h" #include "worksheettoolbutton.h" #include #include #include #include #include #include #include #include #include #include struct AnimationData { QAnimationGroup* animation; QPropertyAnimation* sizeAnimation; QPropertyAnimation* opacAnimation; QPropertyAnimation* posAnimation; const char* slot; QGraphicsObject* item; }; const qreal WorksheetEntry::VerticalMargin = 4; WorksheetEntry::WorksheetEntry(Worksheet* worksheet) : QGraphicsObject() { - m_next = 0; - m_prev = 0; - m_animation = 0; - m_actionBar = 0; - m_actionBarAnimation = 0; + m_next = nullptr; + m_prev = nullptr; + m_animation = nullptr; + m_actionBar = nullptr; + m_actionBarAnimation = nullptr; m_aboutToBeRemoved = false; setAcceptHoverEvents(true); worksheet->addItem(this); } WorksheetEntry::~WorksheetEntry() { emit aboutToBeDeleted(); if (next()) next()->setPrevious(previous()); if (previous()) previous()->setNext(next()); if (m_animation) { m_animation->animation->deleteLater(); delete m_animation; } } int WorksheetEntry::type() const { return Type; } WorksheetEntry* WorksheetEntry::create(int t, Worksheet* worksheet) { switch(t) { case TextEntry::Type: return new TextEntry(worksheet); case CommandEntry::Type: return new CommandEntry(worksheet); case ImageEntry::Type: return new ImageEntry(worksheet); case PageBreakEntry::Type: return new PageBreakEntry(worksheet); case LatexEntry::Type: return new LatexEntry(worksheet); default: - return 0; + return nullptr; } } void WorksheetEntry::insertCommandEntry() { worksheet()->insertCommandEntry(this); } void WorksheetEntry::insertTextEntry() { worksheet()->insertTextEntry(this); } void WorksheetEntry::insertLatexEntry() { worksheet()->insertLatexEntry(this); } void WorksheetEntry::insertImageEntry() { worksheet()->insertImageEntry(this); } void WorksheetEntry::insertPageBreakEntry() { worksheet()->insertPageBreakEntry(this); } void WorksheetEntry::insertCommandEntryBefore() { worksheet()->insertCommandEntryBefore(this); } void WorksheetEntry::insertTextEntryBefore() { worksheet()->insertTextEntryBefore(this); } void WorksheetEntry::insertLatexEntryBefore() { worksheet()->insertLatexEntryBefore(this); } void WorksheetEntry::insertImageEntryBefore() { worksheet()->insertImageEntryBefore(this); } void WorksheetEntry::insertPageBreakEntryBefore() { worksheet()->insertPageBreakEntryBefore(this); } void WorksheetEntry::showCompletion() { } WorksheetEntry* WorksheetEntry::next() const { return m_next; } WorksheetEntry* WorksheetEntry::previous() const { return m_prev; } void WorksheetEntry::setNext(WorksheetEntry* n) { m_next = n; } void WorksheetEntry::setPrevious(WorksheetEntry* p) { m_prev = p; } void WorksheetEntry::startDrag(const QPointF& grabPos) { QDrag* drag = new QDrag(worksheetView()); qDebug() << size(); const qreal scale = worksheet()->epsRenderer()->scale(); QPixmap pixmap((size()*scale).toSize()); pixmap.fill(QColor(255, 255, 255, 0)); QPainter painter(&pixmap); const QRectF sceneRect = mapRectToScene(boundingRect()); worksheet()->render(&painter, pixmap.rect(), sceneRect); painter.end(); QBitmap mask = pixmap.createMaskFromColor(QColor(255, 255, 255), Qt::MaskInColor); pixmap.setMask(mask); drag->setPixmap(pixmap); if (grabPos.isNull()) { const QPointF scenePos = worksheetView()->sceneCursorPos(); drag->setHotSpot((mapFromScene(scenePos) * scale).toPoint()); } else { drag->setHotSpot((grabPos * scale).toPoint()); } drag->setMimeData(new QMimeData()); worksheet()->startDrag(this, drag); } QRectF WorksheetEntry::boundingRect() const { return QRectF(QPointF(0,0), m_size); } void WorksheetEntry::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) { Q_UNUSED(painter); Q_UNUSED(option); Q_UNUSED(widget); } bool WorksheetEntry::focusEntry(int pos, qreal xCoord) { Q_UNUSED(pos); Q_UNUSED(xCoord); if (flags() & QGraphicsItem::ItemIsFocusable) { setFocus(); return true; } return false; } void WorksheetEntry::moveToPreviousEntry(int pos, qreal x) { WorksheetEntry* entry = previous(); while (entry && !(entry->wantFocus() && entry->focusEntry(pos, x))) entry = entry->previous(); } void WorksheetEntry::moveToNextEntry(int pos, qreal x) { WorksheetEntry* entry = next(); while (entry && !(entry->wantFocus() && entry->focusEntry(pos, x))) entry = entry->next(); } Worksheet* WorksheetEntry::worksheet() { return qobject_cast(scene()); } WorksheetView* WorksheetEntry::worksheetView() { return worksheet()->worksheetView(); } WorksheetCursor WorksheetEntry::search(QString pattern, unsigned flags, QTextDocument::FindFlags qt_flags, const WorksheetCursor& pos) { Q_UNUSED(pattern); Q_UNUSED(flags); Q_UNUSED(qt_flags); Q_UNUSED(pos); return WorksheetCursor(); } void WorksheetEntry::keyPressEvent(QKeyEvent* event) { // This event is used in Entries that set the ItemIsFocusable flag switch(event->key()) { case Qt::Key_Left: case Qt::Key_Up: if (event->modifiers() == Qt::NoModifier) moveToPreviousEntry(WorksheetTextItem::BottomRight, 0); break; case Qt::Key_Right: case Qt::Key_Down: if (event->modifiers() == Qt::NoModifier) moveToNextEntry(WorksheetTextItem::TopLeft, 0); break; /*case Qt::Key_Enter: case Qt::Key_Return: if (event->modifiers() == Qt::ShiftModifier) evaluate(); else if (event->modifiers() == Qt::ControlModifier) worksheet()->insertCommandEntry(); break; case Qt::Key_Delete: if (event->modifiers() == Qt::ShiftModifier) startRemoving(); break;*/ default: event->ignore(); } } void WorksheetEntry::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) { QMenu *menu = worksheet()->createContextMenu(); populateMenu(menu, event->pos()); menu->popup(event->screenPos()); } void WorksheetEntry::populateMenu(QMenu *menu, const QPointF& pos) { if (!worksheet()->isRunning() && wantToEvaluate()) menu->addAction(i18n("Evaluate Entry"), this, SLOT(evaluate()), 0); menu->addAction(QIcon::fromTheme(QLatin1String("edit-delete")), i18n("Remove Entry"), this, SLOT(startRemoving()), 0); worksheet()->populateMenu(menu, mapToScene(pos)); } bool WorksheetEntry::evaluateCurrentItem() { // A default implementation that works well for most entries, // because they have only one item. return evaluate(); } void WorksheetEntry::evaluateNext(EvaluationOption opt) { WorksheetEntry* entry = next(); while (entry && !entry->wantFocus()) entry = entry->next(); if (entry) { if (opt == EvaluateNext || Settings::self()->autoEval()) { entry->evaluate(EvaluateNext); } else if (opt == FocusNext) { worksheet()->setModified(); entry->focusEntry(WorksheetTextItem::BottomRight); } else { worksheet()->setModified(); } } else if (opt != DoNothing) { if (!isEmpty() || type() != CommandEntry::Type) worksheet()->appendCommandEntry(); else focusEntry(); worksheet()->setModified(); } } qreal WorksheetEntry::setGeometry(qreal x, qreal y, qreal w) { setPos(x, y); layOutForWidth(w); return size().height(); } void WorksheetEntry::recalculateSize() { qreal height = size().height(); layOutForWidth(size().width(), true); if (height != size().height()) worksheet()->updateEntrySize(this); } QPropertyAnimation* WorksheetEntry::sizeChangeAnimation(QSizeF s) { QSizeF oldSize; QSizeF newSize; if (s.isValid()) { oldSize = size(); newSize = s; } else { oldSize = size(); layOutForWidth(size().width(), true); newSize = size(); } qDebug() << oldSize << newSize; QPropertyAnimation* sizeAn = new QPropertyAnimation(this, "size", this); sizeAn->setDuration(200); sizeAn->setStartValue(oldSize); sizeAn->setEndValue(newSize); sizeAn->setEasingCurve(QEasingCurve::InOutQuad); connect(sizeAn, &QPropertyAnimation::valueChanged, this, &WorksheetEntry::sizeAnimated); return sizeAn; } void WorksheetEntry::sizeAnimated() { worksheet()->updateEntrySize(this); } void WorksheetEntry::animateSizeChange() { if (!worksheet()->animationsEnabled()) { recalculateSize(); return; } if (m_animation) { layOutForWidth(size().width(), true); return; } QPropertyAnimation* sizeAn = sizeChangeAnimation(); m_animation = new AnimationData; - m_animation->item = 0; - m_animation->slot = 0; - m_animation->opacAnimation = 0; - m_animation->posAnimation = 0; + m_animation->item = nullptr; + m_animation->slot = nullptr; + m_animation->opacAnimation = nullptr; + m_animation->posAnimation = nullptr; m_animation->sizeAnimation = sizeAn; m_animation->sizeAnimation->setEasingCurve(QEasingCurve::OutCubic); m_animation->animation = new QParallelAnimationGroup(this); m_animation->animation->addAnimation(m_animation->sizeAnimation); connect(m_animation->animation, &QAnimationGroup::finished, this, &WorksheetEntry::endAnimation); m_animation->animation->start(); } void WorksheetEntry::fadeInItem(QGraphicsObject* item, const char* slot) { if (!worksheet()->animationsEnabled()) { recalculateSize(); if (slot) invokeSlotOnObject(slot, item); return; } if (m_animation) { // this calculates the new size and calls updateSizeAnimation layOutForWidth(size().width(), true); if (slot) invokeSlotOnObject(slot, item); return; } QPropertyAnimation* sizeAn = sizeChangeAnimation(); m_animation = new AnimationData; m_animation->sizeAnimation = sizeAn; m_animation->sizeAnimation->setEasingCurve(QEasingCurve::OutCubic); m_animation->opacAnimation = new QPropertyAnimation(item, "opacity", this); m_animation->opacAnimation->setDuration(200); m_animation->opacAnimation->setStartValue(0); m_animation->opacAnimation->setEndValue(1); m_animation->opacAnimation->setEasingCurve(QEasingCurve::OutCubic); - m_animation->posAnimation = 0; + m_animation->posAnimation = nullptr; m_animation->animation = new QParallelAnimationGroup(this); m_animation->item = item; m_animation->slot = slot; m_animation->animation->addAnimation(m_animation->sizeAnimation); m_animation->animation->addAnimation(m_animation->opacAnimation); connect(m_animation->animation, &QAnimationGroup::finished, this, &WorksheetEntry::endAnimation); m_animation->animation->start(); } void WorksheetEntry::fadeOutItem(QGraphicsObject* item, const char* slot) { // Note: The default value for slot is SLOT(deleteLater()), so item // will be deleted after the animation. if (!worksheet()->animationsEnabled()) { recalculateSize(); if (slot) invokeSlotOnObject(slot, item); return; } if (m_animation) { // this calculates the new size and calls updateSizeAnimation layOutForWidth(size().width(), true); if (slot) invokeSlotOnObject(slot, item); return; } QPropertyAnimation* sizeAn = sizeChangeAnimation(); m_animation = new AnimationData; m_animation->sizeAnimation = sizeAn; m_animation->opacAnimation = new QPropertyAnimation(item, "opacity", this); m_animation->opacAnimation->setDuration(200); m_animation->opacAnimation->setStartValue(1); m_animation->opacAnimation->setEndValue(0); m_animation->opacAnimation->setEasingCurve(QEasingCurve::OutCubic); - m_animation->posAnimation = 0; + m_animation->posAnimation = nullptr; m_animation->animation = new QParallelAnimationGroup(this); m_animation->item = item; m_animation->slot = slot; m_animation->animation->addAnimation(m_animation->sizeAnimation); m_animation->animation->addAnimation(m_animation->opacAnimation); connect(m_animation->animation, &QAnimationGroup::finished, this, &WorksheetEntry::endAnimation); m_animation->animation->start(); } void WorksheetEntry::endAnimation() { if (!m_animation) return; QAnimationGroup* anim = m_animation->animation; if (anim->state() == QAbstractAnimation::Running) { anim->stop(); if (m_animation->sizeAnimation) setSize(m_animation->sizeAnimation->endValue().value()); if (m_animation->opacAnimation) { qreal opac = m_animation->opacAnimation->endValue().value(); m_animation->item->setOpacity(opac); } if (m_animation->posAnimation) { const QPointF& pos = m_animation->posAnimation->endValue().value(); m_animation->item->setPos(pos); } // If the animation was connected to a slot, call it if (m_animation->slot) invokeSlotOnObject(m_animation->slot, m_animation->item); } m_animation->animation->deleteLater(); delete m_animation; - m_animation = 0; + m_animation = nullptr; } bool WorksheetEntry::animationActive() { return m_animation; } void WorksheetEntry::updateSizeAnimation(const QSizeF& size) { // Update the current animation, so that the new ending will be size if (!m_animation) return; if (m_aboutToBeRemoved) // do not modify the remove-animation return; if (m_animation->sizeAnimation) { QPropertyAnimation* sizeAn = m_animation->sizeAnimation; qreal progress = static_cast(sizeAn->currentTime()) / sizeAn->totalDuration(); QEasingCurve curve = sizeAn->easingCurve(); qreal value = curve.valueForProgress(progress); sizeAn->setEndValue(size); QSizeF newStart = 1/(1-value)*(sizeAn->currentValue().value() - value * size); sizeAn->setStartValue(newStart); } else { m_animation->sizeAnimation = sizeChangeAnimation(size); int d = m_animation->animation->duration() - m_animation->animation->currentTime(); m_animation->sizeAnimation->setDuration(d); m_animation->animation->addAnimation(m_animation->sizeAnimation); } } void WorksheetEntry::invokeSlotOnObject(const char* slot, QObject* obj) { const QMetaObject* metaObj = obj->metaObject(); const QByteArray normSlot = QMetaObject::normalizedSignature(slot); const int slotIndex = metaObj->indexOfSlot(normSlot.constData()); if (slotIndex == -1) qDebug() << "Warning: Tried to invoke an invalid slot:" << slot; const QMetaMethod method = metaObj->method(slotIndex); method.invoke(obj, Qt::DirectConnection); } bool WorksheetEntry::aboutToBeRemoved() { return m_aboutToBeRemoved; } void WorksheetEntry::startRemoving() { if (!worksheet()->animationsEnabled()) { m_aboutToBeRemoved = true; remove(); return; } if (m_aboutToBeRemoved) return; if (focusItem()) { if (!next()) { if (previous() && previous()->isEmpty() && !previous()->aboutToBeRemoved()) { previous()->focusEntry(); } else { WorksheetEntry* next = worksheet()->appendCommandEntry(); setNext(next); next->focusEntry(); } } else { next()->focusEntry(); } } if (m_animation) { endAnimation(); } m_aboutToBeRemoved = true; m_animation = new AnimationData; m_animation->sizeAnimation = new QPropertyAnimation(this, "size", this); m_animation->sizeAnimation->setDuration(300); m_animation->sizeAnimation->setEndValue(QSizeF(size().width(), 0)); m_animation->sizeAnimation->setEasingCurve(QEasingCurve::InOutQuad); connect(m_animation->sizeAnimation, &QPropertyAnimation::valueChanged, this, &WorksheetEntry::sizeAnimated); connect(m_animation->sizeAnimation, &QPropertyAnimation::finished, this, &WorksheetEntry::remove); m_animation->opacAnimation = new QPropertyAnimation(this, "opacity", this); m_animation->opacAnimation->setDuration(300); m_animation->opacAnimation->setEndValue(0); m_animation->opacAnimation->setEasingCurve(QEasingCurve::OutCubic); - m_animation->posAnimation = 0; + m_animation->posAnimation = nullptr; m_animation->animation = new QParallelAnimationGroup(this); m_animation->animation->addAnimation(m_animation->sizeAnimation); m_animation->animation->addAnimation(m_animation->opacAnimation); m_animation->animation->start(); } bool WorksheetEntry::stopRemoving() { if (!m_aboutToBeRemoved) return true; if (m_animation->animation->state() == QAbstractAnimation::Stopped) // we are too late to stop the deletion return false; m_aboutToBeRemoved = false; m_animation->animation->stop(); m_animation->animation->deleteLater(); delete m_animation; - m_animation = 0; + m_animation = nullptr; return true; } void WorksheetEntry::remove() { if (!m_aboutToBeRemoved) return; if (previous() && previous()->next() == this) previous()->setNext(next()); else worksheet()->setFirstEntry(next()); if (next() && next()->previous() == this) next()->setPrevious(previous()); else worksheet()->setLastEntry(previous()); // make the entry invisible to QGraphicsScene's itemAt() function hide(); worksheet()->updateLayout(); deleteLater(); } void WorksheetEntry::setSize(QSizeF size) { prepareGeometryChange(); if (m_actionBar && size != m_size) m_actionBar->updatePosition(); m_size = size; } QSizeF WorksheetEntry::size() { return m_size; } bool WorksheetEntry::hasActionBar() { return m_actionBar; } void WorksheetEntry::showActionBar() { if (m_actionBar && !m_actionBarAnimation) return; if (m_actionBarAnimation) { if (m_actionBarAnimation->endValue().toReal() == 1) return; m_actionBarAnimation->stop(); delete m_actionBarAnimation; - m_actionBarAnimation = 0; + m_actionBarAnimation = nullptr; } if (!m_actionBar) { m_actionBar = new ActionBar(this); m_actionBar->addButton(QIcon::fromTheme(QLatin1String("edit-delete")), i18n("Remove Entry"), this, SLOT(startRemoving())); WorksheetToolButton* dragButton; dragButton = m_actionBar->addButton(QIcon::fromTheme(QLatin1String("transform-move")), i18n("Drag Entry")); connect(dragButton, SIGNAL(pressed()), this, SLOT(startDrag())); if (wantToEvaluate()) { QString toolTip = i18n("Evaluate Entry"); m_actionBar->addButton(QIcon::fromTheme(QLatin1String("view-refresh")), toolTip, this, SLOT(evaluate())); } m_actionBar->addSpace(); addActionsToBar(m_actionBar); } if (worksheet()->animationsEnabled()) { m_actionBarAnimation = new QPropertyAnimation(m_actionBar, "opacity", this); m_actionBarAnimation->setStartValue(0); m_actionBarAnimation->setKeyValueAt(0.666, 0); m_actionBarAnimation->setEndValue(1); m_actionBarAnimation->setDuration(600); connect(m_actionBarAnimation, &QPropertyAnimation::finished, this, &WorksheetEntry::deleteActionBarAnimation); m_actionBarAnimation->start(); } } void WorksheetEntry::hideActionBar() { if (!m_actionBar) return; if (m_actionBarAnimation) { if (m_actionBarAnimation->endValue().toReal() == 0) return; m_actionBarAnimation->stop(); delete m_actionBarAnimation; - m_actionBarAnimation = 0; + m_actionBarAnimation = nullptr; } if (worksheet()->animationsEnabled()) { m_actionBarAnimation = new QPropertyAnimation(m_actionBar, "opacity", this); m_actionBarAnimation->setEndValue(0); m_actionBarAnimation->setEasingCurve(QEasingCurve::Linear); m_actionBarAnimation->setDuration(200); connect(m_actionBarAnimation, &QPropertyAnimation::finished, this, &WorksheetEntry::deleteActionBar); m_actionBarAnimation->start(); } else { deleteActionBar(); } } void WorksheetEntry::deleteActionBarAnimation() { if (m_actionBarAnimation) { delete m_actionBarAnimation; - m_actionBarAnimation = 0; + m_actionBarAnimation = nullptr; } } void WorksheetEntry::deleteActionBar() { if (m_actionBar) { delete m_actionBar; - m_actionBar = 0; + m_actionBar = nullptr; } deleteActionBarAnimation(); } void WorksheetEntry::addActionsToBar(ActionBar*) { } void WorksheetEntry::hoverEnterEvent(QGraphicsSceneHoverEvent* event) { Q_UNUSED(event); showActionBar(); } void WorksheetEntry::hoverLeaveEvent(QGraphicsSceneHoverEvent* event) { Q_UNUSED(event); hideActionBar(); } WorksheetTextItem* WorksheetEntry::highlightItem() { - return 0; + return nullptr; } bool WorksheetEntry::wantFocus() { return true; } diff --git a/src/worksheetentry.h b/src/worksheetentry.h index 8aa081b0..3a05e614 100644 --- a/src/worksheetentry.h +++ b/src/worksheetentry.h @@ -1,187 +1,187 @@ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. --- Copyright (C) 2012 Martin Kuettler */ #ifndef WORKSHEETENTRY_H #define WORKSHEETENTRY_H #include #include #include "worksheet.h" #include "worksheettextitem.h" #include "worksheetcursor.h" class TextEntry; class CommandEntry; class ImageEntry; class PageBreakEntry; class LaTeXEntry; class WorksheetTextItem; class ActionBar; class QPainter; class QWidget; class QPropertyAnimation; struct AnimationData; class WorksheetEntry : public QGraphicsObject { Q_OBJECT public: WorksheetEntry(Worksheet* worksheet); ~WorksheetEntry() override; enum {Type = UserType}; int type() const Q_DECL_OVERRIDE; virtual bool isEmpty()=0; static WorksheetEntry* create(int t, Worksheet* worksheet); WorksheetEntry* next() const; WorksheetEntry* previous() const; void setNext(WorksheetEntry*); void setPrevious(WorksheetEntry*); QRectF boundingRect() const Q_DECL_OVERRIDE; - void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget = 0) Q_DECL_OVERRIDE; + void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget = nullptr) Q_DECL_OVERRIDE; virtual bool acceptRichText() = 0; virtual void setContent(const QString& content)=0; virtual void setContent(const QDomElement& content, const KZip& file)=0; virtual QDomElement toXml(QDomDocument& doc, KZip* archive)=0; virtual QString toPlain(const QString& commandSep, const QString& commentStartingSeq, const QString& commentEndingSeq)=0; virtual void interruptEvaluation()=0; virtual void showCompletion(); virtual bool focusEntry(int pos = WorksheetTextItem::TopLeft, qreal xCoord = 0); virtual qreal setGeometry(qreal x, qreal y, qreal w); virtual void layOutForWidth(qreal w, bool force = false) = 0; QPropertyAnimation* sizeChangeAnimation(QSizeF s = QSizeF()); virtual void populateMenu(QMenu *menu, const QPointF& pos); bool aboutToBeRemoved(); QSizeF size(); enum EvaluationOption { DoNothing, FocusNext, EvaluateNext }; virtual WorksheetTextItem* highlightItem(); bool hasActionBar(); enum SearchFlag {SearchCommand=1, SearchResult=2, SearchError=4, SearchText=8, SearchLaTeX=16, SearchAll=31}; virtual WorksheetCursor search(QString pattern, unsigned flags, QTextDocument::FindFlags qt_flags, const WorksheetCursor& pos = WorksheetCursor()); public Q_SLOTS: virtual bool evaluate(EvaluationOption evalOp = FocusNext) = 0; virtual bool evaluateCurrentItem(); virtual void updateEntry() = 0; void insertCommandEntry(); void insertTextEntry(); void insertLatexEntry(); void insertImageEntry(); void insertPageBreakEntry(); void insertCommandEntryBefore(); void insertTextEntryBefore(); void insertLatexEntryBefore(); void insertImageEntryBefore(); void insertPageBreakEntryBefore(); virtual void sizeAnimated(); virtual void startRemoving(); bool stopRemoving(); void moveToPreviousEntry(int pos = WorksheetTextItem::BottomRight, qreal x = 0); void moveToNextEntry(int pos = WorksheetTextItem::TopLeft, qreal x = 0); void recalculateSize(); // similar to recalculateSize, but the size change is animated void animateSizeChange(); // animate the size change and the opacity of item - void fadeInItem(QGraphicsObject* item = 0, const char* slot = 0); - void fadeOutItem(QGraphicsObject* item = 0, const char* slot = "deleteLater()"); + void fadeInItem(QGraphicsObject* item = nullptr, const char* slot = nullptr); + void fadeOutItem(QGraphicsObject* item = nullptr, const char* slot = "deleteLater()"); void endAnimation(); void showActionBar(); void hideActionBar(); void startDrag(const QPointF& grabPos = QPointF()); Q_SIGNALS: void aboutToBeDeleted(); protected: Worksheet* worksheet(); WorksheetView* worksheetView(); void contextMenuEvent(QGraphicsSceneContextMenuEvent *event) Q_DECL_OVERRIDE; void keyPressEvent(QKeyEvent *event) Q_DECL_OVERRIDE; void evaluateNext(EvaluationOption opt); void hoverEnterEvent(QGraphicsSceneHoverEvent* event) Q_DECL_OVERRIDE; void hoverLeaveEvent(QGraphicsSceneHoverEvent* event) Q_DECL_OVERRIDE; void setSize(QSizeF size); bool animationActive(); void updateSizeAnimation(const QSizeF& size); void invokeSlotOnObject(const char* slot, QObject* obj); virtual void addActionsToBar(ActionBar* actionBar); virtual bool wantToEvaluate() = 0; virtual bool wantFocus(); protected Q_SLOTS: virtual void remove(); void deleteActionBar(); void deleteActionBarAnimation(); protected: static const qreal VerticalMargin; private: QSizeF m_size; WorksheetEntry* m_prev; WorksheetEntry* m_next; Q_PROPERTY(QSizeF size READ size WRITE setSize) AnimationData* m_animation; ActionBar* m_actionBar; QPropertyAnimation* m_actionBarAnimation; bool m_aboutToBeRemoved; }; #endif // WORKSHEETENTRY_H diff --git a/src/worksheetimageitem.h b/src/worksheetimageitem.h index c3441551..3e8fd1ae 100644 --- a/src/worksheetimageitem.h +++ b/src/worksheetimageitem.h @@ -1,79 +1,79 @@ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. --- Copyright (C) 2012 Martin Kuettler */ #ifndef WORKSHEETIMAGEITEM_H #define WORKSHEETIMAGEITEM_H #include #include class Worksheet; class QMovie; class QImage; class QGraphicsSceneContextMenuEvent; class QMenu; class WorksheetImageItem : public QGraphicsObject { Q_OBJECT public: WorksheetImageItem(QGraphicsObject* parent); ~WorksheetImageItem() override; enum {Type = UserType + 101}; int type() const Q_DECL_OVERRIDE; bool imageIsValid(); virtual qreal setGeometry(qreal x, qreal y, qreal w, bool centered=false); qreal height() const; qreal width() const; QSizeF size(); void setSize(QSizeF size); QSize imageSize(); QRectF boundingRect() const Q_DECL_OVERRIDE; void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, - QWidget *widget = 0) Q_DECL_OVERRIDE; + QWidget *widget = nullptr) Q_DECL_OVERRIDE; void setEps(const QUrl &url); void setImage(QImage img); void setPixmap(QPixmap pixmap); virtual void populateMenu(QMenu *menu, const QPointF& pos); Worksheet* worksheet(); Q_SIGNALS: void sizeChanged(); void menuCreated(QMenu*, const QPointF&); protected: void contextMenuEvent(QGraphicsSceneContextMenuEvent *event) Q_DECL_OVERRIDE; private: QPixmap m_pixmap; QSizeF m_size; qreal m_maxWidth; }; #endif //WORKSHEETIMAGEITEM_H diff --git a/src/worksheettextitem.cpp b/src/worksheettextitem.cpp index 493ed48d..99fa3385 100644 --- a/src/worksheettextitem.cpp +++ b/src/worksheettextitem.cpp @@ -1,896 +1,896 @@ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. --- Copyright (C) 2012 Martin Kuettler */ #include "worksheettextitem.h" #include "worksheet.h" #include "worksheetentry.h" #include "epsrenderer.h" #include "worksheetcursor.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include WorksheetTextItem::WorksheetTextItem(QGraphicsObject* parent, Qt::TextInteractionFlags ti) : QGraphicsTextItem(parent) { setTextInteractionFlags(ti); if (ti & Qt::TextEditable) { setCursor(Qt::IBeamCursor); connect(this, SIGNAL(sizeChanged()), parent, SLOT(recalculateSize())); } m_completionEnabled = false; m_completionActive = false; m_itemDragable = false; m_richTextEnabled = false; m_size = document()->size();; m_maxWidth = -1; setAcceptDrops(true); setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont)); connect(document(), SIGNAL(contentsChanged()), this, SLOT(testSize())); connect(this, SIGNAL(menuCreated(QMenu*, const QPointF&)), parent, SLOT(populateMenu(QMenu*, const QPointF&)), Qt::DirectConnection); connect(this, SIGNAL(deleteEntry()), parent, SLOT(startRemoving())); connect(this, &WorksheetTextItem::cursorPositionChanged, this, &WorksheetTextItem::updateRichTextActions); connect(document(), SIGNAL(undoAvailable(bool)), this, SIGNAL(undoAvailable(bool))); connect(document(), SIGNAL(redoAvailable(bool)), this, SIGNAL(redoAvailable(bool))); } WorksheetTextItem::~WorksheetTextItem() { if (worksheet() && this == worksheet()->lastFocusedTextItem()) - worksheet()->updateFocusedTextItem(0); + worksheet()->updateFocusedTextItem(nullptr); if (worksheet() && m_maxWidth > 0 && width() > m_maxWidth) worksheet()->removeProtrusion(width() - m_maxWidth); } int WorksheetTextItem::type() const { return Type; } /* void WorksheetTextItem::setHeight() { m_height = height(); } */ void WorksheetTextItem::testSize() { qreal h = document()->size().height(); if (h != m_size.height()) { emit sizeChanged(); m_size.setHeight(h); } qreal w = document()->size().width(); if (w != m_size.width()) { if (m_maxWidth > 0) { qreal oldDiff = m_size.width() - m_maxWidth; qreal newDiff = w - m_maxWidth; if (w > m_maxWidth) { if (m_size.width() > m_maxWidth) worksheet()->updateProtrusion(oldDiff, newDiff); else worksheet()->addProtrusion(newDiff); } else if (m_size.width() > m_maxWidth) { worksheet()->removeProtrusion(oldDiff); } } m_size.setWidth(w); } } qreal WorksheetTextItem::setGeometry(qreal x, qreal y, qreal w, bool centered) { if (m_size.width() < w && centered) setPos(x + w/2 - m_size.width()/2, y); else setPos(x,y); qreal oldDiff = 0; if (m_maxWidth > 0 && width() > m_maxWidth) oldDiff = width() - m_maxWidth; m_maxWidth = w; setTextWidth(w); m_size = document()->size(); if (oldDiff) { if (m_size.width() > m_maxWidth) { qreal newDiff = m_size.width() - m_maxWidth; worksheet()->updateProtrusion(oldDiff, newDiff); } else { worksheet()->removeProtrusion(oldDiff); } } else if (m_size.width() > m_maxWidth) { qreal newDiff = m_size.width() - m_maxWidth; worksheet()->addProtrusion(newDiff); } return m_size.height(); } void WorksheetTextItem::populateMenu(QMenu *menu, const QPointF& pos) { qDebug() << "populate Menu"; QAction * cut = KStandardAction::cut(this, SLOT(cut()), menu); QAction * copy = KStandardAction::copy(this, SLOT(copy()), menu); QAction * paste = KStandardAction::paste(this, SLOT(paste()), menu); if (!textCursor().hasSelection()) { cut->setEnabled(false); copy->setEnabled(false); } if (QApplication::clipboard()->text().isEmpty()) { paste->setEnabled(false); } bool actionAdded = false; if (isEditable()) { menu->addAction(cut); actionAdded = true; } if (!m_itemDragable && (flags() & Qt::TextSelectableByMouse)) { menu->addAction(copy); actionAdded = true; } if (isEditable()) { menu->addAction(paste); actionAdded = true; } if (actionAdded) menu->addSeparator(); emit menuCreated(menu, mapToParent(pos)); } QKeyEvent* WorksheetTextItem::eventForStandardAction(KStandardAction::StandardAction actionID) { // there must be a better way to get the shortcut... QAction * action = KStandardAction::create(actionID, this, SLOT(copy()), this); QKeySequence keySeq = action->shortcut(); // we do not support key sequences with multiple keys here int code = keySeq[0]; const int ModMask = Qt::ShiftModifier | Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier; const int KeyMask = ~ModMask; QKeyEvent* event = new QKeyEvent(QEvent::KeyPress, code & KeyMask, QFlags(code & ModMask)); delete action; return event; } void WorksheetTextItem::cut() { if (richTextEnabled()) { QKeyEvent* event = eventForStandardAction(KStandardAction::Cut); QApplication::sendEvent(worksheet(), event); delete event; } else { copy(); textCursor().removeSelectedText(); } } void WorksheetTextItem::paste() { if (richTextEnabled()) { QKeyEvent* event = eventForStandardAction(KStandardAction::Paste); QApplication::sendEvent(worksheet(), event); delete event; } else { textCursor().insertText(QApplication::clipboard()->text()); } } void WorksheetTextItem::copy() { if (richTextEnabled()) { QKeyEvent* event = eventForStandardAction(KStandardAction::Copy); QApplication::sendEvent(worksheet(), event); delete event; } else { if (!textCursor().hasSelection()) return; QApplication::clipboard()->setText(resolveImages(textCursor())); } } void WorksheetTextItem::undo() { document()->undo(); } void WorksheetTextItem::redo() { document()->redo(); } void WorksheetTextItem::clipboardChanged() { if (isEditable()) emit pasteAvailable(!QApplication::clipboard()->text().isEmpty()); } void WorksheetTextItem::selectionChanged() { emit copyAvailable(textCursor().hasSelection()); if (isEditable()) emit cutAvailable(textCursor().hasSelection()); } QString WorksheetTextItem::resolveImages(const QTextCursor& cursor) { int start = cursor.selectionStart(); int end = cursor.selectionEnd(); const QString repl = QString(QChar::ObjectReplacementCharacter); QString result; QTextCursor cursor1 = textCursor(); cursor1.setPosition(start); QTextCursor cursor2 = document()->find(repl, cursor1); for (; !cursor2.isNull() && cursor2.selectionEnd() <= end; cursor2 = document()->find(repl, cursor1)) { cursor1.setPosition(cursor2.selectionStart(), QTextCursor::KeepAnchor); result += cursor1.selectedText(); QVariant var = cursor2.charFormat().property(EpsRenderer::Delimiter); QString delim; if (var.isValid()) delim = var.value(); else delim = QLatin1String(""); result += delim + cursor2.charFormat().property(EpsRenderer::Code).value() + delim; cursor1.setPosition(cursor2.selectionEnd()); } cursor1.setPosition(end, QTextCursor::KeepAnchor); result += cursor1.selectedText(); return result; } void WorksheetTextItem::setCursorPosition(const QPointF& pos) { QTextCursor cursor = cursorForPosition(pos); setTextCursor(cursor); emit cursorPositionChanged(cursor); //setLocalCursorPosition(mapFromParent(pos)); } QPointF WorksheetTextItem::cursorPosition() const { return mapToParent(localCursorPosition()); } void WorksheetTextItem::setLocalCursorPosition(const QPointF& pos) { int p = document()->documentLayout()->hitTest(pos, Qt::FuzzyHit); QTextCursor cursor = textCursor(); cursor.setPosition(p); setTextCursor(cursor); emit cursorPositionChanged(cursor); } QPointF WorksheetTextItem::localCursorPosition() const { QTextCursor cursor = textCursor(); QTextBlock block = cursor.block(); int p = cursor.position() - block.position(); QTextLine line = block.layout()->lineForTextPosition(p); if (!line.isValid()) // can this happen? return block.layout()->position(); return QPointF(line.cursorToX(p), line.y() + line.height()); } QRectF WorksheetTextItem::sceneCursorRect(QTextCursor cursor) const { return mapRectToScene(cursorRect(cursor)); } QRectF WorksheetTextItem::cursorRect(QTextCursor cursor) const { if (cursor.isNull()) cursor = textCursor(); QTextCursor startCursor = cursor; startCursor.setPosition(cursor.selectionStart()); QTextBlock block = startCursor.block(); if (!block.layout()) return mapRectToScene(boundingRect()); int p = startCursor.position() - block.position(); QTextLine line = block.layout()->lineForTextPosition(p); QRectF r1(line.cursorToX(p), line.y(), 1, line.height()+line.leading()); if (!cursor.hasSelection()) return r1; QTextCursor endCursor = cursor; endCursor.setPosition(cursor.selectionEnd()); block = endCursor.block(); p = endCursor.position() - block.position(); line = block.layout()->lineForTextPosition(p); QRectF r2(line.cursorToX(p), line.y(), 1, line.height()+line.leading()); if (r1.y() == r2.y()) return r1.united(r2); else return QRectF(x(), qMin(r1.y(), r2.y()), boundingRect().width(), qMax(r1.y() + r1.height(), r2.y() + r2.height())); } QTextCursor WorksheetTextItem::cursorForPosition(const QPointF& pos) const { QPointF lpos = mapFromParent(pos); int p = document()->documentLayout()->hitTest(lpos, Qt::FuzzyHit); QTextCursor cursor = textCursor(); cursor.setPosition(p); return cursor; } bool WorksheetTextItem::isEditable() { return textInteractionFlags() & Qt::TextEditable; } bool WorksheetTextItem::richTextEnabled() { return m_richTextEnabled; } void WorksheetTextItem::enableCompletion(bool b) { m_completionEnabled = b; } void WorksheetTextItem::activateCompletion(bool b) { m_completionActive = b; } void WorksheetTextItem::setItemDragable(bool b) { m_itemDragable = b; } void WorksheetTextItem::enableRichText(bool b) { m_richTextEnabled = b; } void WorksheetTextItem::setFocusAt(int pos, qreal xCoord) { QTextCursor cursor = textCursor(); if (pos == TopLeft) { cursor.movePosition(QTextCursor::Start); } else if (pos == BottomRight) { cursor.movePosition(QTextCursor::End); } else { QTextLine line; if (pos == TopCoord) { line = document()->firstBlock().layout()->lineAt(0); } else { QTextLayout* layout = document()->lastBlock().layout(); qDebug() << document()->blockCount() << "blocks"; qDebug() << document()->lastBlock().lineCount() << "lines in last block"; line = layout->lineAt(document()->lastBlock().lineCount()-1); } qreal x = mapFromScene(xCoord, 0).x(); int p = line.xToCursor(x); cursor.setPosition(p); // Hack: The code for selecting the last line above does not work. // This is a workaround if (pos == BottomCoord) while (cursor.movePosition(QTextCursor::Down)) ; } setTextCursor(cursor); emit cursorPositionChanged(cursor); setFocus(); } Cantor::Session* WorksheetTextItem::session() { return worksheet()->session(); } void WorksheetTextItem::keyPressEvent(QKeyEvent *event) { if (!isEditable()) return; switch (event->key()) { case Qt::Key_Left: if (event->modifiers() == Qt::NoModifier && textCursor().atStart()) { emit moveToPrevious(BottomRight, 0); qDebug()<<"Reached leftmost valid position"; return; } break; case Qt::Key_Right: if (event->modifiers() == Qt::NoModifier && textCursor().atEnd()) { emit moveToNext(TopLeft, 0); qDebug()<<"Reached rightmost valid position"; return; } break; case Qt::Key_Up: if (event->modifiers() == Qt::NoModifier && !textCursor().movePosition(QTextCursor::Up)) { qreal x = mapToScene(localCursorPosition()).x(); emit moveToPrevious(BottomCoord, x); qDebug()<<"Reached topmost valid position" << localCursorPosition().x(); return; } break; case Qt::Key_Down: if (event->modifiers() == Qt::NoModifier && !textCursor().movePosition(QTextCursor::Down)) { qreal x = mapToScene(localCursorPosition()).x(); emit moveToNext(TopCoord, x); qDebug()<<"Reached bottommost valid position" << localCursorPosition().x(); return; } break; case Qt::Key_Enter: case Qt::Key_Return: if (event->modifiers() == Qt::NoModifier && m_completionActive) { emit applyCompletion(); return; } break; case Qt::Key_Tab: qDebug() << "Tab"; break; default: break; } int p = textCursor().position(); bool b = textCursor().hasSelection(); QGraphicsTextItem::keyPressEvent(event); if (p != textCursor().position()) emit cursorPositionChanged(textCursor()); if (b != textCursor().hasSelection()) selectionChanged(); } bool WorksheetTextItem::sceneEvent(QEvent *event) { if (event->type() == QEvent::KeyPress) { // QGraphicsTextItem's TabChangesFocus feature prevents calls to // keyPressEvent for Tab, even when it's turned off. So we got to catch // that here. QKeyEvent* kev = dynamic_cast(event); if (kev->key() == Qt::Key_Tab && kev->modifiers() == Qt::NoModifier) { emit tabPressed(); return true; } else if ((kev->key() == Qt::Key_Tab && kev->modifiers() == Qt::ShiftModifier) || kev->key() == Qt::Key_Backtab) { emit backtabPressed(); return true; } } else if (event->type() == QEvent::ShortcutOverride) { QKeyEvent* kev = dynamic_cast(event); QKeySequence seq(kev->key() + kev->modifiers()); if (worksheet()->isShortcut(seq)) { qDebug() << "ShortcutOverride" << kev->key() << kev->modifiers(); kev->ignore(); return false; } } return QGraphicsTextItem::sceneEvent(event); } void WorksheetTextItem::focusInEvent(QFocusEvent *event) { QGraphicsTextItem::focusInEvent(event); //parentItem()->ensureVisible(QRectF(), 0, 0); WorksheetEntry* entry = qobject_cast(parentObject()); WorksheetCursor c(entry, this, textCursor()); worksheet()->makeVisible(c); worksheet()->updateFocusedTextItem(this); connect(QApplication::clipboard(), SIGNAL(dataChanged()), this, SLOT(clipboardChanged())); emit receivedFocus(this); emit cursorPositionChanged(textCursor()); } void WorksheetTextItem::focusOutEvent(QFocusEvent *event) { QGraphicsTextItem::focusOutEvent(event); emit cursorPositionChanged(QTextCursor()); } void WorksheetTextItem::mousePressEvent(QGraphicsSceneMouseEvent *event) { int p = textCursor().position(); bool b = textCursor().hasSelection(); QGraphicsTextItem::mousePressEvent(event); if (isEditable() && event->button() == Qt::MiddleButton && QApplication::clipboard()->supportsSelection() && !event->isAccepted()) event->accept(); if (m_itemDragable && event->button() == Qt::LeftButton) event->accept(); if (p != textCursor().position()) emit cursorPositionChanged(textCursor()); if (b != textCursor().hasSelection()) selectionChanged(); } void WorksheetTextItem::mouseMoveEvent(QGraphicsSceneMouseEvent* event) { const QPointF buttonDownPos = event->buttonDownPos(Qt::LeftButton); if (m_itemDragable && event->buttons() == Qt::LeftButton && contains(buttonDownPos) && (event->pos() - buttonDownPos).manhattanLength() >= QApplication::startDragDistance()) { ungrabMouse(); emit drag(mapToParent(buttonDownPos), mapToParent(event->pos())); event->accept(); } else { bool b = textCursor().hasSelection(); QGraphicsTextItem::mouseMoveEvent(event); if (b != textCursor().hasSelection()) selectionChanged(); } } void WorksheetTextItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { int p = textCursor().position(); // custom middle-click paste that does not copy rich text if (isEditable() && event->button() == Qt::MiddleButton && QApplication::clipboard()->supportsSelection() && !richTextEnabled()) { setLocalCursorPosition(mapFromScene(event->scenePos())); const QString& text = QApplication::clipboard()->text(QClipboard::Selection); textCursor().insertText(text); } else { QGraphicsTextItem::mouseReleaseEvent(event); } if (p != textCursor().position()) emit cursorPositionChanged(textCursor()); } void WorksheetTextItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) { QTextCursor cursor = textCursor(); const QChar repl = QChar::ObjectReplacementCharacter; if (!cursor.hasSelection()) { // We look at the current cursor and the next cursor for a // ObjectReplacementCharacter for (int i = 2; i; --i) { if (document()->characterAt(cursor.position()-1) == repl) { setTextCursor(cursor); emit doubleClick(); return; } cursor.movePosition(QTextCursor::NextCharacter); } } else if (cursor.selectedText().contains(repl)) { emit doubleClick(); return; } QGraphicsTextItem::mouseDoubleClickEvent(event); } void WorksheetTextItem::dragEnterEvent(QGraphicsSceneDragDropEvent* event) { if (isEditable() && event->mimeData()->hasFormat(QLatin1String("text/plain"))) { if (event->proposedAction() & (Qt::CopyAction | Qt::MoveAction)) { event->acceptProposedAction(); } else if (event->possibleActions() & Qt::CopyAction) { event->setDropAction(Qt::CopyAction); event->accept(); } else if (event->possibleActions() & Qt::MoveAction) { event->setDropAction(Qt::MoveAction); event->accept(); } else { event->ignore(); } } else { event->ignore(); } } void WorksheetTextItem::dragMoveEvent(QGraphicsSceneDragDropEvent* event) { if (isEditable() && event->mimeData()->hasFormat(QLatin1String("text/plain"))) setLocalCursorPosition(mapFromScene(event->scenePos())); } void WorksheetTextItem::dropEvent(QGraphicsSceneDragDropEvent* event) { if (isEditable()) { if (richTextEnabled() && event->mimeData()->hasFormat(QLatin1String("text/html"))) textCursor().insertHtml(event->mimeData()->html()); else textCursor().insertText(event->mimeData()->text()); event->accept(); } } void WorksheetTextItem::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) { QMenu *menu = worksheet()->createContextMenu(); populateMenu(menu, event->pos()); menu->popup(event->screenPos()); } void WorksheetTextItem::insertTab() { QTextCursor cursor = textCursor(); cursor.clearSelection(); cursor.movePosition(QTextCursor::StartOfLine, QTextCursor::KeepAnchor); QString sel = cursor.selectedText(); bool spacesOnly = true; qDebug() << sel; for (QString::iterator it = sel.begin(); it != sel.end(); ++it) { if (! it->isSpace()) { spacesOnly = false; break; } } cursor.setPosition(cursor.selectionEnd()); if (spacesOnly) { while (document()->characterAt(cursor.position()) == QLatin1Char(' ')) cursor.movePosition(QTextCursor::NextCharacter); } QTextLayout *layout = textCursor().block().layout(); if (!layout) { cursor.insertText(QLatin1String(" ")); } else { cursor.movePosition(QTextCursor::StartOfLine, QTextCursor::KeepAnchor); int i = cursor.selectionEnd() - cursor.selectionStart(); i = ((i+4) & (~3)) - i; cursor.setPosition(cursor.selectionEnd()); QString insertBlankSpace = QLatin1String(" "); cursor.insertText(insertBlankSpace.repeated(i)); } setTextCursor(cursor); emit cursorPositionChanged(textCursor()); } double WorksheetTextItem::width() const { return m_size.width(); } double WorksheetTextItem::height() const { return m_size.height(); } Worksheet* WorksheetTextItem::worksheet() { return qobject_cast(scene()); } WorksheetView* WorksheetTextItem::worksheetView() { return worksheet()->worksheetView(); } void WorksheetTextItem::clearSelection() { QTextCursor cursor = textCursor(); cursor.clearSelection(); setTextCursor(cursor); selectionChanged(); } bool WorksheetTextItem::isUndoAvailable() { return document()->isUndoAvailable(); } bool WorksheetTextItem::isRedoAvailable() { return document()->isRedoAvailable(); } bool WorksheetTextItem::isCutAvailable() { return isEditable() && textCursor().hasSelection(); } bool WorksheetTextItem::isCopyAvailable() { return !m_itemDragable && textCursor().hasSelection(); } bool WorksheetTextItem::isPasteAvailable() { return isEditable() && !QApplication::clipboard()->text().isEmpty(); } QTextCursor WorksheetTextItem::search(QString pattern, QTextDocument::FindFlags qt_flags, const WorksheetCursor& pos) { if (pos.isValid() && pos.textItem() != this) return QTextCursor(); QTextDocument* doc = document(); QTextCursor cursor; if (pos.isValid()) { cursor = doc->find(pattern, pos.textCursor(), qt_flags); } else { cursor = textCursor(); if (qt_flags & QTextDocument::FindBackward) cursor.movePosition(QTextCursor::End); else cursor.movePosition(QTextCursor::Start); cursor = doc->find(pattern, cursor, qt_flags); } return cursor; } // RichText void WorksheetTextItem::updateRichTextActions(QTextCursor cursor) { if (cursor.isNull()) return; Worksheet::RichTextInfo info; QTextCharFormat fmt = cursor.charFormat(); info.bold = (fmt.fontWeight() == QFont::Bold); info.italic = fmt.fontItalic(); info.underline = fmt.fontUnderline(); info.strikeOut = fmt.fontStrikeOut(); info.font = fmt.fontFamily(); info.fontSize = fmt.font().pointSize(); QTextBlockFormat bfmt = cursor.blockFormat(); info.align = bfmt.alignment(); worksheet()->setRichTextInformation(info); } void WorksheetTextItem::mergeFormatOnWordOrSelection(const QTextCharFormat &format) { qDebug() << format; QTextCursor cursor = textCursor(); QTextCursor wordStart(cursor); QTextCursor wordEnd(cursor); wordStart.movePosition(QTextCursor::StartOfWord); wordEnd.movePosition(QTextCursor::EndOfWord); //cursor.beginEditBlock(); if (!cursor.hasSelection() && cursor.position() != wordStart.position() && cursor.position() != wordEnd.position()) cursor.select(QTextCursor::WordUnderCursor); cursor.mergeCharFormat(format); //q->mergeCurrentCharFormat(format); //cursor.endEditBlock(); setTextCursor(cursor); } void WorksheetTextItem::setTextForegroundColor() { QTextCharFormat fmt = textCursor().charFormat(); QColor color = fmt.foreground().color(); color = QColorDialog::getColor(color, worksheetView()); if (!color.isValid()) color = KColorScheme(QPalette::Active, KColorScheme::View).foreground().color(); QTextCharFormat newFmt; newFmt.setForeground(color); mergeFormatOnWordOrSelection(newFmt); } void WorksheetTextItem::setTextBackgroundColor() { QTextCharFormat fmt = textCursor().charFormat(); QColor color = fmt.background().color(); color = QColorDialog::getColor(color, worksheetView()); if (!color.isValid()) color = KColorScheme(QPalette::Active, KColorScheme::View).background().color(); QTextCharFormat newFmt; newFmt.setBackground(color); mergeFormatOnWordOrSelection(newFmt); } void WorksheetTextItem::setTextBold(bool b) { QTextCharFormat fmt; fmt.setFontWeight(b ? QFont::Bold : QFont::Normal); mergeFormatOnWordOrSelection(fmt); } void WorksheetTextItem::setTextItalic(bool b) { QTextCharFormat fmt; fmt.setFontItalic(b); mergeFormatOnWordOrSelection(fmt); } void WorksheetTextItem::setTextUnderline(bool b) { QTextCharFormat fmt; fmt.setFontUnderline(b); mergeFormatOnWordOrSelection(fmt); } void WorksheetTextItem::setTextStrikeOut(bool b) { QTextCharFormat fmt; fmt.setFontStrikeOut(b); mergeFormatOnWordOrSelection(fmt); } void WorksheetTextItem::setAlignment(Qt::Alignment a) { QTextBlockFormat fmt; fmt.setAlignment(a); QTextCursor cursor = textCursor(); cursor.mergeBlockFormat(fmt); setTextCursor(cursor); } void WorksheetTextItem::setFontFamily(const QString& font) { if (!richTextEnabled()) return; QTextCharFormat fmt; fmt.setFontFamily(font); mergeFormatOnWordOrSelection(fmt); } void WorksheetTextItem::setFontSize(int size) { if (!richTextEnabled()) return; QTextCharFormat fmt; fmt.setFontPointSize(size); mergeFormatOnWordOrSelection(fmt); } diff --git a/src/worksheettoolbutton.h b/src/worksheettoolbutton.h index e60f72e3..e29e0c13 100644 --- a/src/worksheettoolbutton.h +++ b/src/worksheettoolbutton.h @@ -1,60 +1,60 @@ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. --- Copyright (C) 2012 Martin Kuettler */ #ifndef WORKSHEETTOOLBUTTON_H #define WORKSHEETTOOLBUTTON_H #include #include #include class WorksheetToolButton : public QGraphicsObject { Q_OBJECT public: WorksheetToolButton(QGraphicsItem* parent); ~WorksheetToolButton() override; void setIcon(const QIcon& icon); qreal width(); qreal height(); QRectF boundingRect() const Q_DECL_OVERRIDE; void setIconScale(qreal scale); void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, - QWidget* widget = 0) Q_DECL_OVERRIDE; + QWidget* widget = nullptr) Q_DECL_OVERRIDE; Q_SIGNALS: void clicked(); void pressed(); protected: void mousePressEvent(QGraphicsSceneMouseEvent* event) Q_DECL_OVERRIDE; void mouseReleaseEvent(QGraphicsSceneMouseEvent* event) Q_DECL_OVERRIDE; private: QSize m_size; QPixmap m_pixmap; QIcon m_icon; qreal m_scale; }; #endif //WORKSHEETTOOLBUTTON_H diff --git a/src/worksheetview.cpp b/src/worksheetview.cpp index f44e5b9a..6935cf7c 100644 --- a/src/worksheetview.cpp +++ b/src/worksheetview.cpp @@ -1,291 +1,291 @@ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. --- Copyright (C) 2012 Martin Kuettler */ #include "worksheetview.h" #include "worksheet.h" #include #include #include #include WorksheetView::WorksheetView(Worksheet* scene, QWidget* parent) : QGraphicsView(scene, parent) { m_scale = 1; - m_animation = 0; - m_hAnimation = 0; - m_vAnimation = 0; + m_animation = nullptr; + m_hAnimation = nullptr; + m_vAnimation = nullptr; m_worksheet = scene; connect(scene, SIGNAL(sceneRectChanged(const QRectF&)), this, SLOT(sceneRectChanged(const QRectF&))); setAlignment(Qt::AlignLeft | Qt::AlignTop); //setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded); } WorksheetView::~WorksheetView() { } void WorksheetView::makeVisible(const QRectF& sceneRect) { const qreal w = viewport()->width(); const qreal h = viewport()->height(); QRectF rect(m_scale*sceneRect.topLeft(), m_scale*sceneRect.size()); qreal x,y; if (m_animation) { x = m_hAnimation->endValue().toReal(); y = m_vAnimation->endValue().toReal(); if (QRectF(x,y,w,h).contains(rect)) return; } if (horizontalScrollBar()) x = horizontalScrollBar()->value(); else x = 0; if (verticalScrollBar()) y = verticalScrollBar()->value(); else y = 0; qDebug() << rect << QRectF(x,y,w,h); if (!m_animation && QRectF(x,y,w,h).contains(rect)) return; qreal nx, ny; if (y > rect.y() || rect.height() > h) ny = rect.y(); else ny = rect.y() + rect.height() - h; if (rect.x() + rect.width() <= w || x > rect.x()) nx = 0; else nx = rect.x() + rect.width() - w; qDebug() << nx << ny; if (!m_worksheet->animationsEnabled()) { if (horizontalScrollBar()) horizontalScrollBar()->setValue(nx); if (verticalScrollBar()) verticalScrollBar()->setValue(ny); return; } if (!m_animation) m_animation = new QParallelAnimationGroup(this); if (horizontalScrollBar()) { if (!m_hAnimation) { m_hAnimation = new QPropertyAnimation(horizontalScrollBar(), "value", this); m_hAnimation->setStartValue(horizontalScrollBar()->value()); nx = qBound(qreal(0.0), nx, qreal(0.0+horizontalScrollBar()->maximum())); m_hAnimation->setEndValue(nx); m_hAnimation->setDuration(100); m_animation->addAnimation(m_hAnimation); } else { qreal progress = static_cast(m_hAnimation->currentTime()) / m_hAnimation->totalDuration(); QEasingCurve curve = m_hAnimation->easingCurve(); qreal value = curve.valueForProgress(progress); qreal sx = 1/(1-value)*(m_hAnimation->currentValue().toReal() - value * nx); m_hAnimation->setStartValue(sx); m_hAnimation->setEndValue(nx); } } else { - m_hAnimation = 0; + m_hAnimation = nullptr; } if (verticalScrollBar()) { if (!m_vAnimation) { m_vAnimation = new QPropertyAnimation(verticalScrollBar(), "value", this); m_vAnimation->setStartValue(verticalScrollBar()->value()); ny = qBound(qreal(0.0), ny, qreal(0.0+verticalScrollBar()->maximum())); m_vAnimation->setEndValue(ny); m_vAnimation->setDuration(100); m_animation->addAnimation(m_vAnimation); } else { qreal progress = static_cast(m_vAnimation->currentTime()) / m_vAnimation->totalDuration(); QEasingCurve curve = m_vAnimation->easingCurve(); qreal value = curve.valueForProgress(progress); qreal sy = 1/(1-value)*(m_vAnimation->currentValue().toReal() - value * ny); m_vAnimation->setStartValue(sy); m_vAnimation->setEndValue(ny); //qDebug() << sy << value << ny; } } else { - m_vAnimation = 0; + m_vAnimation = nullptr; } connect(m_animation, &QParallelAnimationGroup::finished, this, &WorksheetView::endAnimation); m_animation->start(); } bool WorksheetView::isVisible(const QRectF& sceneRect) { const qreal w = viewport()->width(); const qreal h = viewport()->height(); QRectF rect(m_scale*sceneRect.topLeft(), m_scale*sceneRect.size()); qreal x,y; if (m_animation) { x = m_hAnimation->endValue().toReal(); y = m_vAnimation->endValue().toReal(); } else { if (horizontalScrollBar()) x = horizontalScrollBar()->value(); else x = 0; if (verticalScrollBar()) y = verticalScrollBar()->value(); else y = 0; } return QRectF(x,y,w,h).contains(rect); } bool WorksheetView::isAtEnd() { bool atEnd = true; if (verticalScrollBar()) atEnd &= (verticalScrollBar()->value()==verticalScrollBar()->maximum()); return atEnd; } void WorksheetView::scrollToEnd() { if (verticalScrollBar()) verticalScrollBar()->setValue(verticalScrollBar()->maximum()); } void WorksheetView::scrollBy(int dy) { if (!verticalScrollBar()) return; int ny = verticalScrollBar()->value() + dy; if (ny < 0) ny = 0; else if (ny > verticalScrollBar()->maximum()) ny = verticalScrollBar()->maximum(); int x; if (horizontalScrollBar()) x = horizontalScrollBar()->value(); else x = 0; const qreal w = viewport()->width() / m_scale; const qreal h = viewport()->height() / m_scale; makeVisible(QRectF(x, ny, w, h)); } void WorksheetView::endAnimation() { if (!m_animation) return; m_animation->deleteLater(); - m_hAnimation = 0; - m_vAnimation = 0; - m_animation = 0; + m_hAnimation = nullptr; + m_vAnimation = nullptr; + m_animation = nullptr; } QPoint WorksheetView::viewCursorPos() { return viewport()->mapFromGlobal(QCursor::pos()); } QPointF WorksheetView::sceneCursorPos() { return mapToScene(viewCursorPos()); } QRectF WorksheetView::viewRect() { const qreal w = viewport()->width() / m_scale; const qreal h = viewport()->height() / m_scale; qreal y = verticalScrollBar()->value(); qreal x = horizontalScrollBar() ? horizontalScrollBar()->value() : 0; return QRectF(x, y, w, h); } void WorksheetView::resizeEvent(QResizeEvent * event) { QGraphicsView::resizeEvent(event); updateSceneSize(); } qreal WorksheetView::scaleFactor() { return m_scale; } void WorksheetView::updateSceneSize() { QSize s = viewport()->size(); m_worksheet->setViewSize(s.width()/m_scale, s.height()/m_scale, m_scale); sendViewRectChange(); } void WorksheetView::sceneRectChanged(const QRectF& sceneRect) { Q_UNUSED(sceneRect); if (verticalScrollBar()) connect(verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(sendViewRectChange()), Qt::UniqueConnection); if (horizontalScrollBar()) connect(horizontalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(sendViewRectChange()), Qt::UniqueConnection); } void WorksheetView::sendViewRectChange() { emit viewRectChanged(viewRect()); } void WorksheetView::zoomIn() { m_scale *= 1.1; scale(1.1, 1.1); updateSceneSize(); } void WorksheetView::zoomOut() { m_scale /= 1.1; scale(1/1.1, 1/1.1); updateSceneSize(); }