diff --git a/src/lib/backend.cpp b/src/lib/backend.cpp index fdc84f75..2828be35 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), +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 nullptr; } QWidget* Backend::settingsWidget(QWidget* parent) const { Q_UNUSED(parent) return nullptr; } KConfigSkeleton* Backend::config() const { 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 8f7febcf..411281e8 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 = nullptr,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/defaulthighlighter.cpp b/src/lib/defaulthighlighter.cpp index 56f50efa..cabda0e7 100644 --- a/src/lib/defaulthighlighter.cpp +++ b/src/lib/defaulthighlighter.cpp @@ -1,460 +1,460 @@ /* 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) 2006 David Saxton */ #include "defaulthighlighter.h" #include #include #include #include #include #include #include #include using namespace Cantor; struct HighlightingRule { QRegExp regExp; QTextCharFormat format; }; bool operator==(const HighlightingRule& rule1, const HighlightingRule& rule2) { return rule1.regExp == rule2.regExp; } struct PairOpener { PairOpener() : position(-1), type(-1) { } PairOpener(int p, int t) : position(p), type(t) { } int position; int type; }; class Cantor::DefaultHighlighterPrivate { public: QTextCursor cursor; //Character formats to use for the highlighing QTextCharFormat functionFormat; QTextCharFormat variableFormat; QTextCharFormat objectFormat; QTextCharFormat keywordFormat; QTextCharFormat numberFormat; QTextCharFormat operatorFormat; QTextCharFormat errorFormat; QTextCharFormat commentFormat; QTextCharFormat stringFormat; QTextCharFormat matchingPairFormat; QTextCharFormat mismatchingPairFormat; int lastBlockNumber; int lastPosition; bool suppressRuleChangedSignal; // each two consecutive items build a pair QList pairs; QList regExpRules; QHash wordRules; }; DefaultHighlighter::DefaultHighlighter(QObject* parent) : QSyntaxHighlighter(parent), d(new DefaultHighlighterPrivate) { d->cursor = QTextCursor(); d->lastBlockNumber=-1; d->lastPosition=-1; d->suppressRuleChangedSignal = false; addPair(QLatin1Char('('), QLatin1Char(')')); addPair(QLatin1Char('['), QLatin1Char(']')); addPair(QLatin1Char('{'), QLatin1Char('}')); updateFormats(); connect(qApp, SIGNAL(paletteChanged(QPalette)), this, SLOT(updateFormats())); } DefaultHighlighter::~DefaultHighlighter() { delete d; } void DefaultHighlighter::setTextItem(QGraphicsTextItem* item) { d->cursor = item->textCursor(); setDocument(item->document()); // make sure every item is connected only once item->disconnect(this, SLOT(positionChanged(QTextCursor))); // QGraphicsTextItem has no signal cursorPositionChanged, but item really // is a WorksheetTextItem connect(item, SIGNAL(cursorPositionChanged(QTextCursor)), this, SLOT(positionChanged(QTextCursor))); d->lastBlockNumber = -1; d->lastPosition = -1; } bool DefaultHighlighter::skipHighlighting(const QString& text) { return text.isEmpty(); } void DefaultHighlighter::highlightBlock(const QString& text) { //qDebug() << text; const QTextCursor& cursor = d->cursor; d->lastBlockNumber = cursor.blockNumber(); if (skipHighlighting(text)) return; highlightPairs(text); highlightWords(text); highlightRegExps(text); } -void DefaultHighlighter::addPair(const QChar& openSymbol, const QChar& closeSymbol) +void DefaultHighlighter::addPair(QChar openSymbol, QChar closeSymbol) { Q_ASSERT(!d->pairs.contains(openSymbol)); Q_ASSERT(!d->pairs.contains(closeSymbol)); d->pairs << openSymbol << closeSymbol; } void DefaultHighlighter::highlightPairs(const QString& text) { //qDebug() << text; const QTextCursor& cursor = d->cursor; int cursorPos = -1; if (cursor.blockNumber() == currentBlock().blockNumber() ) { cursorPos = cursor.position() - currentBlock().position(); // when text changes, this will be called before the positionChanged signal // gets emitted. Hence update the position so we don't highlight twice d->lastPosition = cursor.position(); } QStack opened; for (int i = 0; i < text.size(); ++i) { int idx = d->pairs.indexOf(text[i]); if (idx == -1) continue; if (idx % 2 == 0) { //opener of a pair opened.push(PairOpener(i, idx)); } else if (opened.isEmpty()) { //closer with no previous opener setFormat(i, 1, errorFormat()); } else if (opened.top().type == idx - 1) { //closer with matched opener int openPos = opened.pop().position; if (cursorPos != -1 && (openPos == cursorPos || openPos == cursorPos - 1 || i == cursorPos || i == cursorPos - 1)) { setFormat(openPos, 1, matchingPairFormat()); setFormat(i, 1, matchingPairFormat()); } } else { //closer with mismatching opener int openPos = opened.pop().position; setFormat(openPos, 1, mismatchingPairFormat()); setFormat(i, 1, mismatchingPairFormat()); } } // handled unterminated pairs while (!opened.isEmpty()) { int position = opened.pop().position; setFormat(position, 1, errorFormat()); } } void DefaultHighlighter::highlightWords(const QString& text) { //qDebug() << "DefaultHighlighter::highlightWords"; const QStringList& words = text.split(QRegExp(QLatin1String("\\b")), QString::SkipEmptyParts); int count; int pos = 0; const int n = words.size(); for (int i = 0; i < n; ++i) { count = words[i].size(); QString word = words[i]; //kind of a HACK: //look at previous words, if they end with allowed characters, //prepend them to the current word. This allows for example //to highlight words that start with a "Non-word"-character //e.g. %pi in the scilab backend. //qDebug() << "nonSeparatingCharacters().isNull(): " << nonSeparatingCharacters().isNull(); if(!nonSeparatingCharacters().isNull()) { for(int j = i - 1; j >= 0; j--) { //qDebug() << "j: " << j << "w: " << words[j]; const QString& w = words[j]; const QString exp = QString::fromLatin1("(%1)*$").arg(nonSeparatingCharacters()); //qDebug() << "exp: " << exp; int idx = w.indexOf(QRegExp(exp)); const QString& s = w.mid(idx); //qDebug() << "s: " << s; if(s.size() > 0) { pos -= s.size(); count += s.size(); word = s + word; } else{ break; } } } word = word.trimmed(); //qDebug() << "highlighing: " << word; if (d->wordRules.contains(word)) { setFormat(pos, count, d->wordRules[word]); } pos += count; } } void DefaultHighlighter::highlightRegExps(const QString& text) { foreach (const HighlightingRule& rule, d->regExpRules) { int index = rule.regExp.indexIn(text); while (index >= 0) { int length = rule.regExp.matchedLength(); setFormat(index, length, rule.format); index = rule.regExp.indexIn(text, index + length); } } } QTextCharFormat DefaultHighlighter::functionFormat() const { return d->functionFormat; } QTextCharFormat DefaultHighlighter::variableFormat() const { return d->variableFormat; } QTextCharFormat DefaultHighlighter::objectFormat() const { return d->objectFormat; } QTextCharFormat DefaultHighlighter::keywordFormat() const { return d->keywordFormat; } QTextCharFormat DefaultHighlighter::numberFormat() const { return d->numberFormat; } QTextCharFormat DefaultHighlighter::operatorFormat() const { return d->operatorFormat; } QTextCharFormat DefaultHighlighter::errorFormat() const { return d->errorFormat; } QTextCharFormat DefaultHighlighter::commentFormat() const { return d->commentFormat; } QTextCharFormat DefaultHighlighter::stringFormat() const { return d->stringFormat; } QTextCharFormat DefaultHighlighter::matchingPairFormat() const { return d->matchingPairFormat; } QTextCharFormat DefaultHighlighter::mismatchingPairFormat() const { return d->mismatchingPairFormat; } void DefaultHighlighter::updateFormats() { //initialize char-formats KColorScheme scheme(QPalette::Active); d->functionFormat.setForeground(scheme.foreground(KColorScheme::LinkText)); d->functionFormat.setFontWeight(QFont::DemiBold); d->variableFormat.setForeground(scheme.foreground(KColorScheme::ActiveText)); d->objectFormat.setForeground(scheme.foreground(KColorScheme::NormalText)); d->objectFormat.setFontWeight(QFont::Bold); d->keywordFormat.setForeground(scheme.foreground(KColorScheme::NeutralText)); d->keywordFormat.setFontWeight(QFont::Bold); d->numberFormat.setForeground(scheme.foreground(KColorScheme::NeutralText)); d->operatorFormat.setForeground(scheme.foreground(KColorScheme::NormalText)); d->operatorFormat.setFontWeight(QFont::Bold); d->errorFormat.setForeground(scheme.foreground(KColorScheme::NormalText)); d->errorFormat.setUnderlineColor(scheme.foreground(KColorScheme::NegativeText).color()); d->errorFormat.setUnderlineStyle(QTextCharFormat::SpellCheckUnderline); d->commentFormat.setForeground(scheme.foreground(KColorScheme::InactiveText)); d->stringFormat.setForeground(scheme.foreground(KColorScheme::PositiveText)); d->matchingPairFormat.setForeground(scheme.foreground(KColorScheme::NeutralText)); d->matchingPairFormat.setBackground(scheme.background(KColorScheme::NeutralBackground)); d->mismatchingPairFormat.setForeground(scheme.foreground(KColorScheme::NegativeText)); d->mismatchingPairFormat.setBackground(scheme.background(KColorScheme::NegativeBackground)); } -void DefaultHighlighter::positionChanged(QTextCursor cursor) +void DefaultHighlighter::positionChanged(const QTextCursor& cursor) { if (!cursor.isNull() && cursor.document() != document()) // A new item notified us, but we did not yet change our document. // We are waiting for that to happen. return; d->cursor = cursor; if ( (cursor.isNull() || cursor.blockNumber() != d->lastBlockNumber) && d->lastBlockNumber >= 0 ) { // remove highlight from last focused block rehighlightBlock(document()->findBlockByNumber(d->lastBlockNumber)); } if (cursor.isNull()) { d->lastBlockNumber = -1; d->lastPosition = -1; return; } d->lastBlockNumber = cursor.blockNumber(); if ( d->lastPosition == cursor.position() ) { return; } rehighlightBlock(cursor.block()); d->lastPosition = cursor.position(); } void DefaultHighlighter::addRule(const QString& word, const QTextCharFormat& format) { d->wordRules[word] = format; if (!d->suppressRuleChangedSignal) emit rulesChanged(); } void DefaultHighlighter::addRule(const QRegExp& regexp, const QTextCharFormat& format) { HighlightingRule rule = { regexp, format }; d->regExpRules.removeAll(rule); d->regExpRules.append(rule); if (!d->suppressRuleChangedSignal) emit rulesChanged(); } void DefaultHighlighter::removeRule(const QString& word) { d->wordRules.remove(word); if (!d->suppressRuleChangedSignal) emit rulesChanged(); } void DefaultHighlighter::removeRule(const QRegExp& regexp) { HighlightingRule rule = { regexp, QTextCharFormat() }; d->regExpRules.removeAll(rule); if (!d->suppressRuleChangedSignal) emit rulesChanged(); } void DefaultHighlighter::addRules(const QStringList& conditions, const QTextCharFormat& format) { typename QStringList::const_iterator i = conditions.constBegin(); typename QStringList::const_iterator end = conditions.constEnd(); d->suppressRuleChangedSignal = true; for (;i != end; ++i) { addRule(*i, format); } d->suppressRuleChangedSignal = true; emit rulesChanged(); } void DefaultHighlighter::addFunctions(const QStringList& functions) { addRules(functions, functionFormat()); } void DefaultHighlighter::addKeywords(const QStringList& keywords) { addRules(keywords, keywordFormat()); } void DefaultHighlighter::addVariables(const QStringList& variables) { addRules(variables, variableFormat()); } void DefaultHighlighter::removeRules(const QStringList& conditions) { typename QStringList::const_iterator i = conditions.constBegin(); typename QStringList::const_iterator end = conditions.constEnd(); d->suppressRuleChangedSignal = true; for (;i != end; ++i) { removeRule(*i); } d->suppressRuleChangedSignal = false; emit rulesChanged(); } QString DefaultHighlighter::nonSeparatingCharacters() const { return QString(); } diff --git a/src/lib/defaulthighlighter.h b/src/lib/defaulthighlighter.h index 2df97624..95617eb1 100644 --- a/src/lib/defaulthighlighter.h +++ b/src/lib/defaulthighlighter.h @@ -1,183 +1,183 @@ /* 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 DEFAULTHIGHLIGHTER_H #define DEFAULTHIGHLIGHTER_H #include "cantor_export.h" #include class QGraphicsTextItem; namespace Cantor { class DefaultHighlighterPrivate; /** * The DefaultHighlighter is an implementation QSyntaxHighlighter. * It covers most common cases of syntax highlighting for Cantor's command entries. * * When creating a custom highlighter, for example for a new backend, you should use * the provided functions addPairs(), addRule() and/or addRules(). * * If you need more specific functionality, subclass highlightBlock(). Usually it's a good idea to also call * DefaultHighlighter's implementation from it. * * @author Alexander Rieder */ class CANTOR_EXPORT DefaultHighlighter : public QSyntaxHighlighter { Q_OBJECT public: DefaultHighlighter(QObject* parent); ~DefaultHighlighter() override; /** * Change the item being highlighted. */ void setTextItem(QGraphicsTextItem* item); public Q_SLOTS: /** * Called when the cursor moved. Rehighlights accordingly. */ - void positionChanged(QTextCursor); + void positionChanged(const QTextCursor&); protected: /** * This method is called by Cantor's KTextEdit and is where all the highlighting must take place. * The default implementation calls highlightPairs(), highlightWords() and highlightRegExps(). * */ void highlightBlock(const QString& text) Q_DECL_OVERRIDE; bool skipHighlighting(const QString& text); QTextCharFormat functionFormat() const; QTextCharFormat variableFormat() const; QTextCharFormat objectFormat() const; QTextCharFormat keywordFormat() const; QTextCharFormat numberFormat() const; QTextCharFormat operatorFormat() const; QTextCharFormat errorFormat() const; QTextCharFormat commentFormat() const; QTextCharFormat stringFormat() const; QTextCharFormat matchingPairFormat() const; QTextCharFormat mismatchingPairFormat() const; /** * Call this to add a pair of symbols for highlighting. * The default implementation of the class already adds (), {} and [], so no need to add those. * For example, if you wanted to highlight angle-brackets, you would use: * @code * addPair('<', '>'); * @endcode * @param openSymbol the opening symbol of the pair * @param closeSymbol the closing symbol of the pair * @sa highlightPairs */ - void addPair(const QChar& openSymbol, const QChar& closeSymbol); + void addPair(QChar openSymbol, QChar closeSymbol); /** * Highlights all instances of the @p word in the text with the specified @p format * @param word the word to highlight * @param format the format to be used for displaying the word */ void addRule(const QString& word, const QTextCharFormat& format); /** * Highlights all parts of the text matched by the regular expression @p regexp in the text * with the specified @p format * @param regexp the regular expression used to look for matches * @param format the format used to display the matching parts of the text */ void addRule(const QRegExp& regexp, const QTextCharFormat& format); /** * Convenience method, highlights all items in @p conditions with the specified @p format * @code * QStringList greenWords; * greenWords << "tree" << "forest" << "grass"; * addRules(greenWords, greenWordFormat); * @endcode * @param conditions any Qt container of QRegExp or QString. */ void addRules(const QStringList& conditions, const QTextCharFormat& format); /** * Convenience method, equivalent to @code addRules(functions, functionFormat()) @endcode */ void addFunctions(const QStringList& functions); /** * Convenience method, equivalent to @code addRules(variables, variableFormat()) @endcode */ void addVariables(const QStringList& variables); /** * Convenience method, equivalent to @code addRules(keywords, keywordFormat()) @endcode */ void addKeywords(const QStringList& keywords); /** * Removes any rules previously added for the word @p word */ void removeRule(const QString& word); /** * Removes any rules previously added for the regular expression @p regexp */ void removeRule(const QRegExp& regexp); /** * Convenience method, removes all rules with conditions from @p conditions * @sa removeRule, addRules */ void removeRules(const QStringList& conditions); /** * Highlight pairs added with addPair() * @sa addPair */ void highlightPairs(const QString& text); /** * Highlights words added with addRule() * @sa addRule, addRules */ void highlightWords(const QString& text); /** * Highlights all matches from regular expressions added with addRule() * @sa addRule, addRules */ void highlightRegExps(const QString& text); /** * Returns a string that contains a regular expression that matches for characters thar are allowed inside * words for this backend. For example, maxima or scilab allow % at the beginning of variable names */ virtual QString nonSeparatingCharacters() const; private Q_SLOTS: void updateFormats(); Q_SIGNALS: void rulesChanged(); private: DefaultHighlighterPrivate* d; }; } #endif diff --git a/src/lib/extension.h b/src/lib/extension.h index ae79bec6..52749af6 100644 --- a/src/lib/extension.h +++ b/src/lib/extension.h @@ -1,485 +1,493 @@ /* 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 _EXTENSION_H #define _EXTENSION_H #include #include #include #include #include #include "cantor_export.h" namespace Cantor { /** * This is the base class for all Extensions. * An Extension provides a set of Methods to * accomplish specific tasks. This is used to * abstract away the backends syntax for common * tasks like solving equations etc. to be able * to provide Backend independent Dialogs * * @author Alexander Rieder */ class CANTOR_EXPORT Extension : public QObject { + Q_OBJECT public: ///Default constructor Extension( const QString& name, QObject* parent ); ~Extension() override; - }; - //Some basic interfaces for extensions /** * An Extension providing commands for command history */ class CANTOR_EXPORT HistoryExtension : public Extension { + Q_OBJECT public: HistoryExtension(QObject* parent); ~HistoryExtension() override; public Q_SLOTS: /** * Returns a command that retrieves the last result * @return command that retrieves the last result */ virtual QString lastResult() = 0; }; /** * An Extension providing commands to interact * with external scripts */ class CANTOR_EXPORT ScriptExtension : public Extension { + Q_OBJECT public: ScriptExtension(QObject* parent); ~ScriptExtension() override; public Q_SLOTS: /** * returns the command for running a script * @param path path to the script file * @return command for running a script */ virtual QString runExternalScript(const QString& path) = 0; /** * returns the file filter used for Script Files (e.g. *.py) * @return file filter used for Script Files (e.g. *.py) */ virtual QString scriptFileFilter() = 0; /** * returns the name of the language to use for syntax highlighting * in the script editor (e.g. python). The value returned must match * the name attribute from the xml language description in KTexteditor. * @return name of the language to use for syntax highlighting (e.g. python) */ virtual QString highlightingMode() = 0; /** * returns a string used to separate commands (usually ;) * @return a string used to separate commands (usually ;) */ virtual QString commandSeparator(); /** * returns a string used to start a comment (usually #) * @return a string used to start a comment (usually #) */ virtual QString commentStartingSequence(); /** * returns a string used to end a comment (usually "") * @return a string used to end a comment (usually "") */ virtual QString commentEndingSequence(); }; /** * An extension providing the basic computations * in computer algebra, like solving, simplifying * etc **/ class CANTOR_EXPORT CASExtension : public Extension { + Q_OBJECT public: CASExtension(QObject* parent); ~CASExtension() override; public Q_SLOTS: /** * returns the command for solving a set of equations * @param equations a list of equations * @param variables a list of variables that should be solved for * @return command for solving a set of equations */ virtual QString solve(const QStringList& equations, const QStringList& variables) = 0; /** * returns the command for simplifying an expression * @param expression the expression that should be simplified * @return command for simplifying the expression */ virtual QString simplify(const QString& expression) = 0; /** * returns the command for expanding an expression * @param expression the expression that should be expanded * @return command for expanded the expression */ virtual QString expand(const QString& expression) = 0; }; /** * An extension providing the basic calculus * stuff like limits, diffrentiate, integrate etc. */ class CANTOR_EXPORT CalculusExtension : public Extension { + Q_OBJECT public: CalculusExtension(QObject* parent); ~CalculusExtension() override; public Q_SLOTS: /** * returns the command for calculating a limit if an expression * @param expression the expression * @param variable the variable * @param limit the value, the variable approaches * @return the limit of the expression */ virtual QString limit(const QString& expression, const QString& variable, const QString& limit) = 0; /** * returns the command for calculating a differential * @param function the function * @param variable the variable, after which shoudl be differentiated * @param times how often should be differentiated * @return the command to compute the differential */ virtual QString differentiate(const QString& function,const QString& variable, int times) = 0; /** * returns the command for calculating an integral * @param function the function * @param variable the variable, after which shoudl be integrated * @return the command to compute the integrate */ virtual QString integrate(const QString& function, const QString& variable) = 0; /** * returns the command for calculating a definite integral * @param function the function * @param variable the variable, after which shoudl be integrated * @param left the left border of the integral * @param right the right border of the integral * @return the command to compute the integrate */ virtual QString integrate(const QString& function,const QString& variable, const QString& left, const QString& right) = 0; }; /** * An extension providing basic plotting facilities */ class CANTOR_EXPORT PlotExtension : public Extension { + Q_OBJECT public: typedef QPair Interval; typedef QPair VariableParameter; PlotExtension(QObject* parent); ~PlotExtension() override; public Q_SLOTS: /** * returns the command for plotting a 2 dimensional function. * @param function the function to plot * @param variable the variable * @param left the left border of the plot * @param right the right border of the plot * @return the command for plotting */ virtual QString plotFunction2d(const QString& function, const QString& variable, const QString& left, const QString& right) = 0; /** * returns the command for plotting a 3 dimensional function. * @param function the function to plot * @param var1 the parameters for Variable1 (name, interval) * @param var2 the parameters for Variable2 (name, interval) * @return the command for plotting */ virtual QString plotFunction3d(const QString& function, VariableParameter var1, VariableParameter var2) = 0; }; #define PLOT_DIRECTIVE_DISPATCHING(x) QString dispatch(const Cantor::AdvancedPlotExtension::AcceptorBase& acc) const \ { \ const Cantor::AdvancedPlotExtension::DirectiveAcceptor* adaptor= \ dynamic_cast*>(&acc); \ if (adaptor==NULL) { qDebug()<<"Backend incapable of processing directives of type "#x; return QLatin1String(""); } \ else \ return adaptor->accept(*this); \ } /** * An extension providing advanced plotting facilities. Will supersede PlotExtension */ class CANTOR_EXPORT AdvancedPlotExtension : public Extension { + Q_OBJECT public: AdvancedPlotExtension(QObject* parent); ~AdvancedPlotExtension() override; // TODO comment class PlotDirective; // TODO move the hell out of here class CANTOR_EXPORT DirectiveProducer : public QWidget { public: DirectiveProducer(QWidget* parent); virtual PlotDirective* produceDirective() const=0; }; template class DirectiveControl : protected UI, public DirectiveProducer { public: DirectiveControl(QWidget* parent) : DirectiveProducer(parent) { UI::setupUi(this); } protected: typedef DirectiveControl AbstractParent; }; class CANTOR_EXPORT AcceptorBase { public: /** * utilitary typename for easying the code */ typedef DirectiveProducer * (*widgetProc)(QWidget*); /** * returns a constant reference to the list of widget generating procedures * which contains means of creating all the widgets a backend knows how to process * @return the constant reference to a QVector of QWidget* (*)(QWidget*) pointers */ const QVector& widgets() const; protected: /** * constructor only allowed for derived classes **/ AcceptorBase(); virtual ~AcceptorBase(); QVector m_widgets; }; template class DirectiveAcceptor : virtual public AcceptorBase { public: /** * virtual interface to acceptor function mechanics * @param directive the directive to process * @return the parameter corresponding the directive */ virtual QString accept(const Directive& directive) const=0; protected: /** * constructor only allowed for derived classes **/ DirectiveAcceptor(); }; class CANTOR_EXPORT PlotDirective { public: virtual ~PlotDirective(); /** * creates a new widget for editing the value and returns the pointer to it * @param parent the pointer to parent widget passed to newly created widget * @return pointer to the newly-created widget */ static QWidget* widget(QWidget* parent); /** * in order to make dual dispatching this should be present in any derived class * without virtual keyword and with correct class name **/ virtual PLOT_DIRECTIVE_DISPATCHING(PlotDirective); // TODO: find a workaround not to put class names manually protected: /** * only derived classes may construct **/ PlotDirective(); }; public Q_SLOTS: /** * returns the command for plotting a 2 dimensional data set. * @param expression the expression to plot * @param directives the array of directives toward the generator * @return the command for plotting */ QString plotFunction2d(const QString& expression, const QVector directives) const; /** * returns the parameter expression according to a directive. * @param directive the directive toward the generator * @return the parameter for plotting */ QString dispatchDirective(const PlotDirective& directive) const; protected: /** * returns the command name for plotting a 2 dimensional data set. * @return the command for plotting */ virtual QString plotCommand() const=0; /** * returns the separator symbol in a plotting command. * @return the separator symbol or string */ virtual QString separatorSymbol() const; }; template AdvancedPlotExtension::DirectiveAcceptor::DirectiveAcceptor() { m_widgets.push_back(&Directive::widget); } /** * An extension for basic Linear Algebra */ class CANTOR_EXPORT LinearAlgebraExtension : public Extension { + Q_OBJECT public: enum VectorType { ColumnVector, RowVector }; typedef QList Matrix; LinearAlgebraExtension(QObject* parent); ~LinearAlgebraExtension() override; public Q_SLOTS: //Commands to create Vectors/Matrices /** * creates a vector with the given entries * @param entries the entries of the new vector * @param type the type of the vector (row/column) * @return the command for creating the vector */ virtual QString createVector(const QStringList& entries, VectorType type) = 0; /** * creates a null vector, of the given size/type * @param size size of the vector * @param type type of the vector * @return the command used for creating a nullvector **/ virtual QString nullVector(int size, VectorType type); /** * creates a maxtrix with the given entries * @param matrix the entries of the matrix * @return the command to create this matrix */ virtual QString createMatrix(const Matrix& matrix) = 0; /** * creates an identity matrix of the given size * @param size size of the matrix * @return the command used to create the matrix */ virtual QString identityMatrix(int size); /** * creates a null matrix, of the given size * @param rows number of rows * @param columns number of columns * @return the command to create this matrix */ virtual QString nullMatrix(int rows,int columns); //basic functions /** * compute the rank of a matrix * @param matrix the name of the matrix, the rank should be computed of * @return the command for calculating the rank */ virtual QString rank(const QString& matrix) = 0; /** * invert a given matrix * @param matrix the name of the matrix, that should be inverted * @return the command for inverting the matrix */ virtual QString invertMatrix(const QString& matrix) = 0; /** * calculate the characteristic polynom of a matrix * @param matrix the name of the matrix, the charpoly should be computed of * @return the command */ virtual QString charPoly(const QString& matrix) = 0; /** * calculate the eigen vectors of a matrix * @param matrix the name of the matrix, the eigenvectors should be computed of * @return the command */ virtual QString eigenVectors(const QString& matrix) = 0; /** * calculate the eigen values of a matrix * @param matrix the name of the matrix, the eigenvalues should be computed of * @return the command */ virtual QString eigenValues(const QString& matrix) = 0; }; class CANTOR_EXPORT VariableManagementExtension : public Extension { + Q_OBJECT public: VariableManagementExtension( QObject* parent ); ~VariableManagementExtension() override; public Q_SLOTS: virtual QString addVariable(const QString& name, const QString& value) = 0; virtual QString setValue(const QString& name,const QString& value) = 0; virtual QString removeVariable(const QString& name) = 0; virtual QString saveVariables(const QString& fileName) = 0; virtual QString loadVariables(const QString& fileName) = 0; virtual QString clearVariables() = 0; }; /** * An extension for library/module import */ class CANTOR_EXPORT PackagingExtension : public Extension { + Q_OBJECT public: PackagingExtension(QObject* parent); ~PackagingExtension() override; public Q_SLOTS: /** * import library/module * @param package the library/module name * @return the command for import library/module */ virtual QString importPackage(const QString& package) = 0; }; } #endif /* _EXTENSION_H */ diff --git a/src/lib/panelplugin.cpp b/src/lib/panelplugin.cpp index 7b71cd10..cfe1a791 100644 --- a/src/lib/panelplugin.cpp +++ b/src/lib/panelplugin.cpp @@ -1,91 +1,92 @@ /* 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 + 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=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) +void PanelPlugin::setPluginInfo(const 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) { d->session=session; onSessionChanged(); } void PanelPlugin::onSessionChanged() { } diff --git a/src/lib/panelplugin.h b/src/lib/panelplugin.h index ecbd2ef6..a82b9b1e 100644 --- a/src/lib/panelplugin.h +++ b/src/lib/panelplugin.h @@ -1,117 +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) 2010 Alexander Rieder */ #ifndef _PANEL_PLUGIN_H #define _PANEL_PLUGIN_H -#include #include -#include +class KPluginMetaData; #include "backend.h" #include "cantor_export.h" namespace Cantor { class Session; class PanelPluginPrivate; /** * A plugin provides some additional features for the worksheet */ -class CANTOR_EXPORT PanelPlugin : public QObject /*, public KXMLGUIClient*/ +class CANTOR_EXPORT PanelPlugin : public QObject { Q_OBJECT public: /** * Create a new PanelPlugin * @param parent the parent Object @see QObject **/ PanelPlugin( QObject* parent ); /** * Destructor */ ~PanelPlugin() override; /** * Sets the properties of this PanelPlugin * accodring to KPluginMetaData * @param info KPluginMetaData */ - void setPluginInfo(KPluginMetaData info); + void setPluginInfo(const KPluginMetaData&); /** * Returns a list of all extensions, the current backend * must provide to make this PanelPlugin work. If it doesn't * this PanelPlugin won't be enabled * @return list of required extensions */ QStringList requiredExtensions(); /** * Returns the capabilities, the current backend * must provide to make this PanelPlugin work. If it doesn't * this PanelPlugin won't be enabled * @return the required capabilities */ virtual Backend::Capabilities requiredCapabilities(); /** * Returns the name of the plugin * @return name of the plugin */ QString name(); /** * returns the widget, provided by this plugin * @return the widget, provided by this plugin **/ virtual QWidget* widget() = 0; void setParentWidget(QWidget* widget); QWidget* parentWidget(); /** * sets the session this plugin operates on **/ void setSession(Session* session); /** * returns the session */ Session* session(); Q_SIGNALS: void requestRunCommand(const QString& cmd); void visibilityRequested(); protected: virtual void onSessionChanged(); private: PanelPluginPrivate* d; }; } #endif /* _PANEL_PLUGIN_H */